mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-03 23:14:13 +00:00 
			
		
		
		
	リモート投稿にリモートでされたリアクションが表示されるように (#5817)
* 第3インスタンスへのLikeも受け入れるように * リアクション済みだったらエラーにせずに置き換えるように * Likeを第3インスタンスにdeliverするように * fix * fix * 同じリアクションがすでにされていたら何もしない * リモートから自身の投稿へリアクションした場合にエラーにならないように
This commit is contained in:
		
							parent
							
								
									f640da911b
								
							
						
					
					
						commit
						b7a4f286b0
					
				
					 4 changed files with 50 additions and 48 deletions
				
			
		| 
						 | 
				
			
			@ -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…
	
	Add table
		
		Reference in a new issue