AP引用でquoteUrlに対応 (#5632)
* Supports quoteUrl * Quote resolveをリトライする * Update src/remote/activitypub/models/note.ts Co-Authored-By: Acid Chicken (硫酸鶏) <root@acid-chicken.com> * Update src/remote/activitypub/models/note.ts Co-Authored-By: Acid Chicken (硫酸鶏) <root@acid-chicken.com> * Update src/remote/activitypub/models/note.ts Co-Authored-By: Acid Chicken (硫酸鶏) <root@acid-chicken.com> * Update src/remote/activitypub/models/note.ts Co-Authored-By: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
This commit is contained in:
parent
3e85aad80a
commit
c012f4f880
3 changed files with 38 additions and 9 deletions
|
@ -162,16 +162,42 @@ export async function createNote(value: string | IObject, resolver?: Resolver, s
|
||||||
// 引用
|
// 引用
|
||||||
let quote: Note | undefined | null;
|
let quote: Note | undefined | null;
|
||||||
|
|
||||||
if (note._misskey_quote && typeof note._misskey_quote == 'string') {
|
if (note._misskey_quote || note.quoteUrl) {
|
||||||
quote = await resolveNote(note._misskey_quote).catch(e => {
|
const tryResolveNote = async (uri: string): Promise<{
|
||||||
// 4xxの場合は引用してないことにする
|
status: 'ok';
|
||||||
if (e.statusCode >= 400 && e.statusCode < 500) {
|
res: Note | null;
|
||||||
logger.warn(`Ignored quote target ${note.inReplyTo} - ${e.statusCode} `);
|
} | {
|
||||||
return null;
|
status: 'permerror' | 'temperror';
|
||||||
|
}> => {
|
||||||
|
if (typeof uri !== 'string' || !uri.match(/^https?:/)) return { status: 'permerror' };
|
||||||
|
try {
|
||||||
|
const res = await resolveNote(uri);
|
||||||
|
if (res) {
|
||||||
|
return {
|
||||||
|
status: 'ok',
|
||||||
|
res
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
status: 'permerror'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return {
|
||||||
|
status: e.statusCode >= 400 && e.statusCode < 500 ? 'permerror' : 'temperror'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
logger.warn(`Error in quote target ${note.inReplyTo} - ${e.statusCode || e}`);
|
};
|
||||||
throw e;
|
|
||||||
});
|
const uris = unique([note._misskey_quote, note.quoteUrl].filter((x): x is string => typeof x === 'string'));
|
||||||
|
const results = await Promise.all(uris.map(uri => tryResolveNote(uri)));
|
||||||
|
|
||||||
|
quote = results.filter((x): x is { status: 'ok', res: Note | null } => x.status === 'ok').map(x => x.res).find(x => x);
|
||||||
|
if (!quote) {
|
||||||
|
if (results.some(x => x.status === 'temperror')) {
|
||||||
|
throw 'quote resolve failed';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cw = note.summary === '' ? null : note.summary;
|
const cw = note.summary === '' ? null : note.summary;
|
||||||
|
|
|
@ -159,6 +159,7 @@ export default async function renderNote(note: Note, dive = true, isTalk = false
|
||||||
content,
|
content,
|
||||||
_misskey_content: text,
|
_misskey_content: text,
|
||||||
_misskey_quote: quote,
|
_misskey_quote: quote,
|
||||||
|
quoteUrl: quote,
|
||||||
published: note.createdAt.toISOString(),
|
published: note.createdAt.toISOString(),
|
||||||
to,
|
to,
|
||||||
cc,
|
cc,
|
||||||
|
|
|
@ -75,6 +75,7 @@ export interface INote extends IObject {
|
||||||
type: 'Note' | 'Question' | 'Article' | 'Audio' | 'Document' | 'Image' | 'Page' | 'Video';
|
type: 'Note' | 'Question' | 'Article' | 'Audio' | 'Document' | 'Image' | 'Page' | 'Video';
|
||||||
_misskey_content?: string;
|
_misskey_content?: string;
|
||||||
_misskey_quote?: string;
|
_misskey_quote?: string;
|
||||||
|
quoteUrl?: string;
|
||||||
_misskey_talk: boolean;
|
_misskey_talk: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +83,7 @@ export interface IQuestion extends IObject {
|
||||||
type: 'Note' | 'Question';
|
type: 'Note' | 'Question';
|
||||||
_misskey_content?: string;
|
_misskey_content?: string;
|
||||||
_misskey_quote?: string;
|
_misskey_quote?: string;
|
||||||
|
quoteUrl?: string;
|
||||||
oneOf?: IQuestionChoice[];
|
oneOf?: IQuestionChoice[];
|
||||||
anyOf?: IQuestionChoice[];
|
anyOf?: IQuestionChoice[];
|
||||||
endTime?: Date;
|
endTime?: Date;
|
||||||
|
|
Loading…
Reference in a new issue