(target: any)
| 238 | /(?:https?:\/\/)?t\.me\/(?:\+|joinchat\/)([a-zA-Z0-9_-]+)/, |
| 239 | ); |
| 240 | if (inviteLinkMatch) { |
| 241 | return input; // 返回完整链接,让 formatEntity 特殊处理 |
| 242 | } |
| 243 | |
| 244 | // 3. 处理 t.me 公开群组/频道链接 |
| 245 | // https://t.me/groupname 或 t.me/groupname |
| 246 | const publicLinkMatch = input.match(/(?:https?:\/\/)?t\.me\/([a-zA-Z0-9_]+)/); |
| 247 | if (publicLinkMatch) { |
| 248 | return publicLinkMatch[1]; // 返回用户名 |
| 249 | } |
| 250 | |
| 251 | // 4. 处理私有群组链接 https://t.me/c/1234567890/xxx |
| 252 | const privateLinkMatch = input.match(/(?:https?:\/\/)?t\.me\/c\/(\d+)/); |
| 253 | if (privateLinkMatch) { |
| 254 | return `-100${privateLinkMatch[1]}`; // 转换为完整ID |
| 255 | } |
| 256 | |
| 257 | // 5. 处理 @username 格式 |
| 258 | if (input.startsWith("@")) { |
| 259 | return input.substring(1); // 移除 @ 符号 |
| 260 | } |
| 261 | |
| 262 | // 6. 其他情况直接返回原值,让 formatEntity 处理 |
| 263 | return input; |
| 264 | } |
| 265 | |
| 266 | async function formatEntity(target: any) { |
| 267 | const client = await getGlobalClient(); |
| 268 | if (!client) throw new Error("Telegram 客户端未初始化"); |
| 269 | |
| 270 | let id: any; |
| 271 | let entity: any; |
| 272 | |
| 273 | try { |
| 274 | // 检查是否是邀请链接 |
| 275 | const inviteLinkMatch = |
| 276 | typeof target === "string" |
| 277 | ? target.match( |
| 278 | /(?:https?:\/\/)?t\.me\/(?:\+|joinchat\/)([a-zA-Z0-9_-]+)/, |
| 279 | ) |
| 280 | : null; |
| 281 | |
| 282 | if (inviteLinkMatch) { |
| 283 | // 处理邀请链接 |
| 284 | const hash = inviteLinkMatch[1]; |
| 285 | |
| 286 | try { |
| 287 | // 先检查邀请链接信息 |
| 288 | const inviteInfo = await client.invoke( |
| 289 | new Api.messages.CheckChatInvite({ hash }), |
| 290 | ); |
| 291 | |
| 292 | if (inviteInfo instanceof Api.ChatInviteAlready) { |
| 293 | // 已经在群组中,直接使用返回的 chat 对象 |
| 294 | entity = inviteInfo.chat; |
| 295 | id = entity?.id; |
| 296 | } else if (inviteInfo instanceof Api.ChatInvite) { |
| 297 | // 还未加入群组,需要先加入 |
no test coverage detected