{"id":13367187,"url":"https://github.com/nstratos/Go-myanimelist","last_synced_at":"2025-03-12T18:32:06.010Z","repository":{"id":31418178,"uuid":"34981569","full_name":"nstratos/go-myanimelist","owner":"nstratos","description":"Go library for accessing the MyAnimeList API: https://myanimelist.net/apiconfig/references/api/v2","archived":false,"fork":false,"pushed_at":"2024-04-24T14:21:52.000Z","size":1936,"stargazers_count":39,"open_issues_count":3,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-25T05:25:17.076Z","etag":null,"topics":["anime","client-lib","go","go-myanimelist","mal","mal-client","manga","myanimelist","myanimelist-api"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nstratos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-05-03T10:07:05.000Z","updated_at":"2024-09-13T18:55:06.000Z","dependencies_parsed_at":"2024-04-24T13:42:51.543Z","dependency_job_id":"971a8b2d-f0ca-430b-a042-1d9ecc61f8b5","html_url":"https://github.com/nstratos/go-myanimelist","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nstratos%2Fgo-myanimelist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nstratos%2Fgo-myanimelist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nstratos%2Fgo-myanimelist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nstratos%2Fgo-myanimelist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nstratos","download_url":"https://codeload.github.com/nstratos/go-myanimelist/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243271508,"owners_count":20264466,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anime","client-lib","go","go-myanimelist","mal","mal-client","manga","myanimelist","myanimelist-api"],"created_at":"2024-07-30T00:01:40.956Z","updated_at":"2025-03-12T18:32:05.610Z","avatar_url":"https://github.com/nstratos.png","language":"Go","funding_links":[],"categories":["第三方 APIs"],"sub_categories":["高级控制台界面","高級控制台界面"],"readme":"# go-myanimelist\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/nstratos/go-myanimelist/mal.svg)](https://pkg.go.dev/github.com/nstratos/go-myanimelist/mal)\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Go Report Card](https://goreportcard.com/badge/github.com/nstratos/go-myanimelist)](https://goreportcard.com/report/github.com/nstratos/go-myanimelist)\n[![Coverage Status](https://coveralls.io/repos/github/nstratos/go-myanimelist/badge.svg?branch=main)](https://coveralls.io/github/nstratos/go-myanimelist?branch=main)\n[![Test Status](https://github.com/nstratos/go-myanimelist/workflows/tests/badge.svg)](https://github.com/nstratos/go-myanimelist/actions?query=workflow%3Atests)\n[![Integration Status](https://github.com/nstratos/go-myanimelist/workflows/integration/badge.svg)](https://github.com/nstratos/go-myanimelist/actions?query=workflow%3Aintegration)\n\ngo-myanimelist is a Go client library for accessing the [MyAnimeList API v2](https://myanimelist.net/apiconfig/references/api/v2).\n\n## Project Status\n\nThe project has been updated to support MyAnimeList API v2.\n\nAs of March 2017, this package is featured in\n[awesome-go](https://github.com/avelino/awesome-go).\n\n## Installation\n\nThis package can be installed using:\n\n\tgo get github.com/nstratos/go-myanimelist/mal\n\n## Usage\n\nImport the package using:\n\n```go\nimport \"github.com/nstratos/go-myanimelist/mal\"\n```\n\nFirst construct a new mal client:\n\n```go\nc := mal.NewClient(nil)\n```\n\nThen use one of the client's services (User, Anime, Manga and Forum) to access\nthe different MyAnimeList API methods.\n\n## Authentication\n\nWhen creating a new client, pass an `http.Client` that can handle authentication\nfor you. \n\n### Accessing publicly available information\n\nTo access public information, you need to add the ` X-MAL-CLIENT-ID` header in\nyour requests. You can achieve this by creating an `http.Client` with a custom\ntransport and use it as shown below:\n\n```go\ntype clientIDTransport struct {\n\tTransport http.RoundTripper\n\tClientID  string\n}\n\nfunc (c *clientIDTransport) RoundTrip(req *http.Request) (*http.Response, error) {\n\tif c.Transport == nil {\n\t\tc.Transport = http.DefaultTransport\n\t}\n\treq.Header.Add(\"X-MAL-CLIENT-ID\", c.ClientID)\n\treturn c.Transport.RoundTrip(req)\n}\n\nfunc main() {\n\tpublicInfoClient := \u0026http.Client{\n\t\t// Create client ID from https://myanimelist.net/apiconfig. \n\t\tTransport: \u0026clientIDTransport{ClientID: \"\u003cYour application client ID\u003e\"},\n\t}\n\n\tc := mal.NewClient(publicInfoClient)\n\t// ...\n}\n```\n\n### Authenticating using OAuth2\n\nThe recommended way is to use the `golang.org/x/oauth2` package\n(https://github.com/golang/oauth2). After completing the OAuth2 flow, you will\nget an oauth2 token containing an access token, a refresh token and an\nexpiration date. The oauth2 token can easily be stored in JSON format and used\nlike this:\n\n```go\nconst storedToken = `\n{\n\t\"token_type\": \"Bearer\",\n\t\"access_token\": \"yourAccessToken\",\n\t\"refresh_token\": \"yourRefreshToken\",\n\t\"expiry\": \"2021-06-01T16:12:56.1319122Z\"\n}`\n\noauth2Token := new(oauth2.Token)\n_ = json.Unmarshal([]byte(storedToken), oauth2Token)\n\n// Create client ID and secret from https://myanimelist.net/apiconfig. \n//\n// Secret is currently optional if you choose App Type 'other'.\noauth2Conf := \u0026oauth2.Config{\n    ClientID:     \"\u003cEnter your registered MyAnimeList.net application client ID\u003e\",\n    ClientSecret: \"\u003cEnter your registered MyAnimeList.net application client secret\u003e\",\n    Endpoint: oauth2.Endpoint{\n        AuthURL:   \"https://myanimelist.net/v1/oauth2/authorize\",\n        TokenURL:  \"https://myanimelist.net/v1/oauth2/token\",\n        AuthStyle: oauth2.AuthStyleInParams,\n    },\n}\n\noauth2Client := oauth2Conf.Client(ctx, oauth2Token)\n\n// The oauth2Client will refresh the token if it expires.\nc := mal.NewClient(oauth2Client)\n```\n\nNote that all calls made by the client above will include the specified oauth2\ntoken which is specific for an authenticated user. Therefore, authenticated\nclients should almost never be shared between different users.\n\nPerforming the OAuth2 flow involves registering a MAL API application and then\nasking for the user's consent to allow the application to access their data.\n\nThere is a detailed example of how to perform the Oauth2 flow and get an oauth2\ntoken through the terminal under `example/malauth`. The only thing you need to run\nthe example is a client ID and a client secret which you can acquire after\nregistering your MAL API application. Here's how:\n\n 1. Navigate to https://myanimelist.net/apiconfig or go to your MyAnimeList\n    profile, click Edit Profile and select the API tab on the far right.\n\n 2. Click Create ID and submit the form with your application details.\n\nAfter registering your application, you can run the example and pass the client\nID and client secret through flags:\n\n    cd example/malauth\n\tgo run main.go democlient.go --client-id=... --client-secret=...\n\n\tor \n\n    go install github.com/nstratos/go-myanimelist/example/malauth\n    malauth --client-id=... --client-secret=...\n\nAfter you perform a successful authentication once, the oauth2 token will be\ncached in a file under the same directory which makes it easier to run the\nexample multiple times.\n\nOfficial MAL API OAuth2 docs:\nhttps://myanimelist.net/apiconfig/references/authorization\n\n## List\n\nTo search and get anime and manga data:\n\n```go\nlist, _, err := c.Anime.List(ctx, \"hokuto no ken\",\n\tmal.Fields{\"rank\", \"popularity\", \"my_list_status\"},\n\tmal.Limit(5),\n)\n// ...\n\nlist, _, err := c.Manga.List(ctx, \"hokuto no ken\",\n\tmal.Fields{\"rank\", \"popularity\", \"my_list_status\"},\n\tmal.Limit(5),\n)\n// ...\n```\n\nYou may get user specific data for a certain record by using the optional field\n\"my_list_status\".\n\nOfficial docs:\n\n- https://myanimelist.net/apiconfig/references/api/v2#operation/anime_get\n\n- https://myanimelist.net/apiconfig/references/api/v2#operation/manga_get\n\n## UserList\n\nTo get the anime or manga list of a user:\n\n```go\n// Get the authenticated user's anime list, filter only watching anime, sort by\n// last updated, include list status.\nanime, _, err := c.User.AnimeList(ctx, \"@me\",\n    mal.Fields{\"list_status\"},\n    mal.AnimeStatusWatching,\n    mal.SortAnimeListByListUpdatedAt,\n    mal.Limit(5),\n)\n// ...\n\n// Get the authenticated user's manga list's second page, sort by score, \n// include list status, comments and tags.\nmanga, _, err := c.User.MangaList(ctx, \"@me\",\n    mal.SortMangaListByListScore,\n    mal.Fields{\"list_status{comments, tags}\"},\n    mal.Limit(5),\n    mal.Offset(1),\n)\n// ...\n```\n\nYou may provide the username of the user or \"@me\" to get the authenticated\nuser's list.\n\nOfficial docs:\n\n- https://myanimelist.net/apiconfig/references/api/v2#operation/users_user_id_animelist_get\n\n- https://myanimelist.net/apiconfig/references/api/v2#operation/users_user_id_mangalist_get\n\n## MyInfo\n\nTo get information about the authenticated user:\n\n```go\nuser, _, err := c.User.MyInfo(ctx)\n// ...\n```\n\nThis method can use the Fields option but the API doesn't seem to be able to\nsend optional fields like \"anime_statistics\" at the time of writing.\n\nOfficial docs:\n\n- https://myanimelist.net/apiconfig/references/api/v2#operation/users_user_id_get\n\n## Details\n\nTo get details for a certain anime or manga:\n\n```go\na, _, err := c.Anime.Details(ctx, 967,\n\tmal.Fields{\n\t\t\"alternative_titles\",\n\t\t\"media_type\",\n\t\t\"num_episodes\",\n\t\t\"start_season\",\n\t\t\"source\",\n\t\t\"genres\",\n\t\t\"studios\",\n\t\t\"average_episode_duration\",\n\t},\n)\n// ...\n\nm, _, err := c.Manga.Details(ctx, 401,\n\tmal.Fields{\n\t\t\"alternative_titles\",\n\t\t\"media_type\",\n\t\t\"num_volumes\",\n\t\t\"num_chapters\",\n\t\t\"authors{last_name, first_name}\",\n\t\t\"genres\",\n\t\t\"status\",\n\t},\n)\n// ...\n```\n\nBy default most fields are not populated so use the Fields option to request the\nfields you need.\n\nOfficial docs:\n\n- https://myanimelist.net/apiconfig/references/api/v2#operation/anime_anime_id_get\n\n- https://myanimelist.net/apiconfig/references/api/v2#operation/manga_manga_id_get\n\n## Ranking\n\nTo get anime or manga based on a certain ranking:\n\n```go\nanime, _, err := c.Anime.Ranking(ctx,\n\tmal.AnimeRankingAiring,\n\tmal.Fields{\"rank\", \"popularity\"},\n\tmal.Limit(6),\n)\n// ...\n\nmanga, _, err := c.Manga.Ranking(ctx,\n\tmal.MangaRankingByPopularity,\n\tmal.Fields{\"rank\", \"popularity\"},\n\tmal.Limit(6),\n)\n// ...\n```\n\nOfficial docs:\n\n- https://myanimelist.net/apiconfig/references/api/v2#operation/anime_ranking_get\n\n- https://myanimelist.net/apiconfig/references/api/v2#operation/manga_ranking_get\n\n## Add or Update List\n\nTo add or update an entry in an authenticated user's list, provide the anime or\nmanga ID and then options to specify the status, score, comments, tags etc.\n\n```go\n_, _, err := c.Anime.UpdateMyListStatus(ctx, 967,\n\tmal.AnimeStatusWatching,\n\tmal.NumEpisodesWatched(73),\n\tmal.Score(8),\n\tmal.Comments(\"You wa shock!\"),\n\tmal.StartDate(time.Date(2022, 02, 20, 0, 0, 0, 0, time.UTC)),\n\tmal.FinishDate(time.Time{}), // Remove an existing date.\n)\n// ...\n\n_, _, err := c.Manga.UpdateMyListStatus(ctx, 401,\n\tmal.MangaStatusReading,\n\tmal.NumVolumesRead(1),\n\tmal.NumChaptersRead(5),\n\tmal.Comments(\"Migi\"),\n\tmal.StartDate(time.Date(2022, 02, 20, 0, 0, 0, 0, time.UTC)),\n\tmal.FinishDate(time.Time{}), // Remove an existing date.\n)\n// ...\n```\n\nOfficial docs:\n\n- https://myanimelist.net/apiconfig/references/api/v2#operation/anime_anime_id_my_list_status_put\n\n- https://myanimelist.net/apiconfig/references/api/v2#operation/manga_manga_id_my_list_status_put\n\n## Delete\n\nTo delete anime or manga from a user's list, simply provide their IDs:\n\n```go\n_, err := c.Anime.DeleteMyListItem(ctx, 967)\n// ...\n\n_, err := c.Manga.DeleteMyListItem(ctx, 401)\n// ...\n```\n\nOfficial docs:\n\n- https://myanimelist.net/apiconfig/references/api/v2#operation/anime_anime_id_my_list_status_delete\n\n- https://myanimelist.net/apiconfig/references/api/v2#operation/manga_manga_id_my_list_status_delete\n\n## More Examples\n\nSee package examples:\nhttps://pkg.go.dev/github.com/nstratos/go-myanimelist/mal#pkg-examples\n\n## Unit Testing\n\nTo run all unit tests:\n\n\tgo test -cover\n\nTo see test coverage in your browser:\n\n\tgo test -covermode=count -coverprofile=count.out \u0026\u0026 go tool cover -html count.out\n\n## Integration Testing\n\nThe integration tests will exercise the entire package against the live\nMyAnimeList API. As a result, these tests take much longer to run and there is\nalso a much higher chance of false positives in test failures due to network\nissues etc.\n\nThese tests are meant to be run using a dedicated test account that contains\nempty anime and manga lists. A valid oauth2 token needs to be provided every\ntime. Check the authentication section to learn how to get one.\n\nBy default the integration tests are skipped when an oauth2 token is not\nprovided. To run all tests including the integration tests:\n\n\tgo test --client-id='\u003cyour app client ID\u003e' --oauth2-token='\u003cyour oauth2 token\u003e'\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnstratos%2FGo-myanimelist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnstratos%2FGo-myanimelist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnstratos%2FGo-myanimelist/lists"}