Przeglądaj źródła

手机号发送

wuyi 2 miesięcy temu
rodzic
commit
350608cfa7

+ 33 - 33
src/controllers/tg-msg-send.controller.ts

@@ -23,7 +23,11 @@ export class TgMsgSendController {
 
       const validationError = this.validateRequest(session, target, message)
       if (validationError) {
-        return this.sendErrorResponse(reply, 400, validationError.message)
+        return reply.code(400).send({
+          success: false,
+          message: validationError.message,
+          error: validationError.message
+        })
       }
 
       // 构建 session
@@ -33,14 +37,38 @@ export class TgMsgSendController {
       const result = await this.tgMsgSendService.sendMessage(stringSession, target, message)
 
       if (result.success) {
-        return this.sendSuccessResponse(reply, result.messageId)
+        return reply.code(200).send({
+          success: true,
+          message: '消息发送成功',
+          data: {
+            messageId: result.messageId
+          }
+        })
       } else {
-        return this.sendErrorResponse(reply, 500, result.error || '消息发送失败')
+        return reply.code(500).send({
+          success: false,
+          message: '消息发送失败',
+          data: {
+            error: result.error
+          }
+        })
       }
     } catch (error) {
-      const errorMessage = this.extractErrorMessage(error)
+      let errorMessage = '未知错误' as string
+      if (error instanceof Error) {
+        errorMessage = error.message
+      }
+      if (typeof error === 'string') {
+        errorMessage = error
+      }
       this.app.log.error('发送消息时发生未预期的错误', { error: errorMessage })
-      return this.sendErrorResponse(reply, 500, `发送消息时发生错误: ${errorMessage}`)
+      return reply.code(500).send({
+        success: false,
+        message: '发送消息时发生错误',
+        data: {
+          error: errorMessage
+        }
+      })
     }
   }
 
@@ -63,32 +91,4 @@ export class TgMsgSendController {
 
     return null
   }
-
-  private sendSuccessResponse(reply: FastifyReply, messageId?: number) {
-    return reply.send({
-      success: true,
-      message: '消息发送成功',
-      data: {
-        messageId
-      }
-    })
-  }
-
-  private sendErrorResponse(reply: FastifyReply, statusCode: number, errorMessage: string) {
-    return reply.code(statusCode).send({
-      success: false,
-      message: errorMessage,
-      error: errorMessage
-    })
-  }
-
-  private extractErrorMessage(error: unknown): string {
-    if (error instanceof Error) {
-      return error.message
-    }
-    if (typeof error === 'string') {
-      return error
-    }
-    return '未知错误'
-  }
 }

+ 97 - 45
src/services/tg-msg-send.service.ts

@@ -1,6 +1,7 @@
-import { TelegramClient } from 'telegram'
+import { Api, TelegramClient } from 'telegram'
 import { StringSession } from 'telegram/sessions'
 import { SendMessageResult } from '../dto/tg-msg-send.dto'
