summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMeiMei <30769358+mei23@users.noreply.github.com>2020-02-04 08:26:00 +0900
committerGitHub <noreply@github.com>2020-02-04 08:26:00 +0900
commitb7a4f286b02c8ebb376779569e5564f52496913e (patch)
treee113d71516c362eabd7034b3503769d343ec3249 /src
parentAdd Unicode 12.1 Emojis (#5825) (diff)
downloadsharkey-b7a4f286b02c8ebb376779569e5564f52496913e.tar.gz
sharkey-b7a4f286b02c8ebb376779569e5564f52496913e.tar.bz2
sharkey-b7a4f286b02c8ebb376779569e5564f52496913e.zip
リモート投稿にリモートでされたリアクションが表示されるように (#5817)
* 第3インスタンスへのLikeも受け入れるように * リアクション済みだったらエラーにせずに置き換えるように * Likeを第3インスタンスにdeliverするように * fix * fix * 同じリアクションがすでにされていたら何もしない * リモートから自身の投稿へリアクションした場合にエラーにならないように
Diffstat (limited to 'src')
-rw-r--r--src/remote/activitypub/kernel/like.ts21
-rw-r--r--src/remote/activitypub/kernel/undo/like.ts18
-rw-r--r--src/services/note/reaction/create.ts42
-rw-r--r--src/services/note/reaction/delete.ts17
4 files changed, 50 insertions, 48 deletions
diff --git a/src/remote/activitypub/kernel/like.ts b/src/remote/activitypub/kernel/like.ts
index fa8983b38d..b25f80aedc 100644
--- a/src/remote/activitypub/kernel/like.ts
+++ b/src/remote/activitypub/kernel/like.ts
@@ -1,23 +1,16 @@
import { IRemoteUser } from '../../../models/entities/user';
-import { ILike } from '../type';
+import { ILike, getApId } from '../type';
import create from '../../../services/note/reaction/create';
-import { Notes } from '../../../models';
-import { apLogger } from '../logger';
+import { fetchNote } from '../models/note';
export default async (actor: IRemoteUser, activity: ILike) => {
- const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
- if (id == null) throw new Error('missing id');
+ const targetUri = getApId(activity.object);
- // Transform:
- // https://misskey.ex/notes/xxxx to
- // xxxx
- const noteId = id.split('/').pop();
+ const note = await fetchNote(targetUri);
+ if (!note) return `skip: target note not found ${targetUri}`;
- const note = await Notes.findOne(noteId);
- if (note == null) {
- apLogger.warn(`Like activity recivied, but no such note: ${id}`, { id });
- return;
- }
+ if (actor.id === note.userId) return `skip: cannot react to my note`;
await create(actor, note, activity._misskey_reaction || activity.content || activity.name);
+ return `ok`;
};
diff --git a/src/remote/activitypub/kernel/undo/like.ts b/src/remote/activitypub/kernel/undo/like.ts
index 2678828a9a..bd6930c66b 100644
--- a/src/remote/activitypub/kernel/undo/like.ts
+++ b/src/remote/activitypub/kernel/undo/like.ts
@@ -1,21 +1,17 @@
import { IRemoteUser } from '../../../../models/entities/user';
-import { ILike } from '../../type';
+import { ILike, getApId } from '../../type';
import deleteReaction from '../../../../services/note/reaction/delete';
-import { Notes } from '../../../../models';
+import { fetchNote } from '../../models/note';
/**
* Process Undo.Like activity
*/
-export default async (actor: IRemoteUser, activity: ILike): Promise<void> => {
- const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
- if (id == null) throw new Error('missing id');
+export default async (actor: IRemoteUser, activity: ILike) => {
+ const targetUri = getApId(activity.object);
- const noteId = id.split('/').pop();
-
- const note = await Notes.findOne(noteId);
- if (note == null) {
- throw new Error('note not found');
- }
+ const note = await fetchNote(targetUri);
+ if (!note) return `skip: target note not found ${targetUri}`;
await deleteReaction(actor, note);
+ return `ok`;
};
diff --git a/src/services/note/reaction/create.ts b/src/services/note/reaction/create.ts
index a09fbd9c2f..aee31813af 100644
--- a/src/services/note/reaction/create.ts
+++ b/src/services/note/reaction/create.ts
@@ -1,19 +1,18 @@
import { publishNoteStream } from '../../stream';
import watch from '../watch';
import renderLike from '../../../remote/activitypub/renderer/like';
-import { deliver } from '../../../queue';
+import DeliverManager from '../../../remote/activitypub/deliver-manager';
import { renderActivity } from '../../../remote/activitypub/renderer';
import { IdentifiableError } from '../../../misc/identifiable-error';
import { toDbReaction } from '../../../misc/reaction-lib';
-import { User } from '../../../models/entities/user';
+import { User, IRemoteUser } from '../../../models/entities/user';
import { Note } from '../../../models/entities/note';
import { NoteReactions, Users, NoteWatchings, Notes, UserProfiles } from '../../../models';
import { Not } from 'typeorm';
import { perUserReactionsChart } from '../../chart';
import { genId } from '../../../misc/gen-id';
-import { NoteReaction } from '../../../models/entities/note-reaction';
import { createNotification } from '../../create-notification';
-import { isDuplicateKeyValueError } from '../../../misc/is-duplicate-key-value-error';
+import deleteReaction from './delete';
export default async (user: User, note: Note, reaction?: string) => {
// Myself
@@ -23,6 +22,21 @@ export default async (user: User, note: Note, reaction?: string) => {
reaction = await toDbReaction(reaction);
+ const exist = await NoteReactions.findOne({
+ noteId: note.id,
+ userId: user.id,
+ });
+
+ if (exist) {
+ if (exist.reaction !== reaction) {
+ // 別のリアクションがすでにされていたら置き換える
+ await deleteReaction(user, note);
+ } else {
+ // 同じリアクションがすでにされていたら何もしない
+ return;
+ }
+ }
+
// Create reaction
await NoteReactions.save({
id: genId(),
@@ -30,13 +44,6 @@ export default async (user: User, note: Note, reaction?: string) => {
noteId: note.id,
userId: user.id,
reaction
- } as NoteReaction).catch(e => {
- // duplicate key error
- if (isDuplicateKeyValueError(e)) {
- throw new IdentifiableError('51c42bb4-931a-456b-bff7-e5a8a70dd298', 'already reacted');
- }
-
- throw e;
});
// Increment reactions count
@@ -86,12 +93,15 @@ export default async (user: User, note: Note, reaction?: string) => {
}
//#region 配信
- // リアクターがローカルユーザーかつリアクション対象がリモートユーザーの投稿なら配送
- if (Users.isLocalUser(user) && note.userHost !== null) {
+ if (Users.isLocalUser(user) && !note.localOnly) {
const content = renderActivity(renderLike(user, note, reaction));
- Users.findOne(note.userId).then(u => {
- deliver(user, content, u!.inbox);
- });
+ const dm = new DeliverManager(user, content);
+ if (note.userHost !== null) {
+ const reactee = await Users.findOne(note.userId)
+ dm.addDirectRecipe(reactee as IRemoteUser);
+ }
+ dm.addFollowersRecipe();
+ dm.execute();
}
//#endregion
};
diff --git a/src/services/note/reaction/delete.ts b/src/services/note/reaction/delete.ts
index 6e9611ca5a..533c3b4062 100644
--- a/src/services/note/reaction/delete.ts
+++ b/src/services/note/reaction/delete.ts
@@ -2,9 +2,9 @@ import { publishNoteStream } from '../../stream';
import renderLike from '../../../remote/activitypub/renderer/like';
import renderUndo from '../../../remote/activitypub/renderer/undo';
import { renderActivity } from '../../../remote/activitypub/renderer';
-import { deliver } from '../../../queue';
+import DeliverManager from '../../../remote/activitypub/deliver-manager';
import { IdentifiableError } from '../../../misc/identifiable-error';
-import { User } from '../../../models/entities/user';
+import { User, IRemoteUser } from '../../../models/entities/user';
import { Note } from '../../../models/entities/note';
import { NoteReactions, Users, Notes } from '../../../models';
@@ -39,12 +39,15 @@ export default async (user: User, note: Note) => {
});
//#region 配信
- // リアクターがローカルユーザーかつリアクション対象がリモートユーザーの投稿なら配送
- if (Users.isLocalUser(user) && (note.userHost !== null)) {
+ if (Users.isLocalUser(user) && !note.localOnly) {
const content = renderActivity(renderUndo(renderLike(user, note, exist.reaction), user));
- Users.findOne(note.userId).then(u => {
- deliver(user, content, u!.inbox);
- });
+ const dm = new DeliverManager(user, content);
+ if (note.userHost !== null) {
+ const reactee = await Users.findOne(note.userId)
+ dm.addDirectRecipe(reactee as IRemoteUser);
+ }
+ dm.addFollowersRecipe();
+ dm.execute();
}
//#endregion
};