123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- package mastodon
- import (
- "context"
- "fmt"
- "net/http"
- "net/url"
- "strconv"
- "time"
- )
- type AccountPleroma struct {
- Relationship Relationship `json:"relationship"`
- }
- // Account hold information for mastodon account.
- type Account struct {
- ID string `json:"id"`
- Username string `json:"username"`
- Acct string `json:"acct"`
- DisplayName string `json:"display_name"`
- Locked bool `json:"locked"`
- CreatedAt time.Time `json:"created_at"`
- FollowersCount int64 `json:"followers_count"`
- FollowingCount int64 `json:"following_count"`
- StatusesCount int64 `json:"statuses_count"`
- Note string `json:"note"`
- URL string `json:"url"`
- Avatar string `json:"avatar"`
- AvatarStatic string `json:"avatar_static"`
- Header string `json:"header"`
- HeaderStatic string `json:"header_static"`
- Emojis []Emoji `json:"emojis"`
- Moved *Account `json:"moved"`
- Fields []Field `json:"fields"`
- Bot bool `json:"bot"`
- Pleroma *AccountPleroma `json:"pleroma"`
- }
- // Field is a Mastodon account profile field.
- type Field struct {
- Name string `json:"name"`
- Value string `json:"value"`
- VerifiedAt time.Time `json:"verified_at"`
- }
- // AccountSource is a Mastodon account profile field.
- type AccountSource struct {
- Privacy *string `json:"privacy"`
- Sensitive *bool `json:"sensitive"`
- Language *string `json:"language"`
- Note *string `json:"note"`
- Fields *[]Field `json:"fields"`
- }
- // GetAccount return Account.
- func (c *Client) GetAccount(ctx context.Context, id string) (*Account, error) {
- var account Account
- err := c.doAPI(ctx, http.MethodGet, fmt.Sprintf("/api/v1/accounts/%s", url.PathEscape(string(id))), nil, &account, nil)
- if err != nil {
- return nil, err
- }
- if account.Pleroma == nil {
- rs, err := c.GetAccountRelationships(ctx, []string{id})
- if err != nil {
- return nil, err
- }
- if len(rs) > 0 {
- account.Pleroma = &AccountPleroma{*rs[0]}
- }
- }
- return &account, nil
- }
- // GetAccountCurrentUser return Account of current user.
- func (c *Client) GetAccountCurrentUser(ctx context.Context) (*Account, error) {
- var account Account
- err := c.doAPI(ctx, http.MethodGet, "/api/v1/accounts/verify_credentials", nil, &account, nil)
- if err != nil {
- return nil, err
- }
- return &account, nil
- }
- // Profile is a struct for updating profiles.
- type Profile struct {
- // If it is nil it will not be updated.
- // If it is empty, update it with empty.
- DisplayName *string
- Note *string
- Locked *bool
- Fields *[]Field
- Source *AccountSource
- // Set the base64 encoded character string of the image.
- Avatar string
- Header string
- }
- // AccountUpdate updates the information of the current user.
- func (c *Client) AccountUpdate(ctx context.Context, profile *Profile) (*Account, error) {
- params := url.Values{}
- if profile.DisplayName != nil {
- params.Set("display_name", *profile.DisplayName)
- }
- if profile.Note != nil {
- params.Set("note", *profile.Note)
- }
- if profile.Locked != nil {
- params.Set("locked", strconv.FormatBool(*profile.Locked))
- }
- if profile.Fields != nil {
- for idx, field := range *profile.Fields {
- params.Set(fmt.Sprintf("fields_attributes[%d][name]", idx), field.Name)
- params.Set(fmt.Sprintf("fields_attributes[%d][value]", idx), field.Value)
- }
- }
- if profile.Source != nil {
- if profile.Source.Privacy != nil {
- params.Set("source[privacy]", *profile.Source.Privacy)
- }
- if profile.Source.Sensitive != nil {
- params.Set("source[sensitive]", strconv.FormatBool(*profile.Source.Sensitive))
- }
- if profile.Source.Language != nil {
- params.Set("source[language]", *profile.Source.Language)
- }
- }
- if profile.Avatar != "" {
- params.Set("avatar", profile.Avatar)
- }
- if profile.Header != "" {
- params.Set("header", profile.Header)
- }
- var account Account
- err := c.doAPI(ctx, http.MethodPatch, "/api/v1/accounts/update_credentials", params, &account, nil)
- if err != nil {
- return nil, err
- }
- return &account, nil
- }
- // GetAccountStatuses return statuses by specified accuont.
- func (c *Client) GetAccountStatuses(ctx context.Context, id string, onlyMedia bool, pg *Pagination) ([]*Status, error) {
- var statuses []*Status
- params := url.Values{}
- params.Set("only_media", strconv.FormatBool(onlyMedia))
- err := c.doAPI(ctx, http.MethodGet, fmt.Sprintf("/api/v1/accounts/%s/statuses", url.PathEscape(string(id))), params, &statuses, pg)
- if err != nil {
- return nil, err
- }
- return statuses, nil
- }
- // GetAccountFollowers return followers list.
- func (c *Client) GetAccountFollowers(ctx context.Context, id string, pg *Pagination) ([]*Account, error) {
- var accounts []*Account
- err := c.doAPI(ctx, http.MethodGet, fmt.Sprintf("/api/v1/accounts/%s/followers", url.PathEscape(string(id))), nil, &accounts, pg)
- if err != nil {
- return nil, err
- }
- return accounts, nil
- }
- // GetAccountFollowing return following list.
- func (c *Client) GetAccountFollowing(ctx context.Context, id string, pg *Pagination) ([]*Account, error) {
- var accounts []*Account
- err := c.doAPI(ctx, http.MethodGet, fmt.Sprintf("/api/v1/accounts/%s/following", url.PathEscape(string(id))), nil, &accounts, pg)
- if err != nil {
- return nil, err
- }
- return accounts, nil
- }
- // GetBlocks return block list.
- func (c *Client) GetBlocks(ctx context.Context, pg *Pagination) ([]*Account, error) {
- var accounts []*Account
- err := c.doAPI(ctx, http.MethodGet, "/api/v1/blocks", nil, &accounts, pg)
- if err != nil {
- return nil, err
- }
- return accounts, nil
- }
- // Relationship hold information for relation-ship to the account.
- type Relationship struct {
- ID string `json:"id"`
- Following bool `json:"following"`
- FollowedBy bool `json:"followed_by"`
- Blocking bool `json:"blocking"`
- Muting bool `json:"muting"`
- MutingNotifications bool `json:"muting_notifications"`
- Subscribing bool `json:"subscribing"`
- Requested bool `json:"requested"`
- DomainBlocking bool `json:"domain_blocking"`
- ShowingReblogs bool `json:"showing_reblogs"`
- Endorsed bool `json:"endorsed"`
- }
- // AccountFollow follow the account.
- func (c *Client) AccountFollow(ctx context.Context, id string, reblogs *bool) (*Relationship, error) {
- var relationship Relationship
- params := url.Values{}
- if reblogs != nil {
- params.Set("reblogs", strconv.FormatBool(*reblogs))
- }
- err := c.doAPI(ctx, http.MethodPost, fmt.Sprintf("/api/v1/accounts/%s/follow", url.PathEscape(id)), params, &relationship, nil)
- if err != nil {
- return nil, err
- }
- return &relationship, nil
- }
- // AccountUnfollow unfollow the account.
- func (c *Client) AccountUnfollow(ctx context.Context, id string) (*Relationship, error) {
- var relationship Relationship
- err := c.doAPI(ctx, http.MethodPost, fmt.Sprintf("/api/v1/accounts/%s/unfollow", url.PathEscape(string(id))), nil, &relationship, nil)
- if err != nil {
- return nil, err
- }
- return &relationship, nil
- }
- // AccountBlock block the account.
- func (c *Client) AccountBlock(ctx context.Context, id string) (*Relationship, error) {
- var relationship Relationship
- err := c.doAPI(ctx, http.MethodPost, fmt.Sprintf("/api/v1/accounts/%s/block", url.PathEscape(string(id))), nil, &relationship, nil)
- if err != nil {
- return nil, err
- }
- return &relationship, nil
- }
- // AccountUnblock unblock the account.
- func (c *Client) AccountUnblock(ctx context.Context, id string) (*Relationship, error) {
- var relationship Relationship
- err := c.doAPI(ctx, http.MethodPost, fmt.Sprintf("/api/v1/accounts/%s/unblock", url.PathEscape(string(id))), nil, &relationship, nil)
- if err != nil {
- return nil, err
- }
- return &relationship, nil
- }
- // AccountMute mute the account.
- func (c *Client) AccountMute(ctx context.Context, id string) (*Relationship, error) {
- var relationship Relationship
- err := c.doAPI(ctx, http.MethodPost, fmt.Sprintf("/api/v1/accounts/%s/mute", url.PathEscape(string(id))), nil, &relationship, nil)
- if err != nil {
- return nil, err
- }
- return &relationship, nil
- }
- // AccountUnmute unmute the account.
- func (c *Client) AccountUnmute(ctx context.Context, id string) (*Relationship, error) {
- var relationship Relationship
- err := c.doAPI(ctx, http.MethodPost, fmt.Sprintf("/api/v1/accounts/%s/unmute", url.PathEscape(string(id))), nil, &relationship, nil)
- if err != nil {
- return nil, err
- }
- return &relationship, nil
- }
- // GetAccountRelationships return relationship for the account.
- func (c *Client) GetAccountRelationships(ctx context.Context, ids []string) ([]*Relationship, error) {
- params := url.Values{}
- for _, id := range ids {
- params.Add("id[]", id)
- }
- var relationships []*Relationship
- err := c.doAPI(ctx, http.MethodGet, "/api/v1/accounts/relationships", params, &relationships, nil)
- if err != nil {
- return nil, err
- }
- return relationships, nil
- }
- // AccountsSearch search accounts by query.
- func (c *Client) AccountsSearch(ctx context.Context, q string, limit int64) ([]*Account, error) {
- params := url.Values{}
- params.Set("q", q)
- params.Set("limit", fmt.Sprint(limit))
- var accounts []*Account
- err := c.doAPI(ctx, http.MethodGet, "/api/v1/accounts/search", params, &accounts, nil)
- if err != nil {
- return nil, err
- }
- return accounts, nil
- }
- // FollowRemoteUser send follow-request.
- func (c *Client) FollowRemoteUser(ctx context.Context, uri string) (*Account, error) {
- params := url.Values{}
- params.Set("uri", uri)
- var account Account
- err := c.doAPI(ctx, http.MethodPost, "/api/v1/follows", params, &account, nil)
- if err != nil {
- return nil, err
- }
- return &account, nil
- }
- // GetFollowRequests return follow-requests.
- func (c *Client) GetFollowRequests(ctx context.Context, pg *Pagination) ([]*Account, error) {
- var accounts []*Account
- err := c.doAPI(ctx, http.MethodGet, "/api/v1/follow_requests", nil, &accounts, pg)
- if err != nil {
- return nil, err
- }
- return accounts, nil
- }
- // FollowRequestAuthorize is authorize the follow request of user with id.
- func (c *Client) FollowRequestAuthorize(ctx context.Context, id string) error {
- return c.doAPI(ctx, http.MethodPost, fmt.Sprintf("/api/v1/follow_requests/%s/authorize", url.PathEscape(string(id))), nil, nil, nil)
- }
- // FollowRequestReject is rejects the follow request of user with id.
- func (c *Client) FollowRequestReject(ctx context.Context, id string) error {
- return c.doAPI(ctx, http.MethodPost, fmt.Sprintf("/api/v1/follow_requests/%s/reject", url.PathEscape(string(id))), nil, nil, nil)
- }
- // GetMutes returns the list of users muted by the current user.
- func (c *Client) GetMutes(ctx context.Context, pg *Pagination) ([]*Account, error) {
- var accounts []*Account
- err := c.doAPI(ctx, http.MethodGet, "/api/v1/mutes", nil, &accounts, pg)
- if err != nil {
- return nil, err
- }
- return accounts, nil
- }
- // Subscribe to receive notifications for all statuses posted by a user
- func (c *Client) Subscribe(ctx context.Context, id string) (*Relationship, error) {
- var relationship *Relationship
- err := c.doAPI(ctx, http.MethodPost, fmt.Sprintf("/api/v1/pleroma/accounts/%s/subscribe", url.PathEscape(id)), nil, &relationship, nil)
- if err != nil {
- return nil, err
- }
- return relationship, nil
- }
- // UnSubscribe to stop receiving notifications from user statuses
- func (c *Client) UnSubscribe(ctx context.Context, id string) (*Relationship, error) {
- var relationship *Relationship
- err := c.doAPI(ctx, http.MethodPost, fmt.Sprintf("/api/v1/pleroma/accounts/%s/unsubscribe", url.PathEscape(id)), nil, &relationship, nil)
- if err != nil {
- return nil, err
- }
- return relationship, nil
- }
- // GetBookmarks returns the list of bookmarked statuses
- func (c *Client) GetBookmarks(ctx context.Context, pg *Pagination) ([]*Status, error) {
- var statuses []*Status
- err := c.doAPI(ctx, http.MethodGet, "/api/v1/bookmarks", nil, &statuses, pg)
- if err != nil {
- return nil, err
- }
- return statuses, nil
- }
|