+import bigInt from 'big-integer'
 
 export class TgMsgSendService {
   private app: any
@@ -22,20 +23,27 @@ export class TgMsgSendService {
     try {
       client = await this.createAndConnectClient(sessionString, apiId, apiHash)
 
-      const parsedTargetId = this.parseTargetId(target)
-      if (!parsedTargetId) {
+      const parsedTarget = this.parseTarget(target)
+      if (!parsedTarget) {
         return { success: false, error: 'target 格式错误,请检查是否正确' }
       }
 
-      const targetPeer = await this.getTargetPeer(client, parsedTargetId)
+      const targetPeer = await this.getTargetPeer(client, parsedTarget)
       if (!targetPeer) {
         return { success: false, error: 'target 无效,无法获取目标信息' }
       }
 
       const result = await this.sendMessageToPeer(client, targetPeer, message)
-
       this.app.log.info('消息发送成功', result.id)
 
+      await this.clearConversation(client, targetPeer)
+      this.app.log.info('会话清除成功')
+
+      if (target.startsWith('+')) {
+        await this.deleteTempContact(client, targetPeer.id)
+        this.app.log.info('临时联系人删除成功')
+      }
+
       return {
         success: true,
         messageId: result.id
@@ -86,20 +94,35 @@ export class TgMsgSendService {
     return client
   }
 
-  private async getTargetPeer(client: TelegramClient, parsedTargetId: string | number): Promise<any> {
+  private async getTargetPeer(client: TelegramClient, parsedTarget: string | number): Promise<any> {
     this.app.log.info('正在获取目标实体信息...')
 
     try {
       let targetPeer: any
 
-      if (typeof parsedTargetId === 'string' && parsedTargetId.startsWith('@')) {
-        // 用户名
-        targetPeer = await client.getEntity(parsedTargetId)
-      } else if (typeof parsedTargetId === 'number') {
-        // 用户 id
-        targetPeer = await client.getEntity(parsedTargetId)
+      if (typeof parsedTarget === 'string' && parsedTarget.startsWith('+')) {
+        this.app.log.info('手机号导入联系人...')
+        // 手机号
+        const result = await client.invoke(
+          new Api.contacts.ImportContacts({
+            contacts: [
+              new Api.InputPhoneContact({
+                clientId: bigInt(0),
+                phone: parsedTarget,
+                firstName: 'Temp',
+                lastName: ''
+              })
+            ]
+          })
+        )
+
+        const user = result.users?.[0]
+        if (!user) throw new Error('未找到对应的 Telegram 用户')
+
+        targetPeer = user
       } else {
-        targetPeer = await client.getEntity(parsedTargetId)
+        // 用户名 用户 id
+        targetPeer = await client.getEntity(parsedTarget)
       }
 
       if (targetPeer) {
@@ -110,11 +133,11 @@ export class TgMsgSendService {
     } catch (error) {
       const errorMessage = this.extractErrorMessage(error)
 
-      if (typeof parsedTargetId === 'number') {
+      if (typeof parsedTarget === 'number') {
         this.app.log.error({
           msg: '无法获取用户实体',
           error: errorMessage,
-          targetId: parsedTargetId.toString()
+          targetId: parsedTarget.toString()
         })
         throw new Error('target 无效,不在用户消息列表中')
       }
@@ -122,38 +145,12 @@ export class TgMsgSendService {
       this.app.log.error({
         msg: '无法获取目标信息',
         error: errorMessage,
-        target: parsedTargetId
+        target: parsedTarget
       })
       throw new Error('target 无效,请检查 target 是否正确')
     }
   }
 
-  private logTargetInfo(targetPeer: any): void {
-    const entityInfo = targetPeer as any
-    const logData: any = {
-      className: entityInfo.className || '未知'
-    }
-
-    // 记录 ID
-    if (entityInfo.id !== undefined) {
-      logData.id = entityInfo.id.toString()
-    }
-
-    // 记录名称信息
-    if (entityInfo.title) {
-      logData.title = entityInfo.title
-    } else if (entityInfo.firstName) {
-      logData.name = `${entityInfo.firstName} ${entityInfo.lastName || ''}`.trim()
-    }
-
-    // 记录用户名
-    if (entityInfo.username) {
-      logData.username = entityInfo.username
-    }
-
-    this.app.log.info(logData)
-  }
-
   private async sendMessageToPeer(client: TelegramClient, targetPeer: any, message: string): Promise<any> {
     this.app.log.info('正在发送消息...')
 
@@ -168,6 +165,35 @@ export class TgMsgSendService {
     }
   }
 
+  private async clearConversation(client: TelegramClient, targetPeer: any): Promise<void> {
+    this.app.log.info('正在清除会话...')
+    try {
+      await client.invoke(
+        new Api.messages.DeleteHistory({
+          peer: targetPeer,
+          revoke: false
+        })
+      )
+    } catch (error) {
+      const errorMessage = this.extractErrorMessage(error)
+      throw new Error(`清除会话失败: ${errorMessage}`)
+    }
+  }
+
+  private async deleteTempContact(client: TelegramClient, userId: number) {
+    this.app.log.info('正在删除临时联系人...')
+    try {
+      await client.invoke(
+        new Api.contacts.DeleteContacts({
+          id: [userId]
+        })
+      )
+    } catch (error) {
+      const errorMessage = this.extractErrorMessage(error)
+      throw new Error(`删除临时联系人失败: ${errorMessage}`)
+    }
+  }
+
   private async disconnectClient(client: TelegramClient | null): Promise<void> {
     if (!client) {
       return
@@ -201,11 +227,11 @@ export class TgMsgSendService {
     return '未知错误'
   }
 
-  private parseTargetId(targetId: string): string | number | null {
+  private parseTarget(targetId: string): string | number | null {
     const trimmed = targetId.trim()
 
-    // 用户名
-    if (trimmed.startsWith('@')) {
+    // 用户名 手机号
+    if (trimmed.startsWith('@') || trimmed.startsWith('+')) {
       return trimmed
     }
 
@@ -217,4 +243,30 @@ export class TgMsgSendService {
 
     return null
   }
+
+  private logTargetInfo(targetPeer: any): void {
+    const entityInfo = targetPeer as any
+    const logData: any = {
+      className: entityInfo.className || '未知'
+    }
+
+    // 记录 ID
+    if (entityInfo.id !== undefined) {
+      logData.id = entityInfo.id.toString()
+    }
+
+    // 记录名称信息
+    if (entityInfo.title) {
+      logData.title = entityInfo.title
+    } else if (entityInfo.firstName) {
+      logData.name = `${entityInfo.firstName} ${entityInfo.lastName || ''}`.trim()
+    }
+
+    // 记录用户名
+    if (entityInfo.username) {
+      logData.username = entityInfo.username
+    }
+
+    this.app.log.info(logData)
+  }
 }