ActivityPub Outboxの修正とactivity idのURLを実装 (#2662)

* Fix Outbox structure

* Implement activity endpoint

* Use in instead of or

* Use in, addition
This commit is contained in:
MeiMei 2018-09-08 05:24:55 +09:00 committed by syuilo
parent 2824d8a5b6
commit ef62497777
3 changed files with 37 additions and 14 deletions

View file

@ -5,7 +5,7 @@ export default (object: any, note: INote) => {
const attributedTo = `${config.url}/users/${note.userId}`; const attributedTo = `${config.url}/users/${note.userId}`;
return { return {
id: `${config.url}/notes/${note._id}`, id: `${config.url}/notes/${note._id}/activity`,
actor: `${config.url}/users/${note.userId}`, actor: `${config.url}/users/${note.userId}`,
type: 'Announce', type: 'Announce',
published: note.createdAt.toISOString(), published: note.createdAt.toISOString(),

View file

@ -10,7 +10,7 @@ import User, { isLocalUser, ILocalUser, IUser } from '../models/user';
import renderNote from '../remote/activitypub/renderer/note'; import renderNote from '../remote/activitypub/renderer/note';
import renderKey from '../remote/activitypub/renderer/key'; import renderKey from '../remote/activitypub/renderer/key';
import renderPerson from '../remote/activitypub/renderer/person'; import renderPerson from '../remote/activitypub/renderer/person';
import Outbox from './activitypub/outbox'; import Outbox, { packActivity } from './activitypub/outbox';
import Followers from './activitypub/followers'; import Followers from './activitypub/followers';
import Following from './activitypub/following'; import Following from './activitypub/following';
@ -77,6 +77,22 @@ router.get('/notes/:note', async (ctx, next) => {
setResponseType(ctx); setResponseType(ctx);
}); });
// note activity
router.get('/notes/:note/activity', async ctx => {
const note = await Note.findOne({
_id: new mongo.ObjectID(ctx.params.note),
visibility: { $in: ['public', 'home'] }
});
if (note === null) {
ctx.status = 404;
return;
}
ctx.body = pack(await packActivity(note));
setResponseType(ctx);
});
// outbox // outbox
router.get('/users/:user/outbox', Outbox); router.get('/users/:user/outbox', Outbox);

View file

@ -8,8 +8,10 @@ import renderOrderedCollection from '../../remote/activitypub/renderer/ordered-c
import renderOrderedCollectionPage from '../../remote/activitypub/renderer/ordered-collection-page'; import renderOrderedCollectionPage from '../../remote/activitypub/renderer/ordered-collection-page';
import { setResponseType } from '../activitypub'; import { setResponseType } from '../activitypub';
import Note from '../../models/note'; import Note, { INote } from '../../models/note';
import renderNote from '../../remote/activitypub/renderer/note'; import renderNote from '../../remote/activitypub/renderer/note';
import renderCreate from '../../remote/activitypub/renderer/create';
import renderAnnounce from '../../remote/activitypub/renderer/announce';
import { countIf } from '../../prelude/array'; import { countIf } from '../../prelude/array';
export default async (ctx: Router.IRouterContext) => { export default async (ctx: Router.IRouterContext) => {
@ -53,15 +55,7 @@ export default async (ctx: Router.IRouterContext) => {
const query = { const query = {
userId: user._id, userId: user._id,
$and: [{ visibility: { $in: ['public', 'home'] }
$or: [ { visibility: 'public' }, { visibility: 'home' } ]
}, { // exclude renote, but include quote
$or: [{
text: { $ne: null }
}, {
fileIds: { $ne: [] }
}]
}]
} as any; } as any;
if (sinceId) { if (sinceId) {
@ -85,10 +79,10 @@ export default async (ctx: Router.IRouterContext) => {
if (sinceId) notes.reverse(); if (sinceId) notes.reverse();
const renderedNotes = await Promise.all(notes.map(note => renderNote(note, false))); const activities = await Promise.all(notes.map(note => packActivity(note)));
const rendered = renderOrderedCollectionPage( const rendered = renderOrderedCollectionPage(
`${partOf}?page=true${sinceId ? `&since_id=${sinceId}` : ''}${untilId ? `&until_id=${untilId}` : ''}`, `${partOf}?page=true${sinceId ? `&since_id=${sinceId}` : ''}${untilId ? `&until_id=${untilId}` : ''}`,
user.notesCount, renderedNotes, partOf, user.notesCount, activities, partOf,
notes.length > 0 ? `${partOf}?page=true&since_id=${notes[0]._id}` : null, notes.length > 0 ? `${partOf}?page=true&since_id=${notes[0]._id}` : null,
notes.length > 0 ? `${partOf}?page=true&until_id=${notes[notes.length - 1]._id}` : null notes.length > 0 ? `${partOf}?page=true&until_id=${notes[notes.length - 1]._id}` : null
); );
@ -105,3 +99,16 @@ export default async (ctx: Router.IRouterContext) => {
setResponseType(ctx); setResponseType(ctx);
} }
}; };
/**
* Pack Create<Note> or Announce Activity
* @param note Note
*/
export async function packActivity(note: INote): Promise<object> {
if (note.renoteId && note.text == null) {
const renote = await Note.findOne(note.renoteId);
return renderAnnounce(renote.uri ? renote.uri : `${config.url}/notes/${renote._id}`, note);
}
return renderCreate(await renderNote(note, false), note);
}