barkey/packages/backend/src/server/api/mastodon/endpoints/notifications.ts

84 lines
3.1 KiB
TypeScript

/*
* SPDX-FileCopyrightText: marie and other Sharkey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Injectable } from '@nestjs/common';
import { parseTimelineArgs, TimelineArgs } from '@/server/api/mastodon/argsUtils.js';
import { MastodonConverters } from '@/server/api/mastodon/MastodonConverters.js';
import { attachMinMaxPagination } from '@/server/api/mastodon/pagination.js';
import { MastodonClientService } from '../MastodonClientService.js';
import type { FastifyInstance } from 'fastify';
import type multer from 'fastify-multer';
interface ApiNotifyMastodonRoute {
Params: {
id?: string,
},
Querystring: TimelineArgs,
}
@Injectable()
export class ApiNotificationsMastodon {
constructor(
private readonly mastoConverters: MastodonConverters,
private readonly clientService: MastodonClientService,
) {}
public register(fastify: FastifyInstance, upload: ReturnType<typeof multer>): void {
fastify.get<ApiNotifyMastodonRoute>('/v1/notifications', async (request, reply) => {
const { client, me } = await this.clientService.getAuthClient(request);
const data = await client.getNotifications(parseTimelineArgs(request.query));
const notifications = await Promise.all(data.data.map(n => this.mastoConverters.convertNotification(n, me)));
const response: MastodonEntity.Notification[] = [];
for (const notification of notifications) {
// Notifications for inaccessible notes will be null and should be ignored
if (!notification) continue;
response.push(notification);
if (notification.type === 'reaction') {
response.push({
...notification,
type: 'favourite',
});
}
}
attachMinMaxPagination(request, reply, response);
reply.send(response);
});
fastify.get<ApiNotifyMastodonRoute & { Params: { id?: string } }>('/v1/notification/:id', async (_request, reply) => {
if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
const { client, me } = await this.clientService.getAuthClient(_request);
const data = await client.getNotification(_request.params.id);
const response = await this.mastoConverters.convertNotification(data.data, me);
// Notifications for inaccessible notes will be null and should be ignored
if (!response) {
return reply.code(404).send({
error: 'NOT_FOUND',
});
}
reply.send(response);
});
fastify.post<ApiNotifyMastodonRoute & { Params: { id?: string } }>('/v1/notification/:id/dismiss', { preHandler: upload.single('none') }, async (_request, reply) => {
if (!_request.params.id) return reply.code(400).send({ error: 'BAD_REQUEST', error_description: 'Missing required parameter "id"' });
const client = this.clientService.getClient(_request);
const data = await client.dismissNotification(_request.params.id);
reply.send(data.data);
});
fastify.post<ApiNotifyMastodonRoute>('/v1/notifications/clear', { preHandler: upload.single('none') }, async (_request, reply) => {
const client = this.clientService.getClient(_request);
const data = await client.dismissNotifications();
reply.send(data.data);
});
}
}