(msg: Api.Message)
| 70 | if (!msg.replyTo) { |
| 71 | await msg.edit({ text: "❌ <b>错误:</b> 请回复一张图片后使用此命令", parseMode: "html" }); |
| 72 | return; |
| 73 | } |
| 74 | |
| 75 | const replied = await safeGetReplyMessage(msg); |
| 76 | if (!replied?.photo) { |
| 77 | await msg.edit({ text: "❌ <b>错误:</b> 回复的消息不包含图片", parseMode: "html" }); |
| 78 | return; |
| 79 | } |
| 80 | |
| 81 | await msg.edit({ text: "⏳ 正在下载并上传图片...", parseMode: "html" }); |
| 82 | |
| 83 | try { |
| 84 | const buffer = await replied.downloadMedia(); |
| 85 | if (!Buffer.isBuffer(buffer) || buffer.length === 0) { |
| 86 | await msg.edit({ text: "❌ <b>错误:</b> 图片下载失败或为空", parseMode: "html" }); |
| 87 | return; |
| 88 | } |
| 89 | |
| 90 | // 从 oxost.ts 借鉴的图片类型检测和文件名生成逻辑 |
| 91 | let filename = "photo.jpg"; |
| 92 | const head = buffer.slice(0, 8).toString('hex').toLowerCase(); |
| 93 | if (head.startsWith('ffd8ff')) filename = "photo.jpg"; |
| 94 | else if (head.startsWith('89504e47')) filename = "photo.png"; |
| 95 | else if (head.startsWith('47494638')) filename = "photo.gif"; |
| 96 | else if (head.startsWith('52494646')) filename = "photo.webp"; |
| 97 | |
| 98 | const form = new globalThis.FormData(); |
| 99 | form.append("file", new Blob([new Uint8Array(buffer)]), filename); |
| 100 | |
| 101 | const response = await axios.post("https://0x0.st", form, { |
| 102 | headers: { 'User-Agent': 'curl/8.0.1' }, |
| 103 | timeout: 60000, |
| 104 | }); |
| 105 | |
| 106 | const imageUrl = response.data?.toString().trim(); |
| 107 | if (!imageUrl || !imageUrl.startsWith("https://0x0.st/")) { |
| 108 | throw new Error("从 0x0.st 获取URL失败"); |
| 109 | } |
| 110 | |
| 111 | const googleUrl = `https://lens.google.com/uploadbyurl?url=${encodeURIComponent(imageUrl)}`; |
| 112 | const yandexUrl = `https://yandex.ru/images/search?url=${encodeURIComponent(imageUrl)}&rpt=imageview`; |
| 113 | |
| 114 | const responseText = `🖼️ <b>搜图结果:</b> (<a href="${htmlEscape(imageUrl)}">原图</a>) |
| 115 | 有效期限: 约30天 |
| 116 | |
| 117 | • <a href="${htmlEscape(googleUrl)}">Google Lens</a> |
| 118 | • <a href="${htmlEscape(yandexUrl)}">Yandex Images</a>`; |
| 119 | |
| 120 | await msg.edit({ text: responseText, parseMode: "html" }); |
| 121 | |
| 122 | } catch (error: any) { |
| 123 | console.error("[soutu] 处理图片失败:", error); |
| 124 | const errorText = `❌ 搜图失败: ${htmlEscape(error.message)}`; |
| 125 | await msg.edit({ text: errorText, parseMode: "html" }); |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 |
no test coverage detected