cleanup Mastodon API (resolves #804 and #865, partially resolves #492)

* Fix TS errors and warnings
* Fix ESLint errors and warnings
* Fix property typos in various places
* Fix property data conversion
* Add missing entity properties
* Normalize logging and reduce spam
* Check for missing request parameters
* Allow mastodon API to work with local debugging
* Safer error handling
* Fix quote-post detection
This commit is contained in:
Hazelnoot 2025-01-31 02:46:38 -05:00
parent 2c2fb8a692
commit 16f483d273
13 changed files with 1275 additions and 1147 deletions

View file

@ -3,73 +3,53 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { parseTimelineArgs, TimelineArgs } from '@/server/api/mastodon/timelineArgs.js';
import { convertNotification } from '../converters.js';
import type { MegalodonInterface, Entity } from 'megalodon';
import type { MegalodonInterface } from 'megalodon';
import type { FastifyRequest } from 'fastify';
function toLimitToInt(q: any) {
if (q.limit) if (typeof q.limit === 'string') q.limit = parseInt(q.limit, 10);
return q;
export interface ApiNotifyMastodonRoute {
Params: {
id?: string,
},
Querystring: TimelineArgs,
}
export class ApiNotifyMastodon {
private request: FastifyRequest;
private client: MegalodonInterface;
constructor(request: FastifyRequest, client: MegalodonInterface) {
this.request = request;
this.client = client;
}
constructor(
private readonly request: FastifyRequest<ApiNotifyMastodonRoute>,
private readonly client: MegalodonInterface,
) {}
public async getNotifications() {
try {
const data = await this.client.getNotifications( toLimitToInt(this.request.query) );
const notifs = data.data;
const processed = notifs.map((n: Entity.Notification) => {
const convertedn = convertNotification(n);
if (convertedn.type !== 'follow' && convertedn.type !== 'follow_request') {
if (convertedn.type === 'reaction') convertedn.type = 'favourite';
return convertedn;
} else {
return convertedn;
}
});
return processed;
} catch (e: any) {
console.error(e);
return e.response.data;
}
const data = await this.client.getNotifications(parseTimelineArgs(this.request.query));
return data.data.map(n => {
const converted = convertNotification(n);
if (converted.type === 'reaction') {
converted.type = 'favourite';
}
return converted;
});
}
public async getNotification() {
try {
const data = await this.client.getNotification( (this.request.params as any).id );
const notif = convertNotification(data.data);
if (notif.type !== 'follow' && notif.type !== 'follow_request' && notif.type === 'reaction') notif.type = 'favourite';
return notif;
} catch (e: any) {
console.error(e);
return e.response.data;
if (!this.request.params.id) throw new Error('Missing required parameter "id"');
const data = await this.client.getNotification(this.request.params.id);
const converted = convertNotification(data.data);
if (converted.type === 'reaction') {
converted.type = 'favourite';
}
return converted;
}
public async rmNotification() {
try {
const data = await this.client.dismissNotification( (this.request.params as any).id );
return data.data;
} catch (e: any) {
console.error(e);
return e.response.data;
}
if (!this.request.params.id) throw new Error('Missing required parameter "id"');
const data = await this.client.dismissNotification(this.request.params.id);
return data.data;
}
public async rmNotifications() {
try {
const data = await this.client.dismissNotifications();
return data.data;
} catch (e: any) {
console.error(e);
return e.response.data;
}
const data = await this.client.dismissNotifications();
return data.data;
}
}