(msg: Api.Message, args: QuoteArgs)
| 1209 | const canvas = createCanvas(img.width, img.height); |
| 1210 | const ctx = canvas.getContext("2d"); |
| 1211 | ctx.clearRect(0, 0, canvas.width, canvas.height); |
| 1212 | ctx.drawImage(img, 0, 0); |
| 1213 | return canvas; |
| 1214 | } catch (_) { |
| 1215 | return undefined; |
| 1216 | } |
| 1217 | } |
| 1218 | |
| 1219 | function collectAnimatedEmojiIds(messages: any[]): string[] { |
| 1220 | const ids = new Set<string>(); |
| 1221 | const scanEntity = (entity: any) => { |
| 1222 | const id = entity?.custom_emoji_id; |
| 1223 | if (id && animatedCustomEmojiCache.get(String(id))) ids.add(String(id)); |
| 1224 | }; |
| 1225 | const scanMessage = (message: any) => { |
| 1226 | if (!message) return; |
| 1227 | (message.entities || []).forEach(scanEntity); |
| 1228 | (message.caption_entities || []).forEach(scanEntity); |
| 1229 | // Do not let sender emoji_status alone turn a pure-text quote into animated WebM. |
| 1230 | // It is already rendered from customEmojiCache as a static first frame. |
| 1231 | if (message.replyMessage) scanMessage(message.replyMessage); |
| 1232 | if (message.forward) scanMessage(message.forward); |
| 1233 | }; |
| 1234 | messages.forEach(scanMessage); |
| 1235 | return Array.from(ids); |
| 1236 | } |
| 1237 | |
| 1238 | function applyCustomEmojiFrame(messages: any[], id: string, frame: Buffer): void { |
| 1239 | const applyEntity = (entity: any) => { |
| 1240 | if (String(entity?.custom_emoji_id || "") === id) entity.customEmojiBuffer = frame; |
| 1241 | }; |
| 1242 | const scanMessage = (message: any) => { |
| 1243 | if (!message) return; |
| 1244 | (message.entities || []).forEach(applyEntity); |
| 1245 | (message.caption_entities || []).forEach(applyEntity); |
| 1246 | const statusId = message.from?.emoji_status?.custom_emoji_id || message.from?.emoji_status?.customEmojiId || message.emoji_status?.custom_emoji_id || message.emoji_status?.customEmojiId; |
| 1247 | if (String(statusId || "") === id) { |
| 1248 | if (message.from?.emoji_status) message.from.emoji_status.customEmojiBuffer = frame; |
| 1249 | if (message.emoji_status) message.emoji_status.customEmojiBuffer = frame; |
| 1250 | } |
| 1251 | if (message.replyMessage) scanMessage(message.replyMessage); |
| 1252 | if (message.forward) scanMessage(message.forward); |
| 1253 | }; |
| 1254 | messages.forEach(scanMessage); |
| 1255 | } |
| 1256 | |
| 1257 | function isWebmBuffer(buffer: Buffer | undefined): boolean { |
| 1258 | return !!buffer && buffer.length >= 4 && buffer.subarray(0, 4).equals(Buffer.from([0x1a, 0x45, 0xdf, 0xa3])); |
| 1259 | } |
| 1260 | |
| 1261 | function isGifBuffer(buffer: Buffer | undefined): boolean { |
| 1262 | return !!buffer && buffer.length >= 6 && (buffer.subarray(0, 6).toString("ascii") === "GIF87a" || buffer.subarray(0, 6).toString("ascii") === "GIF89a"); |
| 1263 | } |
| 1264 |
no test coverage detected