billstclair/elm-mastodon/6.0.2

NOTE: the latest version is 24.0.0

Mastodon.Request

Types to represent the Mastodon REST API.

Funcion to generate a request and parse the return.

Documentation starts at https://docs.joinmastodon.org/api/rest/accounts

Basic Types

type alias ServerInfo =
{ server : String
, token : Maybe String
}

Used to create the HTTP URL and fill in its authentication token.

It's the host name for the URL.

Example server: "mastodon.social".

A few requests do not require a token. Most do, and will error if you don't include one.

type Request
= AccountsRequest AccountsReq
| AppsRequest AppsReq
| BlocksRequest BlocksReq
| CustomEmojisRequest CustomEmojisReq
| DomainBlocksRequest DomainBlocksReq
| EndorsementsRequest EndorsementsReq
| FavouritesRequest FavouritesReq
| FiltersRequest FiltersReq
| FollowRequestsRequest FollowRequestsReq
| FollowSuggestionsRequest FollowSuggestionsReq
| GroupsRequest GroupsReq
| InstanceRequest InstanceReq
| ListsRequest ListsReq
| MediaAttachmentsRequest MediaAttachmentsReq
| MutesRequest MutesReq
| NotificationsRequest NotificationsReq
| PollsRequest PollsReq
| ReportsRequest ReportsReq
| ScheduledStatusesRequest ScheduledStatusesReq
| SearchRequest SearchReq
| StatusesRequest StatusesReq
| TimelinesRequest TimelinesReq
| TrendsRequest TrendsReq

An API request.

Broken down as in the documentation.

Result entity types are documented with the various "xxxReq" types.

type alias Response =
{ request : Request
, rawRequest : RawRequest
, metadata : Metadata
, entity : Entity
}

A response from an API request.

The request is a copy of the Request that was sent over the wire, for cases where that isn't obvious from the Entity tag.

The metadata is Http.Metadata for a successful request, mostly so you can get to the headers, if you need them.

type Error
= BadUrl String
| Timeout
| NetworkError
| BadStatus Metadata String
| BadBody Metadata Error String

Encodes an error from the server request.

Same as Http.Error, but includes Http.Metadata when it's available.

The String in a BadStatus is the Http error message, usually HTML.

The Error in BadBody is a Json.Decode.Error. The String in BadBody is the JSON string returned by the Http request.

Creating an HTTP request

(id -> Result Error Response -> msg)
-> List Header
-> ServerInfo
-> id
-> Cmd msg

Create an HTTP request for the server.

The id is whatever you need, besides the Request, to identify the returned Error or Response.

You will often pass [] for headers, but including a "User-Agent" header is usually a good idea. For example, https://mammudeck.com uses:

[ Mastodon.Request.userAgentHeader "Mammudeck" ]

Request details

= GetVerifyCredentials
| GetAccountByUsername { username : String }
| GetAccount { id : String }
| PatchUpdateCredentials
{ display_name : Maybe String
, note : Maybe String
, avatar : Maybe File
, header : Maybe File
, locked : Maybe Bool
, source : Maybe SourceUpdate
, fields_attributes : Maybe (List FieldUpdate)
}
| GetFollowers
{ id : String
, limit : Maybe Int
}
| GetFollowing
{ id : String
, limit : Maybe Int
}
| GetStatuses
{ id : String
, only_media : Bool
, pinned : Bool
, exclude_replies : Bool
, paging : Maybe Paging
, exclude_reblogs : Bool
}
| PostFollow
{ id : String
, reblogs : Bool
}
| PostUnfollow { id : String }
| GetRelationships { ids : List String }
| GetSearchAccounts
{ q : String
, limit : Maybe Int
, resolve : Bool
, following : Bool
}

GET/POST/PATCH /api/v1/accounts

(and GET /api/v1/account_by_username)

GetAccountByUsername and GetAccount do not require an authentication token.

GetAccountByUsername, GetAccount, GetVerifyCredentials, and PatchUpdateCredentials result in an AccountEntity.

GetFollowers, GetFollowing, and GetSearchAccounts result in an AccountListEntity.

GetStatuses results in a StatusListEntity.

PostFollow and PostUnfollow result in a RelationshipEntity.

GetRelationships results in a RelationshipListEntity.

GetAccountByUsername (GET account_by_username) is not documented, and may be Gab-only.

The fields_attributes list in PatchUpdateCredentials will be silently shortened to four elements if it's longer than that. If it's shorter than four elements, then the fields past those specified will be cleared.

