From 7da191396469642de14655c30eba86926882e98c Mon Sep 17 00:00:00 2001 From: syuilo Date: Tue, 3 Apr 2018 00:59:38 +0900 Subject: [PATCH] [wip] Implement like activity --- src/models/post-reaction.ts | 2 +- src/remote/activitypub/act/like.ts | 48 +++++++++++++++++++++++++ src/remote/activitypub/renderer/note.ts | 2 +- 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/remote/activitypub/act/like.ts diff --git a/src/models/post-reaction.ts b/src/models/post-reaction.ts index 3fc33411f..81be95b8d 100644 --- a/src/models/post-reaction.ts +++ b/src/models/post-reaction.ts @@ -5,12 +5,12 @@ import Reaction from './post-reaction'; import { pack as packUser } from './user'; const PostReaction = db.get('postReactions'); +PostReaction.createIndex(['userId', 'postId'], { unique: true }); export default PostReaction; export interface IPostReaction { _id: mongo.ObjectID; createdAt: Date; - deletedAt: Date; postId: mongo.ObjectID; userId: mongo.ObjectID; reaction: string; diff --git a/src/remote/activitypub/act/like.ts b/src/remote/activitypub/act/like.ts new file mode 100644 index 000000000..d2ddba89a --- /dev/null +++ b/src/remote/activitypub/act/like.ts @@ -0,0 +1,48 @@ +import { MongoError } from 'mongodb'; +import Post from '../../../models/post'; +import Reaction from '../../../models/post-reaction'; +import config from '../../../config'; +import queue from '../../../queue'; + +export default async (actor, activity) => { + const prefix = config.url + '/posts'; + const id = activity.object.id || activity.object; + let reaction; + + if (!id.startsWith(prefix)) { + return null; + } + + const postId = id.slice(prefix.length); + + const post = await Post.findOne({ _id: postId }); + if (post === null) { + throw new Error(); + } + + try { + reaction = await Reaction.insert({ + createdAt: new Date(), + postId, + userId: actor._id, + reaction: 'pudding' + }); + } catch (exception) { + // duplicate key error + if (exception instanceof MongoError && exception.code === 11000) { + return null; + } + + throw exception; + } + + await new Promise((resolve, reject) => { + queue.create('http', { type: 'like', reaction: reaction._id }).save(error => { + if (error) { + reject(error); + } else { + resolve(null); + } + }); + }); +}; diff --git a/src/remote/activitypub/renderer/note.ts b/src/remote/activitypub/renderer/note.ts index 43531b121..36f8578ec 100644 --- a/src/remote/activitypub/renderer/note.ts +++ b/src/remote/activitypub/renderer/note.ts @@ -30,7 +30,7 @@ export default async (user, post) => { const attributedTo = `${config.url}/@${user.username}`; return { - id: `${attributedTo}/${post._id}`, + id: `${config.url}/posts/${post._id}}`, type: 'Note', attributedTo, content: post.textHtml,