リモート投稿にリモートでされたリアクションが表示されるように (#5817)
* 第3インスタンスへのLikeも受け入れるように * リアクション済みだったらエラーにせずに置き換えるように * Likeを第3インスタンスにdeliverするように * fix * fix * 同じリアクションがすでにされていたら何もしない * リモートから自身の投稿へリアクションした場合にエラーにならないように
This commit is contained in:
		
							parent
							
								
									f640da911b
								
							
						
					
					
						commit
						b7a4f286b0
					
				|  | @ -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`; | ||||
| }; | ||||
|  |  | |||
|  | @ -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`; | ||||
| }; | ||||
|  |  | |||
|  | @ -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
 | ||||
| }; | ||||
|  |  | |||
|  | @ -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
 | ||||
| }; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue