diff --git a/src/remote/activitypub/renderer/question.ts b/src/remote/activitypub/renderer/question.ts new file mode 100644 index 0000000000..9df4daca3b --- /dev/null +++ b/src/remote/activitypub/renderer/question.ts @@ -0,0 +1,20 @@ +import config from '../../../config'; +import { ILocalUser } from '../../../models/user'; +import { INote } from '../../../models/note'; + +export default async function renderQuestion(user: ILocalUser, note: INote) { + const question = { + type: 'Question', + id: `${config.url}/questions/${note._id}`, + actor: `${config.url}/users/${user._id}`, + content: note.text != null ? note.text : '', + oneOf: note.poll.choices.map(c => { + return { + name: c.text, + _misskey_votes: c.votes, + }; + }), + }; + + return question; +} diff --git a/src/server/activitypub.ts b/src/server/activitypub.ts index 9adc3dd943..ac8d3d4e26 100644 --- a/src/server/activitypub.ts +++ b/src/server/activitypub.ts @@ -16,6 +16,7 @@ import Outbox, { packActivity } from './activitypub/outbox'; import Followers from './activitypub/followers'; import Following from './activitypub/following'; import Featured from './activitypub/featured'; +import renderQuestion from '../remote/activitypub/renderer/question'; // Init router const router = new Router(); @@ -110,6 +111,36 @@ router.get('/notes/:note/activity', async ctx => { setResponseType(ctx); }); +// question +router.get('/questions/:question', async (ctx, next) => { + if (!ObjectID.isValid(ctx.params.question)) { + ctx.status = 404; + return; + } + + const poll = await Note.findOne({ + _id: new ObjectID(ctx.params.question), + visibility: { $in: ['public', 'home'] }, + localOnly: { $ne: true }, + poll: { + $exists: true, + $ne: null + }, + }); + + if (poll === null) { + ctx.status = 404; + return; + } + + const user = await User.findOne({ + _id: poll.userId + }); + + ctx.body = pack(await renderQuestion(user as ILocalUser, poll)); + setResponseType(ctx); +}); + // outbox router.get('/users/:user/outbox', Outbox);