(msg: Api.Message, args: QuoteArgs)
| 1209 | try { |
| 1210 | return await withTimeout(client.invoke(new (Api as any).messages.GetCustomEmojiDocuments({ documentId: unique.map((id) => BigInt(id)) })), QUOTE_RPC_TIMEOUT_MS, "getCustomEmojiDocuments.invoke"); |
| 1211 | } catch (err: any) { |
| 1212 | console.warn("quote custom emoji fetch failed", err?.message || err); |
| 1213 | return []; |
| 1214 | } |
| 1215 | } |
| 1216 | |
| 1217 | async function hydrateCustomEmojiBuffers(client: any, messages: any[]): Promise<void> { |
| 1218 | const ids: string[] = []; |
| 1219 | const scanEntity = (entity: any) => { |
| 1220 | const id = entity?.custom_emoji_id; |
| 1221 | if (id && !customEmojiCache.get(String(id))) ids.push(String(id)); |
| 1222 | }; |
| 1223 | const scanMessage = (message: any) => { |
| 1224 | (message.entities || []).forEach(scanEntity); |
| 1225 | (message.caption_entities || []).forEach(scanEntity); |
| 1226 | const statusId = message.from?.emoji_status?.custom_emoji_id || message.from?.emoji_status?.customEmojiId || message.emoji_status?.custom_emoji_id || message.emoji_status?.customEmojiId; |
| 1227 | if (statusId && !customEmojiCache.get(String(statusId))) ids.push(String(statusId)); |
| 1228 | if (message.replyMessage) scanMessage(message.replyMessage); |
| 1229 | if (message.forward) scanMessage(message.forward); |
| 1230 | }; |
| 1231 | messages.forEach(scanMessage); |
| 1232 | const docs = await getCustomEmojiDocuments(client, ids); |
| 1233 | await runWithConcurrency(docs, EMOJI_FETCH_CONCURRENCY, async (doc: any) => { |
| 1234 | const id = String(doc.id ?? doc.documentId ?? doc.document_id ?? ""); |
| 1235 | if (!id) return; |
| 1236 | let rawBuffer = await downloadCustomEmojiAnimatedPreferred(client, doc); |
| 1237 | const wasAnimated = looksLikeAnimatedEmoji(rawBuffer); |
| 1238 | if (isAnimatedRasterBuffer(rawBuffer)) animatedCustomEmojiCache.set(id, rawBuffer); |
| 1239 | const buffer = await normalizeCustomEmojiBuffer(rawBuffer); |
| 1240 | customEmojiCache.set(id, buffer); |
| 1241 | console.warn("quote custom emoji loaded", id, buffer ? buffer.length : 0, wasAnimated ? "animated-converted" : "static", "source", isGifBuffer(rawBuffer) ? "gif" : isWebmBuffer(rawBuffer) ? "webm" : "other", "mime", doc.mimeType || doc.mime_type || "", "thumbs", doc.thumbs?.length || 0, "videoThumbs", doc.videoThumbs?.length || doc.video_thumbs?.length || 0); |
| 1242 | }); |
| 1243 | const loadedDocIds = new Set(docs.map((doc: any) => String(doc.id ?? doc.documentId ?? doc.document_id ?? "")).filter(Boolean)); |
| 1244 | ids.forEach((id) => { |
| 1245 | if (!loadedDocIds.has(id)) console.warn("quote custom emoji document missing", id); |
| 1246 | else if (!customEmojiCache.get(id)) console.warn("quote custom emoji buffer missing", id); |
| 1247 | }); |
| 1248 | |
| 1249 | const applyEntity = (entity: any) => { |
| 1250 | const id = entity?.custom_emoji_id; |
| 1251 | if (!id) return; |
| 1252 | const buffer = customEmojiCache.get(String(id)); |
| 1253 | if (buffer) entity.customEmojiBuffer = buffer; |
| 1254 | else console.warn("quote custom emoji apply missing", String(id)); |
| 1255 | }; |
| 1256 | const applyMessage = (message: any) => { |
| 1257 | (message.entities || []).forEach(applyEntity); |
| 1258 | (message.caption_entities || []).forEach(applyEntity); |
| 1259 | const statusId = message.from?.emoji_status?.custom_emoji_id || message.from?.emoji_status?.customEmojiId || message.emoji_status?.custom_emoji_id || message.emoji_status?.customEmojiId; |
| 1260 | if (statusId) { |
| 1261 | const buffer = customEmojiCache.get(String(statusId)); |
| 1262 | if (buffer) { |
| 1263 | console.warn("quote sender emoji status cached", String(statusId), buffer.length); |
| 1264 | if (message.from?.emoji_status) message.from.emoji_status.customEmojiBuffer = buffer; |
no test coverage detected