type AppsReq
= PostApp
{ client_name : String
, redirect_uris : String
, scopes : List String
, website : Maybe String
}
| GetVerifyAppCredentials

GET/POST /api/v1/apps

PostApp results in an AppEntity.

These are not associated with your account on Mastodon servers, but they need to be deleted when you're done with them on Pleroma servers (if you use one to get a token, and you wouldn't bother to make it except for that). I don't know yet how to delete them, except in the Pleroma server's web API (the "Security" tab at https://<pleroma-server.com>/user-settings).

You will rarely use PostApp directly, instead allowing the functions in the Mastodon.Login module to do that for you.

= GetBlocks { limit : Maybe Int }
| PostBlock { id : String }
| PostUnblock { id : String }

GET/POST /api/v1/blocks

GetBlocks results in an AccountListEntity.

PostBlock and PostUnblock result in a RelationshipEntity.

= GetCustomEmojis

GET /api/v8/custom_emojis

GetCustomEmojis results in an EmojiListEntity.

= GetDomainBlocks { limit : Maybe Int }
| PostDomainBlock { domain : String }
| DeleteDomainBlock { domain : String }

GET/POST /api/v8/domain_blocks

GetDomainBlocks results in a StringListEntity, a list of domain names.

PostDomainBlock and DeleteDomainBlock result in NoEntity.

= GetEndorsements
| PostPinAccount { id : String }
| PostUnpinAccount { id : String }

GET/POST /api/v1/endorsements

GetEndorsements results in an AccountListEntity.

PostPinAccount and PostUnpinAccount result in a RelationshipEntity.

= GetFavourites { limit : Maybe Int }
| PostFavourite { id : String }
| PostUnfavourite { id : String }

GET/POST /api/v1/favourites

GetFavourites results in a StatusListEntity.

PostFavourite and PostUnfavorite result in a StatusEntity.

= GetFilters
| PostFilter
{ phrase : String
, context : List FilterContext
, irreversible : Bool
, whole_word : Bool
, expires_in : Maybe Int
}
| GetFilter { id : String }
| PutFilter
{ id : String
, phrase : String
, context : List FilterContext
, irreversible : Bool
, whole_word : Bool
, expires_in : Maybe Int
}
| DeleteFilter { id : String }

GET/POST/PUT /api/v1/filters

GetFilters results in a FilterListEntity.

PostFilter, GetFilter, and PutFilter result in a FilterEntity.

DeleteFilter results in NoEntity.

= GetFollowRequests { limit : Maybe Int }
| PostAuthorizeFollow { id : String }
| PostRejectFollow { id : String }

GET/POST /api/v1/follow_requests

GetFollowRequests results in an AccountListEntity.

PostAuthorizeFollow and PostRejectFollow result in NoEntity.

= GetFollowSuggestions
| DeleteFollowSuggestions { account_id : String }

GET/DELETE /api/v1/suggestions

GetFollowSuggestions results in an AccountListEntity.

DeleteFollowSuggestions results in NoEntity.

= GetGroups { tab : WhichGroups }
| GetGroup { id : String }
| GetGroupAccounts { id : String }
| PostGroup
{ title : String
, description : String
, cover_image : Maybe File
}
| PutGroup
{ id : String
, title : Maybe String
, description : Maybe String
, cover_image : Maybe File
}
| GetGroupRelationships { ids : List String }
| PostGroupJoin { id : String }
| DeleteGroupJoin { id : String }
| DeleteGroupStatus
{ id : String
, status_id : String
}
| GetGroupRemovedAccounts { id : String }
| PostGroupRemovedAccounts
{ id : String
, account_id : String
}
| DeleteGroupRemovedAccounts
{ id : String
, account_id : String
}
| PatchGroupAddAdministrator
{ id : String
, account_id : String
}

GET /api/v1/groups

The groups API is Gab-only.

GetGroups results in a GroupListEntity.

GetGroup, PostGroup, and PutGroup result in a GroupEntity

GetGroupRelationships results in a GroupRelationshipListEntity.

GetGroupAccounts and GetGroupRemovedAccounts result in an AccountListEntity.

PostGroupJoin results in a GroupRelationshipEntity.

DeleteGroupJoin, DeleteGroupStatus, PostGroupRemovedAccounts, DeleteGroupRemovedAccounts, and PatchGroupAddAdministrator result in NoEntity.

Descriptions

GetGroups fetches the list of all groups of which the logged-in account is a member.

GetGroup fetches one group.

GetGroupAccounts returns the members of a group.

GetGroupRelationships gets the logged-in account relationships for one or more groups.

PostGroup creates a new group.

PutGroup updates the group profile information.

PostGroupJoin joins a group from the logged-in account.

DeletGroupJoin leaves a group from the logged-in account.

DeleteGroupStatus removes a status from the group.

GetGroupRemovedAccounts returns the list of removed accounts for a group.

PostGroupRemovedAccounts revokes group membership for an account.

DeleteGroupRemovedAccounts removes a previously revoked membership from the list of deleted accounts.

PatchGroupAddAdministrator adds an administrator to a group. There is currently no way to remove an administrator, except to remove the account from the group.

= GetInstance
| GetActivity
| GetPeers

GET /api/v1/instance

= GetLists
| GetAccountLists { id : String }
| GetListAccounts
{ id : String
, limit : Maybe Int
}
| GetList { id : String }
| PostList { title : String }
| PutList
{ id : String
, title : String
}
| DeleteList { id : String }
| PostListAccounts
{ id : String
, account_ids : List String
}
| DeleteListAccounts
{ id : String
, account_ids : List String
}

GET/POST/PUT/DELETE /api/v1/lists

GetLists and GetAccountLists result in a ListEntityEntity.

GetListAccounts results in an AccountListEntity.

GetList, PostList, and PutList result in a ListEntity.

PostListAccounts and DeleteListAccounts result in NoEntity.

= PostMedia
{ file : File
, description : Maybe String
, focus : Maybe Focus
}
| PutMedia
{ id : String
, description : Maybe String
, focus : Maybe Focus
}

GET/POST /api/v1/media

PostMedia and PutMedia result in an AttachmentEntity.

= GetAccountMutes { limit : Maybe Int }
| PostAccountMute
{ id : String
, notifications : Bool
}
| PostAccountUnmute { id : String }
| PostStatusMute { id : String }
| PostStatusUnmute { id : String }

GET/POST /api/v1/mutes

GetAccountMutes results in an AccountListEntity.

PostAccountMute and PostAccountUnmute result in a RelationshipEntity.

PostStatusMute and PostStatusUnmute result in a StatusEntity.

= GetNotifications
{ paging : Maybe Paging
, exclude_types : List NotificationType
, account_id : Maybe String
}
| GetNotification { id : String }
| PostClearNotifications
| PostDismissNotification { id : String }

GET/POST /api/v1/notifications

GetNotifications results in a NotificationListEntity.

GetNotification results in NotificationEntity.

PostClearNotifications and PostDismissNotifications result in NoEntity.

This doesn't yet define requests for "POST /api/v1/push/subscription", "GET /api/v1/push/subscription", "PUT /api/v1/push/subscription", or "DELETE /api/v1/push/subscription".

= GetPoll { id : String }
| PostVotes
{ id : String
, choices : List Int
}

GET/POST /api/v1/polls

GetPoll and PostVotes result in a PollInstance.

GetPoll does not require an authentication token.

= PostReports
{ account_id : String
, status_ids : List String
, comment : Maybe String
, forward : Bool
}

POST /api/v1/reports

PostReports results in NoInstance.

= GetScheduledStatuses
| GetScheduledStatus { id : String }
| PutScheduledStatus
{ id : String
, scheduled_at : Maybe UnixTimestamp
}
| DeleteScheduledStatus { id : String }

GET/PUT /api/v1/scheduled_statuses

GetScheduledStatuses results in a ScheduledStatusListInstance.

GetScheduledStatus and PutScheduledStatus result in a ScheduledStatusInstance.

DeleteScheduledStatus results in NoInstance.

= GetSearch
{ q : String
, resolve : Bool
, limit : Maybe Int
, offset : Maybe Int
, following : Bool
}

GET/POST /api/v1/search

GetSearch results in a ResultsInstance.

= GetStatus { id : String }
| GetStatusContext { id : String }
| GetStatusCard { id : String }
| GetStatusRebloggedBy
{ id : String
, limit : Maybe Int
}
| GetStatusFavouritedBy
{ id : String
, limit : Maybe Int
}
| PostStatus
{ status : Maybe String
, in_reply_to_id : Maybe String
, group_id : Maybe String
, quote_of_id : Maybe String
, media_ids : List String
, poll : Maybe PollDefinition
, sensitive : Bool
, spoiler_text : Maybe String
, visibility : Maybe Visibility
, scheduled_at : Maybe Datetime
, language : Maybe ISO6391
, idempotencyKey : Maybe String
}
| DeleteStatus { id : String }
| PostReblogStatus { id : String }
| PostUnreblogStatus { id : String }
| PostPinStatus { id : String }
| PostUnpinStatus { id : String }

GET/POST /api/v1/statuses

GetStatus, PostStatus, PostReblogStatus, PostUnreblogStatus, PostPinStatus, and PostUnpinStatus result in a StatusEntity.

GetStatusContext results in a ContextEntity.

GetStatusCard results in a CardEntity.

GetStatusRebloggedBy and GetStatusFavouritedBy result in an AccountListEntity.

DeleteStatus results in NoEntity.

The GetXxx requests require no authentication token.

= GetHomeTimeline { paging : Maybe Paging }
| GetConversations { paging : Maybe Paging }
| GetPublicTimeline
{ local : Bool
, only_media : Bool
, paging : Maybe Paging
}
| GetTagTimeline
{ hashtag : String
, local : Bool
, only_media : Bool
, paging : Maybe Paging
}
| GetListTimeline
{ list_id : String
, paging : Maybe Paging
}
| GetGroupTimeline
{ group_id : String
, paging : Maybe Paging
}

GET/POST /api/v1/timelines

GetHomeTimeline, GetPublicTimeline, GetTagTimeline, and GetListTimeline result in a StatusListEntity.

GetConversations results in a ConversationListEntity.

GetPublicTimeline and GetTagTimeline do not require an authentication token.

= GetTrends

GET /api/v1/trends

GetTrends results in a TagListEntity.

Non-atomic data in requests

type alias Paging =
{ max_id : Maybe String
, since_id : Maybe String
, min_id : Maybe String
, limit : Maybe Int
}

Parameters to control paging for requests that return lists.

type alias SourceUpdate =
{ privacy : Maybe Privacy
, sensitive : Maybe Bool
, language : Maybe (Maybe ISO6391)
}

Updated account Source information

type alias FieldUpdate =
{ name : String
, value : HtmlString
}

Updated account Field information.

type alias PollDefinition =
{ options : List String
, expires_in : Int
, multiple : Bool
, hide_totals : Bool
}

Define a Poll as part of a posted new Status

= MemberGroups
| FeaturedGroups
| AdminGroups

Which groups to return from GetGroups { tab : WhichGroups }

Utility

userAgentHeader : String -> Header

Only required by GitHub that I know of, but can't hurt.

Pass whatever string describes your user agent. Or fake a common one.

idempotencyKeyHeader : String -> Header

Create an "Idempotency-Key" header for use with PostStatus.

Usually, you will create this header by passing Just key for the idempotencyKey property of the parameter to PostStatus, but if you need to create it in another context, use this.

emptyPaging : Paging

The default Paging instance, with no restrictions.

simplePostStatus : String -> Maybe String -> Maybe String -> Request

Create a PostStatus request using only the most common non-blank fields.

Parameters are:

simplePostStatus status in_reply_to_id spoiler_text

Low-level request creation

type alias RawRequest =
{ method : String
, token : Maybe String
, url : String
, headers : List Header
, body : Body
, request : Request
, jsonBody : Maybe Value
, decoder : Decoder Entity
}

Represent an HTTP request.

Usually, you will let serverRequest create one of these internally.

Sometimes, however, you need to create one yourself, or call requestToRawRequest to make one, make changes to it, and then call rawRequestToCmd.

requestToRawRequest : List Header -> ServerInfo -> Request -> RawRequest

Convert a Request into a RawRequest.

You will usually not call this yourself, but let serverRequest do it internally.

Sometimes, however, you need to call this to create a RawRequest, modify it, and then call rawRequestToCmd to turn it into a Cmd.

rawRequestToCmd : (Result Error Response -> msg) -> RawRequest -> Cmd msg

Convert a RawRequest into a Cmd.

You will usually not call this yourself, but let serverRequest do it internally.

Sometimes, however, you need to create a RawRequest, by hand or by calling requestToRawRequest, then pass it here to turn it into a Cmd.

rawRequestToTask : RawRequest -> Task Error Response

Same as rawRequestToCmd, but returns a Task.

rawRequestToCmd could be defined as:

rawRequestToCmd : (Result Error Response -> msg) -> RawRequest -> Cmd msg
rawRequestToCmd tagger rawRequest =
    Task.attempt tagger <|
        rawRequestToTask rawRequest

Testing

emptyRawRequest : RawRequest

An empty raw request.

Exposed only for testing in elm repl.

emptyServerInfo : ServerInfo

For testing in elm repl.