/* * 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): void { fastify.get('/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('/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('/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('/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); }); } }