| 1010 | } |
| 1011 | |
| 1012 | async function convertImageToStickerWebp( |
| 1013 | srcPath: string |
| 1014 | ): Promise<string | null> { |
| 1015 | try { |
| 1016 | if (!fs.existsSync(srcPath)) return null; |
| 1017 | const stickerPath = path.join( |
| 1018 | TEMP_DIR, |
| 1019 | `speedtest_sticker_${Date.now()}_${Math.random() |
| 1020 | .toString(36) |
| 1021 | .slice(2, 8)}.webp` |
| 1022 | ); |
| 1023 | |
| 1024 | // Resize to 512x512 and convert to webp for sticker |
| 1025 | await sharp(srcPath) |
| 1026 | .resize(512, 512, { |
| 1027 | fit: "contain", |
| 1028 | background: { r: 0, g: 0, b: 0, alpha: 0 }, |
| 1029 | }) |
| 1030 | .webp({ quality: 85, effort: 5 }) |
| 1031 | .toFile(stickerPath); |
| 1032 | |
| 1033 | // Basic size check for Telegram sticker (~512KB) |
| 1034 | try { |
| 1035 | const { size } = fs.statSync(stickerPath); |
| 1036 | if (size > 512 * 1024) { |
| 1037 | // Try recompress at lower quality |
| 1038 | await sharp(srcPath) |
| 1039 | .resize(512, 512, { |
| 1040 | fit: "contain", |
| 1041 | background: { r: 0, g: 0, b: 0, alpha: 0 }, |
| 1042 | }) |
| 1043 | .webp({ quality: 65, effort: 6 }) |
| 1044 | .toFile(stickerPath); |
| 1045 | } |
| 1046 | } catch { } |
| 1047 | |
| 1048 | return stickerPath; |
| 1049 | } catch (e) { |
| 1050 | console.error("Failed to convert image to sticker:", e); |
| 1051 | return null; |
| 1052 | } |
| 1053 | } |
| 1054 | |
| 1055 | const speedtest = async (msg: Api.Message) => { |
| 1056 | const rawArgs = msg.message.slice(1).split(" ").slice(1); |