(frames: Buffer[], fps = TG_STICKER_FPS)
| 946 | if (!message) return; |
| 947 | (message.entities || []).forEach(scanEntity); |
| 948 | (message.caption_entities || []).forEach(scanEntity); |
| 949 | // Do not let sender emoji_status alone turn a pure-text quote into animated WebM. |
| 950 | // It is already rendered from customEmojiCache as a static first frame. |
| 951 | if (message.replyMessage) scanMessage(message.replyMessage); |
| 952 | if (message.forward) scanMessage(message.forward); |
| 953 | }; |
| 954 | messages.forEach(scanMessage); |
| 955 | return Array.from(ids); |
| 956 | } |
| 957 | |
| 958 | function applyCustomEmojiFrame(messages: any[], id: string, frame: Buffer): void { |
| 959 | const applyEntity = (entity: any) => { |
| 960 | if (String(entity?.custom_emoji_id || "") === id) entity.customEmojiBuffer = frame; |
| 961 | }; |
| 962 | const scanMessage = (message: any) => { |
| 963 | if (!message) return; |
| 964 | (message.entities || []).forEach(applyEntity); |
| 965 | (message.caption_entities || []).forEach(applyEntity); |
| 966 | const statusId = message.from?.emoji_status?.custom_emoji_id || message.from?.emoji_status?.customEmojiId || message.emoji_status?.custom_emoji_id || message.emoji_status?.customEmojiId; |
| 967 | if (String(statusId || "") === id) { |
| 968 | if (message.from?.emoji_status) message.from.emoji_status.customEmojiBuffer = frame; |
| 969 | if (message.emoji_status) message.emoji_status.customEmojiBuffer = frame; |
| 970 | } |
| 971 | if (message.replyMessage) scanMessage(message.replyMessage); |
| 972 | if (message.forward) scanMessage(message.forward); |
| 973 | }; |
| 974 | messages.forEach(scanMessage); |
| 975 | } |
| 976 | |
| 977 | function isWebmBuffer(buffer: Buffer | undefined): boolean { |
| 978 | return !!buffer && buffer.length >= 4 && buffer.subarray(0, 4).equals(Buffer.from([0x1a, 0x45, 0xdf, 0xa3])); |
| 979 | } |
| 980 | |
| 981 | function isGifBuffer(buffer: Buffer | undefined): boolean { |
| 982 | return !!buffer && buffer.length >= 6 && (buffer.subarray(0, 6).toString("ascii") === "GIF87a" || buffer.subarray(0, 6).toString("ascii") === "GIF89a"); |
| 983 | } |
| 984 | |
| 985 | function isAnimatedRasterBuffer(buffer: Buffer | undefined): boolean { |
| 986 | return isWebmBuffer(buffer) || isGifBuffer(buffer); |
| 987 | } |
| 988 | |
| 989 | function bufferKind(buffer: Buffer | undefined): string { |
| 990 | if (!buffer) return "none"; |
| 991 | if (isGifBuffer(buffer)) return "gif"; |
| 992 | if (isWebmBuffer(buffer)) return "webm"; |
| 993 | if (buffer.length >= 8 && buffer.subarray(1, 4).toString("ascii") === "PNG") return "png"; |
| 994 | if (buffer[0] === 0xff && buffer[1] === 0xd8) return "jpg"; |
no test coverage detected