megalodon
Version:
Fediverse API client for node.js and browser
1,469 lines (1,468 loc) • 58 kB
JavaScript
import { OAuth2Client } from '@badgateway/oauth2-client';
import FormData from 'form-data';
import { parseLinkHeader } from './parse_link_header.js';
import FriendicaAPI from './friendica/api_client.js';
import { NotImplementedError } from './megalodon.js';
import { NO_REDIRECT, DEFAULT_SCOPE, DEFAULT_UA } from './default.js';
import * as FriendicaOAuth from './friendica/oauth.js';
import { UnknownNotificationTypeError } from './notification.js';
export default class Friendica {
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 FriendicaAPI.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) => FriendicaOAuth.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 this.client.get('/api/v1/apps/verify_credentials');
}
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) => FriendicaOAuth.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) => FriendicaOAuth.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) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async verifyAccountCredentials() {
return this.client.get('/api/v1/accounts/verify_credentials').then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.account(res.data)
});
});
}
async updateCredentials(_options) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async getAccount(id) {
return this.client.get(`/api/v1/accounts/${id}`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.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
});
}
}
return this.client.get(`/api/v1/accounts/${id}/statuses`, params).then(res => {
return Object.assign(res, {
data: res.data.map(s => FriendicaAPI.Converter.status(s))
});
});
}
async subscribeAccount(id) {
const params = {
notify: true
};
return this.client.post(`/api/v1/accounts/${id}/follow`, params).then(res => {
return Object.assign(res, {
data: FriendicaAPI.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: FriendicaAPI.Converter.relationship(res.data)
});
});
}
getAccountFavourites(_id, _options) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
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 => FriendicaAPI.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 => FriendicaAPI.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 => FriendicaAPI.Converter.list(l))
});
});
}
async getIdentityProof(id) {
return this.client.get(`/api/v1/accounts/${id}/identity_proofs`).then(res => {
return Object.assign(res, {
data: res.data.map(i => FriendicaAPI.Converter.identity_proof(i))
});
});
}
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: FriendicaAPI.Converter.relationship(res.data)
});
});
}
async unfollowAccount(id) {
return this.client.post(`/api/v1/accounts/${id}/unfollow`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.relationship(res.data)
});
});
}
async blockAccount(id) {
return this.client.post(`/api/v1/accounts/${id}/block`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.relationship(res.data)
});
});
}
async unblockAccount(id) {
return this.client.post(`/api/v1/accounts/${id}/unblock`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.relationship(res.data)
});
});
}
async muteAccount(id, notifications = true) {
return this.client
.post(`/api/v1/accounts/${id}/mute`, {
notifications: notifications
})
.then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.relationship(res.data)
});
});
}
async unmuteAccount(id) {
return this.client.post(`/api/v1/accounts/${id}/unmute`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.relationship(res.data)
});
});
}
async pinAccount(_id) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async unpinAccount(_id) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async setAccountNote(_id) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async getRelationship(id) {
return this.client
.get('/api/v1/accounts/relationships', {
id: [id]
})
.then(res => {
return Object.assign(res, {
data: FriendicaAPI.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 => FriendicaAPI.Converter.relationship(r))
});
});
}
async searchAccount(q, options) {
let params = { q: q };
if (options) {
if (options.following !== undefined && options.following !== null) {
params = Object.assign(params, {
following: options.following
});
}
if (options.resolve !== undefined && options.resolve !== null) {
params = Object.assign(params, {
resolve: options.resolve
});
}
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.client.get('/api/v1/accounts/search', params).then(res => {
return Object.assign(res, {
data: res.data.map(a => FriendicaAPI.Converter.account(a))
});
});
}
async lookupAccount(_acct) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
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 => FriendicaAPI.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 => FriendicaAPI.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 => FriendicaAPI.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 => FriendicaAPI.Converter.account(a))
});
});
}
async getDomainBlocks(_options) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
blockDomain(_domain) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
unblockDomain(_domain) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica 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 => FriendicaAPI.Converter.filter(f))
});
});
}
async getFilter(_id) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async createFilter(_phrase, _context, _options) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async updateFilter(_id, _phrase, _context, _options) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async deleteFilter(_id) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async report(_account_id, _options) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
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 => FriendicaAPI.Converter.follow_request(a))
});
});
}
else {
return this.client.get('/api/v1/follow_requests').then(res => {
return Object.assign(res, {
data: res.data.map(a => FriendicaAPI.Converter.follow_request(a))
});
});
}
}
async acceptFollowRequest(id) {
return this.client.post(`/api/v1/follow_requests/${id}/authorize`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.relationship(res.data)
});
});
}
async rejectFollowRequest(id) {
return this.client.post(`/api/v1/follow_requests/${id}/reject`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.relationship(res.data)
});
});
}
async getEndorsements(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/endorsements', params).then(res => {
return Object.assign(res, {
data: res.data.map(a => FriendicaAPI.Converter.account(a))
});
});
}
async getFeaturedTags() {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async createFeaturedTag(_name) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
deleteFeaturedTag(_id) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async getSuggestedTags() {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async getPreferences() {
return this.client.get('/api/v1/preferences').then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.preferences(res.data)
});
});
}
async getFollowedTags() {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async getSuggestions(limit) {
if (limit) {
return this.client
.get('/api/v1/suggestions', {
limit: limit
})
.then(res => {
return Object.assign(res, {
data: res.data.map(a => FriendicaAPI.Converter.account(a))
});
});
}
else {
return this.client.get('/api/v1/suggestions').then(res => {
return Object.assign(res, {
data: res.data.map(a => FriendicaAPI.Converter.account(a))
});
});
}
}
async getTag(id) {
return this.client.get(`/api/v1/tags/${id}`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.tag(res.data)
});
});
}
async followTag(id) {
return this.client.post(`/api/v1/tags/${id}/follow`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.tag(res.data)
});
});
}
async unfollowTag(id) {
return this.client.post(`/api/v1/tags/${id}/unfollow`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.tag(res.data)
});
});
}
async postStatus(status, options) {
let params = {
status: status
};
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: FriendicaAPI.Converter.encodeVisibility(options.visibility)
});
}
if (options.scheduled_at) {
params = Object.assign(params, {
scheduled_at: options.scheduled_at
});
}
if (options.language) {
params = Object.assign(params, {
language: options.language
});
}
if (options.quote_id) {
params = Object.assign(params, {
quote_id: options.quote_id
});
}
}
if (options.scheduled_at) {
return this.client.post('/api/v1/statuses', params).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.scheduled_status(res.data)
});
});
}
return this.client.post('/api/v1/statuses', params).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.status(res.data)
});
});
}
async getStatus(id) {
return this.client.get(`/api/v1/statuses/${id}`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.status(res.data)
});
});
}
async editStatus(id, options) {
let params = {};
if (options.status) {
params = Object.assign(params, {
status: options.status
});
}
if (options.spoiler_text) {
params = Object.assign(params, {
spoiler_text: options.spoiler_text
});
}
if (options.sensitive) {
params = Object.assign(params, {
sensitive: options.sensitive
});
}
if (options.media_ids) {
params = Object.assign(params, {
media_ids: options.media_ids
});
}
if (options.poll) {
let pollParam = {};
if (options.poll.options !== undefined) {
pollParam = Object.assign(pollParam, {
options: options.poll.options
});
}
if (options.poll.expires_in !== undefined) {
pollParam = Object.assign(pollParam, {
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
});
}
return this.client.put(`/api/v1/statuses/${id}`, params).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.status(res.data)
});
});
}
async deleteStatus(id) {
return this.client.del(`/api/v1/statuses/${id}`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.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: FriendicaAPI.Converter.context(res.data)
});
});
}
async getStatusSource(id) {
return this.client.get(`/api/v1/statuses/${id}/source`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.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 => FriendicaAPI.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 => FriendicaAPI.Converter.account(a))
});
});
}
async favouriteStatus(id) {
return this.client.post(`/api/v1/statuses/${id}/favourite`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.status(res.data)
});
});
}
async unfavouriteStatus(id) {
return this.client.post(`/api/v1/statuses/${id}/unfavourite`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.status(res.data)
});
});
}
async reblogStatus(id) {
return this.client.post(`/api/v1/statuses/${id}/reblog`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.status(res.data)
});
});
}
async unreblogStatus(id) {
return this.client.post(`/api/v1/statuses/${id}/unreblog`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.status(res.data)
});
});
}
async bookmarkStatus(id) {
return this.client.post(`/api/v1/statuses/${id}/bookmark`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.status(res.data)
});
});
}
async unbookmarkStatus(id) {
return this.client.post(`/api/v1/statuses/${id}/unbookmark`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.status(res.data)
});
});
}
async muteStatus(id) {
return this.client.post(`/api/v1/statuses/${id}/mute`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.status(res.data)
});
});
}
async unmuteStatus(id) {
return this.client.post(`/api/v1/statuses/${id}/unmute`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.status(res.data)
});
});
}
async pinStatus(id) {
return this.client.post(`/api/v1/statuses/${id}/pin`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.status(res.data)
});
});
}
async unpinStatus(id) {
return this.client.post(`/api/v1/statuses/${id}/unpin`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.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: FriendicaAPI.Converter.async_attachment(res.data)
});
});
}
async getMedia(id) {
const res = await this.client.get(`/api/v1/media/${id}`);
return Object.assign(res, {
data: FriendicaAPI.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: FriendicaAPI.Converter.attachment(res.data)
});
});
}
async getPoll(id) {
return this.client.get(`/api/v1/polls/${id}`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.poll(res.data)
});
});
}
async votePoll(_id, _choices) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async getScheduledStatuses(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
});
}
}
return this.client.get('/api/v1/scheduled_statuses', params).then(res => {
return Object.assign(res, {
data: res.data.map(s => FriendicaAPI.Converter.scheduled_status(s))
});
});
}
async getScheduledStatus(id) {
return this.client.get(`/api/v1/scheduled_statuses/${id}`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.scheduled_status(res.data)
});
});
}
async scheduleStatus(_id, _scheduled_at) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
cancelScheduledStatus(id) {
return this.client.del(`/api/v1/scheduled_statuses/${id}`);
}
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 => FriendicaAPI.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 => FriendicaAPI.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 => FriendicaAPI.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 => FriendicaAPI.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 => FriendicaAPI.Converter.status(s))
});
});
}
async getConversationTimeline(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/conversations', params).then(res => {
return Object.assign(res, {
data: res.data.map(c => FriendicaAPI.Converter.conversation(c))
});
});
}
deleteConversation(id) {
return this.client.del(`/api/v1/conversations/${id}`);
}
async readConversation(id) {
return this.client.post(`/api/v1/conversations/${id}/read`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.conversation(res.data)
});
});
}
async getLists() {
return this.client.get('/api/v1/lists').then(res => {
return Object.assign(res, {
data: res.data.map(l => FriendicaAPI.Converter.list(l))
});
});
}
async getList(id) {
return this.client.get(`/api/v1/lists/${id}`).then(res => {
return Object.assign(res, {
data: FriendicaAPI.Converter.list(res.data)
});
});
}
async createList(title) {
return this.client
.post('/api/v1/lists', {
title: title
})
.then(res => {
return Object.assign(res, {
data: FriendicaAPI.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: FriendicaAPI.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 => FriendicaAPI.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 new Promise(resolve => {
const res = {
data: {},
status: 200,
statusText: '200',
headers: {}
};
resolve(res);
});
}
async saveMarkers(_options) {
return new Promise(resolve => {
const res = {
data: {},
status: 200,
statusText: '200',
headers: {}
};
resolve(res);
});
}
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 => FriendicaAPI.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 = FriendicaAPI.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 = FriendicaAPI.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 this.client.post(`/api/v1/notifications/${id}/dismiss`);
}
readNotifications(_options) {
return new Promise((_, reject) => {
const err = new NotImplementedError('Friendica does not support this method');
reject(err);
});
}
async subscribePushNotification(subscription, data) {
let params = {
subscription
};
if (data) {
params = Object.assign(params, {
data
});