(buffer: Buffer)
| 718 | // Telegram puts formatting entities on the message body. For media messages |
| 719 | // the caption IS the body, so the entities already live in msg.entities. |
| 720 | // Some layers use a separate caption_entities field — merge both. |
| 721 | const msgEntities = ((msg as any).entities || []) as any[]; |
| 722 | const capEntities = ((msg as any).captionEntities || (msg as any).caption_entities || []) as any[]; |
| 723 | const all = Array.isArray(msgEntities) && Array.isArray(capEntities) ? [...msgEntities, ...capEntities] : msgEntities; |
| 724 | return all.map((e) => { |
| 725 | const name = e.className || e.constructor?.name || ""; |
| 726 | const offset = e.offset ?? 0; |
| 727 | const length = e.length ?? 0; |
| 728 | if (name.includes("Bold")) return { type: "bold", offset, length }; |
| 729 | if (name.includes("Italic")) return { type: "italic", offset, length }; |
| 730 | if (name.includes("Underline")) return { type: "underline", offset, length }; |
| 731 | if (name.includes("Strike")) return { type: "strikethrough", offset, length }; |
| 732 | if (name.includes("Blockquote")) return { type: "blockquote", offset, length }; |
| 733 | if (name.includes("Spoiler")) return { type: "spoiler", offset, length }; |
| 734 | if (name.includes("Code")) return { type: "code", offset, length }; |
| 735 | if (name.includes("Pre")) return { type: "pre", offset, length, language: e.language }; |
| 736 | if (name.includes("TextUrl")) return { type: "text_link", offset, length, url: e.url }; |
| 737 | if (name.includes("MentionName")) return { type: "text_mention", offset, length, user: e.userId }; |
| 738 | if (name.includes("Mention")) return { type: "mention", offset, length }; |
| 739 | if (name.includes("Hashtag")) return { type: "hashtag", offset, length }; |
| 740 | if (name.includes("Cashtag")) return { type: "cashtag", offset, length }; |
| 741 | if (name.includes("BotCommand")) return { type: "bot_command", offset, length }; |
| 742 | if (name.includes("Url")) return { type: "url", offset, length }; |
| 743 | if (name.includes("Email")) return { type: "email", offset, length }; |
| 744 | if (name.includes("Phone")) return { type: "phone_number", offset, length }; |
| 745 | if (name.includes("CustomEmoji")) return { type: "custom_emoji", offset, length, custom_emoji_id: String(e.documentId ?? e.document_id ?? "") }; |
| 746 | return { type: "text", offset, length }; |
| 747 | }).filter((e) => e.length > 0 && e.type !== "text"); |
| 748 | } |
| 749 | |
| 750 | async function normalizeAvatarBuffer(buffer: Buffer): Promise<Buffer | undefined> { |
no test coverage detected