UNPKG

megalodon

Version:

Fediverse API client for node.js and browser

1,470 lines (1,469 loc) 56.9 kB
import { OAuth2Client } from '@badgateway/oauth2-client'; import FormData from 'form-data'; import dayjs from 'dayjs'; import { parseLinkHeader } from './parse_link_header.js'; import GotosocialAPI from './gotosocial/api_client.js'; import { NotImplementedError } from './megalodon.js'; import { NO_REDIRECT, DEFAULT_SCOPE, DEFAULT_UA } from './default.js'; import * as GotosocialOAuth from './gotosocial/oauth.js'; import { UnknownNotificationTypeError } from './notification.js'; export default class Gotosocial { client; baseUrl; constructor(baseUrl, accessToken = null, userAgent = DEFAULT_UA) { let token = ''; if (accessToken) { token = accessToken; } let agent = DEFAULT_UA; if (userAgent) { agent = userAgent; } this.client = new GotosocialAPI.Client(baseUrl, token, agent); this.baseUrl = baseUrl; } cancel() { return this.client.cancel(); } async registerApp(client_name, options) { const scopes = options.scopes || DEFAULT_SCOPE; return this.createApp(client_name, options).then(async (appData) => { return this.generateAuthUrl(appData.client_id, appData.client_secret, { scope: scopes, redirect_uri: appData.redirect_uri }).then(url => { appData.url = url; return appData; }); }); } async createApp(client_name, options) { const scopes = options.scopes || DEFAULT_SCOPE; const redirect_uris = options.redirect_uris || NO_REDIRECT; const params = { client_name: client_name, redirect_uris: redirect_uris, scopes: scopes.join(' ') }; if (options.website) params.website = options.website; return this.client .post('/api/v1/apps', params) .then((res) => GotosocialOAuth.toAppData(res.data)); } generateAuthUrl(clientId, clientSecret, options) { const scope = options.scope || DEFAULT_SCOPE; const redirect_uri = options.redirect_uri || NO_REDIRECT; return new Promise(resolve => { const oauthClient = new OAuth2Client({ server: this.baseUrl, clientId: clientId, clientSecret: clientSecret, tokenEndpoint: '/oauth/token', authorizationEndpoint: '/oauth/authorize' }); const url = oauthClient.authorizationCode.getAuthorizeUri({ redirectUri: redirect_uri, scope: scope }); resolve(url); }); } verifyAppCredentials() { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async fetchAccessToken(client_id, client_secret, code, redirect_uri = NO_REDIRECT) { if (!client_id) { throw new Error('client_id is required'); } return this.client .post('/oauth/token', { client_id, client_secret, code, redirect_uri, grant_type: 'authorization_code' }) .then((res) => GotosocialOAuth.toTokenData(res.data)); } async refreshToken(client_id, client_secret, refresh_token) { return this.client .post('/oauth/token', { client_id, client_secret, refresh_token, grant_type: 'refresh_token' }) .then((res) => GotosocialOAuth.toTokenData(res.data)); } async revokeToken(client_id, client_secret, token) { return this.client.post('/oauth/revoke', { client_id, client_secret, token }); } async registerAccount(username, email, password, agreement, locale, reason) { let params = { username: username, email: email, password: password, agreement: agreement, locale: locale }; if (reason) { params = Object.assign(params, { reason: reason }); } return this.client.post('/api/v1/accounts', params).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.token(res.data) }); }); } async verifyAccountCredentials() { return this.client.get('/api/v1/accounts/verify_credentials').then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.account(res.data) }); }); } async updateCredentials(options) { let params = {}; if (options) { if (options.discoverable !== undefined) { params = Object.assign(params, { discoverable: options.discoverable }); } if (options.bot !== undefined) { params = Object.assign(params, { bot: options.bot }); } if (options.display_name) { params = Object.assign(params, { display_name: options.display_name }); } if (options.note) { params = Object.assign(params, { note: options.note }); } if (options.avatar) { params = Object.assign(params, { avatar: options.avatar }); } if (options.header) { params = Object.assign(params, { header: options.header }); } if (options.locked !== undefined) { params = Object.assign(params, { locked: options.locked }); } if (options.source) { params = Object.assign(params, { source: options.source }); } if (options.fields_attributes) { params = Object.assign(params, { fields_attributes: options.fields_attributes }); } } return this.client.patch('/api/v1/accounts/update_credentials', params).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.account(res.data) }); }); } async getAccount(id) { return this.client.get(`/api/v1/accounts/${id}`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.account(res.data) }); }); } async getAccountStatuses(id, options) { let params = {}; if (options) { if (options.limit) { params = Object.assign(params, { limit: options.limit }); } if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.since_id) { params = Object.assign(params, { since_id: options.since_id }); } if (options.min_id) { params = Object.assign(params, { min_id: options.min_id }); } if (options.pinned) { params = Object.assign(params, { pinned: options.pinned }); } if (options.exclude_replies) { params = Object.assign(params, { exclude_replies: options.exclude_replies }); } if (options.exclude_reblogs) { params = Object.assign(params, { exclude_reblogs: options.exclude_reblogs }); } if (options.only_media) { params = Object.assign(params, { only_media: options.only_media }); } if (options.only_public) { params = Object.assign(params, { only_public: options.only_public }); } } return this.client.get(`/api/v1/accounts/${id}/statuses`, params).then(res => { return Object.assign(res, { data: res.data.map(s => GotosocialAPI.Converter.status(s)) }); }); } getAccountFavourites(_id, _options) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async subscribeAccount(id) { const params = { notify: true }; return this.client.post(`/api/v1/accounts/${id}/follow`, params).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.relationship(res.data) }); }); } async unsubscribeAccount(id) { const params = { notify: false }; return this.client.post(`/api/v1/accounts/${id}/follow`, params).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.relationship(res.data) }); }); } async getAccountFollowers(id, options) { let params = {}; if (options) { if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.since_id) { params = Object.assign(params, { since_id: options.since_id }); } if (options.limit) { params = Object.assign(params, { limit: options.limit }); } } return this.urlToAccounts(`/api/v1/accounts/${id}/followers`, params, options?.get_all || false, options?.sleep_ms || 0); } async getAccountFollowing(id, options) { let params = {}; if (options) { if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.since_id) { params = Object.assign(params, { since_id: options.since_id }); } if (options.limit) { params = Object.assign(params, { limit: options.limit }); } } return this.urlToAccounts(`/api/v1/accounts/${id}/following`, params, options?.get_all || false, options?.sleep_ms || 0); } async urlToAccounts(url, params, get_all, sleep_ms) { const res = await this.client.get(url, params); let converted = Object.assign({}, res, { data: res.data.map(a => GotosocialAPI.Converter.account(a)) }); if (get_all && converted.headers.link) { let parsed = parseLinkHeader(converted.headers.link); while (parsed['next']) { const nextRes = await this.client.get(parsed['next'], undefined, undefined, true); converted = Object.assign({}, converted, { data: [...converted.data, ...nextRes.data.map(a => GotosocialAPI.Converter.account(a))] }); if (nextRes.headers.link === undefined) { break; } parsed = parseLinkHeader(nextRes.headers.link); if (sleep_ms) { await new Promise(converted => setTimeout(converted, sleep_ms)); } } } return converted; } async getAccountLists(id) { return this.client.get(`/api/v1/accounts/${id}/lists`).then(res => { return Object.assign(res, { data: res.data.map(l => GotosocialAPI.Converter.list(l)) }); }); } async getIdentityProof(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async followAccount(id, options) { let params = {}; if (options) { if (options.reblog !== undefined) { params = Object.assign(params, { reblog: options.reblog }); } } return this.client.post(`/api/v1/accounts/${id}/follow`, params).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.relationship(res.data) }); }); } async unfollowAccount(id) { return this.client.post(`/api/v1/accounts/${id}/unfollow`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.relationship(res.data) }); }); } async blockAccount(id) { return this.client.post(`/api/v1/accounts/${id}/block`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.relationship(res.data) }); }); } async unblockAccount(id) { return this.client.post(`/api/v1/accounts/${id}/unblock`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.relationship(res.data) }); }); } async muteAccount(_id, _notifications = true) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async unmuteAccount(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async pinAccount(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async unpinAccount(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async setAccountNote(id, note) { let params = {}; if (note) { params = Object.assign(params, { comment: note }); } return this.client.post(`/api/v1/accounts/${id}/note`, params).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.relationship(res.data) }); }); } async getRelationship(id) { return this.client .get('/api/v1/accounts/relationships', { id: [id] }) .then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.relationship(res.data[0]) }); }); } async getRelationships(ids) { return this.client .get('/api/v1/accounts/relationships', { id: ids }) .then(res => { return Object.assign(res, { data: res.data.map(r => GotosocialAPI.Converter.relationship(r)) }); }); } async searchAccount(_q) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async lookupAccount(acct) { return this.client.get(`/api/v1/accounts/lookup?acct=${acct}`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.account(res.data) }); }); } async getBookmarks(options) { let params = {}; if (options) { if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.since_id) { params = Object.assign(params, { since_id: options.since_id }); } if (options.limit) { params = Object.assign(params, { limit: options.limit }); } if (options.min_id) { params = Object.assign(params, { min_id: options.min_id }); } } return this.client.get('/api/v1/bookmarks', params).then(res => { return Object.assign(res, { data: res.data.map(s => GotosocialAPI.Converter.status(s)) }); }); } async getFavourites(options) { let params = {}; if (options) { if (options.min_id) { params = Object.assign(params, { min_id: options.min_id }); } if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.limit) { params = Object.assign(params, { limit: options.limit }); } } return this.client.get('/api/v1/favourites', params).then(res => { return Object.assign(res, { data: res.data.map(s => GotosocialAPI.Converter.status(s)) }); }); } async getMutes(options) { let params = {}; if (options) { if (options.min_id) { params = Object.assign(params, { min_id: options.min_id }); } if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.limit) { params = Object.assign(params, { limit: options.limit }); } } return this.client.get('/api/v1/mutes', params).then(res => { return Object.assign(res, { data: res.data.map(a => GotosocialAPI.Converter.account(a)) }); }); } async getBlocks(options) { let params = {}; if (options) { if (options.min_id) { params = Object.assign(params, { min_id: options.min_id }); } if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.limit) { params = Object.assign(params, { limit: options.limit }); } } return this.client.get('/api/v1/blocks', params).then(res => { return Object.assign(res, { data: res.data.map(a => GotosocialAPI.Converter.account(a)) }); }); } async getDomainBlocks() { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } blockDomain(_domain) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } unblockDomain(_domain) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async getFilters() { return this.client.get('/api/v1/filters').then(res => { return Object.assign(res, { data: res.data.map(f => GotosocialAPI.Converter.filter(f)) }); }); } async getFilter(id) { return this.client.get(`/api/v1/filters/${id}`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.filter(res.data) }); }); } async createFilter(phrase, context, options) { let params = { phrase: phrase, context: context }; if (options) { if (options.irreversible !== undefined) { params = Object.assign(params, { irreversible: options.irreversible }); } if (options.whole_word !== undefined) { params = Object.assign(params, { whole_word: options.whole_word }); } if (options.expires_in) { params = Object.assign(params, { expires_in: options.expires_in }); } } return this.client.post('/api/v1/filters', params).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.filter(res.data) }); }); } async updateFilter(id, phrase, context, options) { let params = { phrase: phrase, context: context }; if (options) { if (options.irreversible !== undefined) { params = Object.assign(params, { irreversible: options.irreversible }); } if (options.whole_word !== undefined) { params = Object.assign(params, { whole_word: options.whole_word }); } if (options.expires_in) { params = Object.assign(params, { expires_in: options.expires_in }); } } return this.client.put(`/api/v1/filters/${id}`, params).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.filter(res.data) }); }); } async deleteFilter(id) { return this.client.del(`/api/v1/filters/${id}`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.filter(res.data) }); }); } async report(account_id, options) { let params = { account_id: account_id }; if (options) { if (options.status_ids) { params = Object.assign(params, { status_ids: options.status_ids }); } if (options.comment) { params = Object.assign(params, { comment: options.comment }); } if (options.forward !== undefined) { params = Object.assign(params, { forward: options.forward }); } if (options.category) { params = Object.assign(params, { category: options.category }); } if (options.rule_ids) { params = Object.assign(params, { rule_ids: options.rule_ids }); } } return this.client.post('/api/v1/reports', params).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.report(res.data) }); }); } async getFollowRequests(limit) { if (limit) { return this.client .get('/api/v1/follow_requests', { limit: limit }) .then(res => { return Object.assign(res, { data: res.data.map(a => GotosocialAPI.Converter.account(a)) }); }); } else { return this.client.get('/api/v1/follow_requests').then(res => { return Object.assign(res, { data: res.data.map(a => GotosocialAPI.Converter.account(a)) }); }); } } async acceptFollowRequest(id) { return this.client.post(`/api/v1/follow_requests/${id}/authorize`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.relationship(res.data) }); }); } async rejectFollowRequest(id) { return this.client.post(`/api/v1/follow_requests/${id}/reject`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.relationship(res.data) }); }); } async getEndorsements() { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async getFeaturedTags() { return new Promise(resolve => { resolve({ data: [], status: 200, statusText: '200', headers: {} }); }); } async createFeaturedTag(_name) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } deleteFeaturedTag(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async getSuggestedTags() { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async getPreferences() { return this.client.get('/api/v1/preferences').then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.preferences(res.data) }); }); } async getFollowedTags() { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async getSuggestions() { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async getTag(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async followTag(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async unfollowTag(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async postStatus(status, options) { let params = { status: status }; let scheduled = false; if (options) { if (options.media_ids) { params = Object.assign(params, { media_ids: options.media_ids }); } if (options.poll) { let pollParam = { options: options.poll.options, expires_in: options.poll.expires_in }; if (options.poll.multiple !== undefined) { pollParam = Object.assign(pollParam, { multiple: options.poll.multiple }); } if (options.poll.hide_totals !== undefined) { pollParam = Object.assign(pollParam, { hide_totals: options.poll.hide_totals }); } params = Object.assign(params, { poll: pollParam }); } if (options.in_reply_to_id) { params = Object.assign(params, { in_reply_to_id: options.in_reply_to_id }); } if (options.sensitive !== undefined) { params = Object.assign(params, { sensitive: options.sensitive }); } if (options.spoiler_text) { params = Object.assign(params, { spoiler_text: options.spoiler_text }); } if (options.visibility) { params = Object.assign(params, { visibility: GotosocialAPI.Converter.encodeVisibility(options.visibility) }); } if (options.scheduled_at && dayjs(options.scheduled_at).diff(dayjs(), 'seconds') > 300) { scheduled = true; params = Object.assign(params, { scheduled_at: options.scheduled_at }); } if (options.language) { params = Object.assign(params, { language: options.language }); } } if (scheduled) { return this.client.post('/api/v1/statuses', params).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.scheduled_status(res.data) }); }); } return this.client.post('/api/v1/statuses', params).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status(res.data) }); }); } async getStatus(id) { return this.client.get(`/api/v1/statuses/${id}`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status(res.data) }); }); } async editStatus(_id, _options) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async deleteStatus(id) { return this.client.del(`/api/v1/statuses/${id}`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status(res.data) }); }); } async getStatusContext(id, options) { let params = {}; if (options) { if (options.limit) { params = Object.assign(params, { limit: options.limit }); } if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.since_id) { params = Object.assign(params, { since_id: options.since_id }); } } return this.client.get(`/api/v1/statuses/${id}/context`, params).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.context(res.data) }); }); } async getStatusSource(id) { return this.client.get(`/api/v1/statuses/${id}/source`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status_source(res.data) }); }); } async getStatusRebloggedBy(id) { return this.client.get(`/api/v1/statuses/${id}/reblogged_by`).then(res => { return Object.assign(res, { data: res.data.map(a => GotosocialAPI.Converter.account(a)) }); }); } async getStatusFavouritedBy(id) { return this.client.get(`/api/v1/statuses/${id}/favourited_by`).then(res => { return Object.assign(res, { data: res.data.map(a => GotosocialAPI.Converter.account(a)) }); }); } async favouriteStatus(id) { return this.client.post(`/api/v1/statuses/${id}/favourite`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status(res.data) }); }); } async unfavouriteStatus(id) { return this.client.post(`/api/v1/statuses/${id}/unfavourite`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status(res.data) }); }); } async reblogStatus(id) { return this.client.post(`/api/v1/statuses/${id}/reblog`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status(res.data) }); }); } async unreblogStatus(id) { return this.client.post(`/api/v1/statuses/${id}/unreblog`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status(res.data) }); }); } async bookmarkStatus(id) { return this.client.post(`/api/v1/statuses/${id}/bookmark`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status(res.data) }); }); } async unbookmarkStatus(id) { return this.client.post(`/api/v1/statuses/${id}/unbookmark`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status(res.data) }); }); } async muteStatus(id) { return this.client.post(`/api/v1/statuses/${id}/mute`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status(res.data) }); }); } async unmuteStatus(id) { return this.client.post(`/api/v1/statuses/${id}/unmute`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status(res.data) }); }); } async pinStatus(id) { return this.client.post(`/api/v1/statuses/${id}/pin`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status(res.data) }); }); } async unpinStatus(id) { return this.client.post(`/api/v1/statuses/${id}/unpin`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.status(res.data) }); }); } async uploadMedia(file, options) { const formData = new FormData(); formData.append('file', file); if (options) { if (options.description) { formData.append('description', options.description); } if (options.focus) { formData.append('focus', options.focus); } } return this.client.postForm('/api/v2/media', formData).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.async_attachment(res.data) }); }); } async getMedia(id) { const res = await this.client.get(`/api/v1/media/${id}`); return Object.assign(res, { data: GotosocialAPI.Converter.attachment(res.data) }); } async updateMedia(id, options) { const formData = new FormData(); if (options) { if (options.file) { formData.append('file', options.file); } if (options.description) { formData.append('description', options.description); } if (options.focus) { formData.append('focus', options.focus); } } return this.client.putForm(`/api/v1/media/${id}`, formData).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.attachment(res.data) }); }); } async getPoll(id) { return this.client.get(`/api/v1/polls/${id}`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.poll(res.data) }); }); } async votePoll(id, choices) { return this.client .post(`/api/v1/polls/${id}/votes`, { choices: choices }) .then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.poll(res.data) }); }); } async getScheduledStatuses() { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async getScheduledStatus(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async scheduleStatus(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } cancelScheduledStatus(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async getPublicTimeline(options) { let params = { local: false }; if (options) { if (options.only_media !== undefined) { params = Object.assign(params, { only_media: options.only_media }); } if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.since_id) { params = Object.assign(params, { since_id: options.since_id }); } if (options.min_id) { params = Object.assign(params, { min_id: options.min_id }); } if (options.limit) { params = Object.assign(params, { limit: options.limit }); } } return this.client.get('/api/v1/timelines/public', params).then(res => { return Object.assign(res, { data: res.data.map(s => GotosocialAPI.Converter.status(s)) }); }); } async getLocalTimeline(options) { let params = { local: true }; if (options) { if (options.only_media !== undefined) { params = Object.assign(params, { only_media: options.only_media }); } if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.since_id) { params = Object.assign(params, { since_id: options.since_id }); } if (options.min_id) { params = Object.assign(params, { min_id: options.min_id }); } if (options.limit) { params = Object.assign(params, { limit: options.limit }); } } return this.client.get('/api/v1/timelines/public', params).then(res => { return Object.assign(res, { data: res.data.map(s => GotosocialAPI.Converter.status(s)) }); }); } async getTagTimeline(hashtag, options) { let params = {}; if (options) { if (options.local !== undefined) { params = Object.assign(params, { local: options.local }); } if (options.only_media !== undefined) { params = Object.assign(params, { only_media: options.only_media }); } if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.since_id) { params = Object.assign(params, { since_id: options.since_id }); } if (options.min_id) { params = Object.assign(params, { min_id: options.min_id }); } if (options.limit) { params = Object.assign(params, { limit: options.limit }); } } return this.client.get(`/api/v1/timelines/tag/${hashtag}`, params).then(res => { return Object.assign(res, { data: res.data.map(s => GotosocialAPI.Converter.status(s)) }); }); } async getHomeTimeline(options) { let params = {}; if (options) { if (options.local !== undefined) { params = Object.assign(params, { local: options.local }); } if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.since_id) { params = Object.assign(params, { since_id: options.since_id }); } if (options.min_id) { params = Object.assign(params, { min_id: options.min_id }); } if (options.limit) { params = Object.assign(params, { limit: options.limit }); } } return this.client.get('/api/v1/timelines/home', params).then(res => { return Object.assign(res, { data: res.data.map(s => GotosocialAPI.Converter.status(s)) }); }); } async getListTimeline(list_id, options) { let params = {}; if (options) { if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.since_id) { params = Object.assign(params, { since_id: options.since_id }); } if (options.min_id) { params = Object.assign(params, { min_id: options.min_id }); } if (options.limit) { params = Object.assign(params, { limit: options.limit }); } } return this.client.get(`/api/v1/timelines/list/${list_id}`, params).then(res => { return Object.assign(res, { data: res.data.map(s => GotosocialAPI.Converter.status(s)) }); }); } async getConversationTimeline() { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } deleteConversation(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async readConversation(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } async getLists() { return this.client.get('/api/v1/lists').then(res => { return Object.assign(res, { data: res.data.map(l => GotosocialAPI.Converter.list(l)) }); }); } async getList(id) { return this.client.get(`/api/v1/lists/${id}`).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.list(res.data) }); }); } async createList(title) { return this.client .post('/api/v1/lists', { title: title }) .then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.list(res.data) }); }); } async updateList(id, title) { return this.client .put(`/api/v1/lists/${id}`, { title: title }) .then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.list(res.data) }); }); } deleteList(id) { return this.client.del(`/api/v1/lists/${id}`); } async getAccountsInList(id, options) { let params = {}; if (options) { if (options.limit) { params = Object.assign(params, { limit: options.limit }); } if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.since_id) { params = Object.assign(params, { since_id: options.since_id }); } } return this.client.get(`/api/v1/lists/${id}/accounts`, params).then(res => { return Object.assign(res, { data: res.data.map(a => GotosocialAPI.Converter.account(a)) }); }); } addAccountsToList(id, account_ids) { return this.client.post(`/api/v1/lists/${id}/accounts`, { account_ids: account_ids }); } deleteAccountsFromList(id, account_ids) { return this.client.del(`/api/v1/lists/${id}/accounts`, { account_ids: account_ids }); } async getMarkers(timeline) { return this.client .get('/api/v1/markers', { timeline: timeline }) .then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.marker(res.data) }); }); } async saveMarkers(options) { let params = {}; if (options) { if (options.home) { params = Object.assign(params, { home: options.home }); } if (options.notifications) { params = Object.assign(params, { notifications: options.notifications }); } } return this.client.post('/api/v1/markers', params).then(res => { return Object.assign(res, { data: GotosocialAPI.Converter.marker(res.data) }); }); } async getNotifications(options) { let params = {}; if (options) { if (options.limit) { params = Object.assign(params, { limit: options.limit }); } if (options.max_id) { params = Object.assign(params, { max_id: options.max_id }); } if (options.since_id) { params = Object.assign(params, { since_id: options.since_id }); } if (options.min_id) { params = Object.assign(params, { min_id: options.min_id }); } if (options.exclude_types) { params = Object.assign(params, { exclude_types: options.exclude_types.map(e => GotosocialAPI.Converter.encodeNotificationType(e)) }); } if (options.account_id) { params = Object.assign(params, { account_id: options.account_id }); } } return this.client.get('/api/v1/notifications', params).then(res => { return Object.assign(res, { data: res.data.flatMap(n => { const notify = GotosocialAPI.Converter.notification(n); if (notify instanceof UnknownNotificationTypeError) return []; return notify; }) }); }); } async getNotification(id) { const res = await this.client.get(`/api/v1/notifications/${id}`); const notify = GotosocialAPI.Converter.notification(res.data); if (notify instanceof UnknownNotificationTypeError) { throw new UnknownNotificationTypeError(); } return { ...res, data: notify }; } dismissNotifications() { return this.client.post('/api/v1/notifications/clear'); } dismissNotification(_id) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); }); } readNotifications(_options) { return new Promise((_, reject) => { const err = new NotImplementedError('Gotosocial does not support this method'); reject(err); });