* 媒体消息防撤回处理
( client: TelegramClient, message: Api.Message, trollImagePath: string | null, chatEntity: any )
| 131 | ): Promise<boolean> { |
| 132 | // 排除网页预览 |
| 133 | if (!message.media || message.media instanceof Api.MessageMediaWebPage) { |
| 134 | return false; |
| 135 | } |
| 136 | |
| 137 | // 检查是否为贴纸并跳过 |
| 138 | if (message.media instanceof Api.MessageMediaDocument) { |
| 139 | const doc = message.media.document; |
| 140 | if (doc instanceof Api.Document) { |
| 141 | // 检查文档属性中是否包含贴纸标识 |
| 142 | const isSticker = doc.attributes?.some(attr => |
| 143 | attr instanceof Api.DocumentAttributeSticker |
| 144 | ); |
| 145 | if (isSticker) { |
| 146 | return false; |
| 147 | } |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | if (!trollImagePath || !fs.existsSync(trollImagePath)) { |
| 152 | return false; |
| 153 | } |
| 154 | |
| 155 | // 超过可编辑时间窗口(48h)则静默跳过,避免 MESSAGE_EDIT_TIME_EXPIRED |
| 156 | const nowSec = Math.floor(Date.now() / 1000); |
| 157 | if (typeof (message as any).date === "number" && nowSec - (message as any).date > 172800) { |
| 158 | return false; |
| 159 | } |
| 160 | |
| 161 | try { |
| 162 | const uploadedFile = await client.uploadFile({ |
| 163 | file: new CustomFile( |
| 164 | "dme_troll.jpg", |
| 165 | fs.statSync(trollImagePath).size, |
| 166 | trollImagePath |
| 167 | ), |
| 168 | workers: 1, |
| 169 | }); |
| 170 | |
| 171 | await client.invoke( |
| 172 | new Api.messages.EditMessage({ |
| 173 | peer: chatEntity, |
| 174 | id: message.id, |
| 175 | message: "", |
| 176 | media: new Api.InputMediaUploadedPhoto({ file: uploadedFile }), |
| 177 | }) |
| 178 | ); |
| 179 | return true; |
| 180 | } catch { |
| 181 | // 任意编辑失败(含 MESSAGE_EDIT_TIME_EXPIRED)静默跳过 |
| 182 | return false; |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | async function editTextMessageToPlaceholder( |
| 187 | client: TelegramClient, |
| 188 | message: Api.Message, |
| 189 | chatEntity: any |
| 190 | ): Promise<boolean> { |
no outgoing calls
no test coverage detected