v0.7.0
Breaking changes
Flatten the facade: every endpoint function that used to live on an entity module (
Hunter.Account,Hunter.Application,Hunter.Attachment,Hunter.Client,Hunter.Context,Hunter.Instance,Hunter.List,Hunter.Notification,Hunter.Poll,Hunter.Relationship,Hunter.Report,Hunter.Result,Hunter.Status,Hunter.WebPushSubscription) was removed and now lives only onHunter, with the exact same name, arity, and default arguments — the return value is unchanged. These modules are now pure data definitions (defstruct,@type t, and field docs only); their@type tstructs are otherwise unchanged.Hunter.Domainhad no struct and was deleted entirely; its three functions moved toHunterunchanged. Migration is mechanical: replaceHunter.<Entity>.<function>(...)withHunter.<function>(...)at every call site, per the table below. Internally,Hunter.Api.HTTPClientwas deleted; the single transport is nowHunter.Api.Request.request!/6Old module Old call → new call Hunter.AccountHunter.Account.followers/3→Hunter.followers/3; alsoaccount/2,verify_credentials/1,update_credentials/2,following/3,search_account/2,blocks/2,follow_requests/2,mutes/2,accept_follow_request/2,reject_follow_request/2,reblogged_by/3,favourited_by/3Hunter.ApplicationHunter.Application.create_app/5→Hunter.create_app/5;Hunter.Application.load_credentials/1→Hunter.load_credentials/1Hunter.AttachmentHunter.Attachment.upload_media/3→Hunter.upload_media/3; alsomedia_attachment/2,update_media/3,delete_media/2Hunter.ClientHunter.Client.new/1→Hunter.new/1;Hunter.Client.log_in/4→Hunter.log_in/4;Hunter.Client.log_in_oauth/3→Hunter.log_in_oauth/3;Hunter.Client.user_agent/0→Hunter.user_agent/0Hunter.ContextHunter.Context.status_context/2→Hunter.status_context/2Hunter.Domain(module deleted)Hunter.Domain.blocked_domains/2→Hunter.blocked_domains/2; alsoblock_domain/2,unblock_domain/2Hunter.InstanceHunter.Instance.instance_info/1→Hunter.instance_info/1Hunter.ListHunter.List.lists/1→Hunter.lists/1; alsolist/2,create_list/3,update_list/3,destroy_list/2,list_accounts/3,add_accounts_to_list/3,remove_accounts_from_list/3,account_lists/2Hunter.NotificationHunter.Notification.notifications/2→Hunter.notifications/2; alsonotification/2,clear_notifications/1,clear_notification/2,unread_count/1,notification_policy/1,update_notification_policy/2,notification_requests/2,notification_request/2,accept_notification_request/2,dismiss_notification_request/2,accept_notification_requests/2,dismiss_notification_requests/2,notification_requests_merged?/1,grouped_notifications/2,notification_group/2,dismiss_notification_group/2,notification_group_accounts/2,grouped_unread_count/1Hunter.PollHunter.Poll.poll/2→Hunter.poll/2;Hunter.Poll.vote/3→Hunter.vote/3Hunter.RelationshipHunter.Relationship.follow/2→Hunter.follow/2; alsounfollow/2,block/2,unblock/2,mute/2,unmute/2,relationships/2Hunter.ReportHunter.Report.report/4→Hunter.report/4Hunter.ResultHunter.Result.search/3→Hunter.search/3Hunter.StatusHunter.Status.create_status/3→Hunter.create_status/3; alsostatus/2,statuses_by_ids/2,edit_status/4,status_history/2,status_source/2,bookmark/2,unbookmark/2,bookmarks/2,pin/2,unpin/2,mute_conversation/2,unmute_conversation/2,translate_status/3,destroy_status/2,reblog/2,unreblog/2,favourite/2,unfavourite/2,favourites/2,statuses/3,home_timeline/2,public_timeline/2,hashtag_timeline/3,list_timeline/3Hunter.WebPushSubscriptionHunter.WebPushSubscription.create_push_subscription/3→Hunter.create_push_subscription/3; alsopush_subscription/1,update_push_subscription/2,delete_push_subscription/1Typespec honesty (#116): entity
idfields are now typedString.t()— what Mastodon has returned since 2.0 and what the structs actually held at runtime; id parameters acceptString.t() | non_neg_integeras beforeFire-and-forget endpoints (
destroy_status,destroy_list,delete_media,clear_notification(s),block_domain,unblock_domain,add_accounts_to_list,remove_accounts_from_list) now returntrueas theirbooleanspecs always promised, instead of leaking the decoded response body (#116)Require Elixir 1.16+ (media uploads stream the file in raw byte chunks, which needs the
File.stream!(path, bytes)argument order introduced in 1.16); the 1.15 floor existed only for httpoison's transitive dependencies, which are goneThe HTTP stack migrated from HTTPoison/hackney to Req (#103). The
:http_optionsconfiguration key was replaced by:req_options, which takes Req optionsThe
Hunter.Apibehaviour and the:hunter_apiadapter configuration were removed (#103). Entity modules now call the HTTP client directly; to stub Hunter in your tests, intercept requests at the HTTP layer withReq.Testviaconfig :hunter, req_options: [plug: {Req.Test, MyStub}]
Features
- Notifications v2 (#122):
unread_count/1, the notification filtering policy (notification_policy/1,update_notification_policy/2), notification requests (notification_requests/2,notification_request/2,accept_notification_request/2,dismiss_notification_request/2, bulk accept/dismiss,notification_requests_merged?/1) and grouped notifications (grouped_notifications/2,notification_group/2,dismiss_notification_group/2,notification_group_accounts/2,grouped_unread_count/1, newHunter.GroupedNotificationsResultsentity), all onHunter - Web Push subscriptions (#122):
create_push_subscription/3,push_subscription/1,update_push_subscription/2anddelete_push_subscription/1onHunter - Lists support (#121):
lists/1,list/2,create_list/3,update_list/3,destroy_list/2,list_accounts/3,add_accounts_to_list/3,remove_accounts_from_list/3,account_lists/2and thelist_timeline/3timeline, all exposed on theHunterfacade - Status parity endpoints (#120):
edit_status/4,status_history/2,status_source/2,bookmark/2,unbookmark/2,bookmarks/2,pin/2,unpin/2,mute_conversation/2,unmute_conversation/2,translate_status/3andstatuses_by_ids/2(all also exposed on theHunterfacade) - Polls (#120):
Hunter.poll/2andHunter.vote/3, plus thepolloption oncreate_status create_statusupgrades (#120):languageandquoted_status_idoptions;scheduled_atreturns aHunter.ScheduledStatus;idempotency_keyis sent as theIdempotency-Keyheader- Media management (#120):
media_attachment/2(processing status of async uploads),update_media/3anddelete_media/2 - New entities
Hunter.StatusSourceandHunter.StatusEditbacking the status source/history endpoints (#120) - Modernized the existing entity structs to the Mastodon 4.6 shapes
(#119):
Hunter.Status:text,edited_at,replies_count,bookmarked,pinned,emojis,poll,filtered,quote,quote_approvalHunter.Account:uri,last_status_at,group,discoverable,noindex,suspended,limited,hide_collections,roles,attribution_domains,source;fieldsis now a list ofHunter.FieldstructsHunter.Relationship:showing_reblogs,notifying,languages,blocked_by,muting_notifications,muting_expires_at,requested_by,endorsed,noteHunter.Notification:group_key,report,event,moderation_warningHunter.Tag:id,history,following,featuringHunter.Card:blurhash,embed_url,authors(list ofHunter.Card.Author), pluspublished_at/historyfor trending linksHunter.Attachment:blurhash,preview_remote_urlHunter.Emoji:categoryHunter.Application:name,website,redirect_uris,client_secret_expires_at(theCredentialApplicationshape)Hunter.Instance.rulesis now a list ofHunter.Rulestructs
- New entity structs, ready for the endpoints that return them (#119):
Hunter.Poll(andHunter.Poll.Option),Hunter.Quote,Hunter.Filter,Hunter.FilterKeyword,Hunter.FilterStatus,Hunter.FilterResult,Hunter.Translation,Hunter.ScheduledStatus,Hunter.List,Hunter.Conversation,Hunter.Marker,Hunter.Suggestion,Hunter.FeaturedTag,Hunter.Announcement(andHunter.Announcement.Reaction),Hunter.Preferences,Hunter.Field,Hunter.Role,Hunter.NotificationPolicy,Hunter.NotificationRequest,Hunter.NotificationGroup,Hunter.WebPushSubscription,Hunter.Rule,Hunter.ExtendedDescription,Hunter.PrivacyPolicy,Hunter.TermsOfService,Hunter.DomainBlock,Hunter.Collection(andHunter.Collection.Item),Hunter.AnnualReport
- Notifications v2 (#122):
v0.6.0
Features
Hunter.log_in_oauth/3: obtain an access token from an OAuth authorization code (the authorization-code grant), complementing the existing password-grantHunter.log_in/4Hunter.Applicationnow records thescopesandredirect_urithe app was registered with (persisted bysave?: true), so the login helpers can request them
Breaking changes
- Require Elixir 1.15+ and Erlang/OTP 26+ (transitive dependencies of httpoison 3.0 no longer compile on OTP 25)
- Major dependency upgrades: httpoison 1.x → 3.0 and poison 4.x/5.x → 6.0; check for version conflicts with sibling dependencies in your tree
Hunter.Result.hashtagsis now a list ofHunter.Tagstructs (the/api/v2/searchshape) instead of strings.- Removed the
follow_by_urifunction (HunterandHunter.Account): Mastodon 4.0 removedPOST /api/v1/follows. Search for the account and useHunter.follow/2instead. - Removed the
reportslisting function (HunterandHunter.Report): Mastodon removedGET /api/v1/reports. Filing reports viaHunter.report/4still works. - The
Hunter.Apibehaviour contract changed:log_in_oauth/3is a new required callback; thefollow_by_uri/reports/card_by_statuscallbacks were removed; andfollow_request_actionnow returns aHunter.Relationship— custom API adapters need updating Hunter.Clientfieldbearer_tokenwas renamed toaccess_tokenfor consistency with other Mastodon client libraries; updateHunter.Client.new(bearer_token: …)calls toaccess_token:(#101)- Removed the
card_by_statusfunction (HunterandHunter.Card): Mastodon 3.0 removed the endpoint. The preview card is now embedded inHunter.Statusas thecardfield (#118) accept_follow_request/2andreject_follow_request/2now call the documented per-id endpoints and return aHunter.Relationshipinstead of a boolean; the previous implementation matched no Mastodon version and could only fail (#118)Hunter.Instancereshaped to theGET /api/v2/instanceentity (domain,configuration,contact, …); nested objects decode as plain maps for now (#118)
Bug fixes
- GET/DELETE request options now travel as query-string parameters instead of JSON request bodies, which proxies routinely drop (#74)
Hunter.log_in/4now requests the scopes the app was registered with; previously the token silently fell back to Mastodon's defaultreadscope, making every write action fail with "This action is outside the authorized scopes" (#100). Re-runcreate_apponce to refresh saved credentials created by older hunter versions.block_domain/2andunblock_domain/2now send theAuthorizationheader; previously they always failed with "The access token is invalid" (#110)Hunter.log_in_oauth/3now sends theredirect_uriin the token exchange; Doorkeeper rejects the authorization-code grant without it, so the function could never succeed.Hunter.Applicationrecords the redirect URI the app was registered with; stale saved credentials fall back tourn:ietf:wg:oauth:2.0:oob(#112)- Account
emojisnow decode asHunter.Emojistructs, matching the documented typespec; previously they were plain maps (#107) - Notification dismissal uses the documented
POST /api/v1/notifications/:id/dismisspath; the previous path matched no Mastodon version (#118) - Media uploads use
POST /api/v2/media(v1 deprecated since Mastodon 3.1.3); large files process asynchronously and the attachmenturlmay beniluntil ready (#118)
v0.5.1
- Bug fixes
- Fix publishing new statuses (#14)
v0.5.0
- Features
- Add Emoji entity, add new fields on Account entity
- Fix upload_media
- Updated some dependencies
- Include new attributes in some Entities
- Improve exception handling
- Move
reblogged_byandfavourited_byto Account module - Update endpoints according to recent docs
- Fix
create_statusandrelationshipsendpoints - Refactor HTTP Client
- Set default values for API base url and home
- Fix some specs
- Documentation
- Hide internal details from docs
- Fix link to server-sent events docs
- Add more examples in the docs
v0.4.0
- Features
- Update current user:
Hunter.update_credentials/2 - Register an application:
Hunter.create_app/5 - Load persisted app credentials:
Hunter.load_credentials/1 - Acquire access token:
Hunter.log_in/4 - Get who reblogged a status:
Hunter.reblogged_by/2 - Get who favorited a status:
Hunter.favourited_by/2 - Authorize follow requests:
Hunter.accept_follow_request/2 - Reject follow requests:
Hunter.reject_follow_request/2
- Update current user:
- Documentation
- Add more examples in the README
- How to contribute guide
- Code of conduct
v0.3.0
- Features:
- Search for accounts or content
- Get an account's relationship
- Fetch user's blocks
- Fetch a list of follow requests
- Fetch user's mutes
- Get instance information
- Fetch user's notifications
- Getting a single notification
- Clear notifications
- Fetch user's reports
- Report a user
- Get status context
- Get a card associated with a status
v0.2.0
- Features:
- Add media files
- Fetching user's favorites
- (un)favoriting a status
## v0.1.0
- Initial release