* 等待机器人回复消息 * @param client Telegram客户端 * @param botEntity 机器人实体 * @param timeout 超时时间(毫秒) * @param expectPhoto 是否期望图片回复 * @returns 机器人回复的消息,如果超时则返回null
( client: any, botEntity: any, timeout: number = 30000, expectPhoto: boolean = true )
| 59 | botEntity: any, |
| 60 | timeout: number = 30000, |
| 61 | expectPhoto: boolean = true |
| 62 | ): Promise<Api.Message | null> { |
| 63 | return new Promise((resolve) => { |
| 64 | let timeoutId: NodeJS.Timeout | null = null; |
| 65 | let eventHandler: ((event: any) => Promise<void>) | null = null; |
| 66 | let eventBuilder: NewMessage | null = null; |
| 67 | let pendingListener: PendingReplyListener | null = null; |
| 68 | let isResolved = false; |
| 69 | |
| 70 | const cleanup = (result: Api.Message | null) => { |
| 71 | if (isResolved) return; |
| 72 | isResolved = true; |
| 73 | |
| 74 | if (timeoutId) { |
| 75 | clearTimeout(timeoutId); |
| 76 | runtime.pendingDeleteTimers.delete(timeoutId); |
| 77 | timeoutId = null; |
| 78 | } |
| 79 | |
| 80 | if (eventHandler) { |
| 81 | try { |
| 82 | client.removeEventHandler(eventHandler, eventBuilder || new NewMessage({})); |
| 83 | } catch (e) { |
| 84 | console.warn('[botmzt] 移除事件监听器失败:', e); |
| 85 | } |
| 86 | eventHandler = null; |
| 87 | } |
| 88 | |
| 89 | if (pendingListener) { |
| 90 | runtime.pendingReplyListeners.delete(pendingListener); |
| 91 | pendingListener = null; |
| 92 | } |
| 93 | |
| 94 | resolve(result); |
| 95 | }; |
| 96 | |
| 97 | timeoutId = setTimeout(() => cleanup(null), timeout); |
| 98 | runtime.pendingDeleteTimers.add(timeoutId); |
| 99 | |
| 100 | eventHandler = async (event: any) => { |
| 101 | try { |
| 102 | const message = event.message; |
| 103 | |
| 104 | if (!message || !message.peerId) return; |
| 105 | |
| 106 | const senderId = message.senderId?.toString(); |
| 107 | const botId = (botEntity as any).id?.toString(); |
| 108 | |
| 109 | if (senderId !== botId) return; |
| 110 | |
| 111 | const messageTime = message.date * 1000; |
| 112 | const currentTime = Date.now(); |
| 113 | const timeDiff = currentTime - messageTime; |
| 114 | |
| 115 | if (timeDiff > 5000) return; |
| 116 | |
| 117 | if (expectPhoto) { |
| 118 | const hasPhoto = message.photo || |
no test coverage detected