Procházet zdrojové kódy

✨ feat(agora): 新增Agora Token服务模块

- 实现RTC Token生成功能,用于语音转文字服务
- 实现RTM Token生成功能,用于实时消息服务
- 添加Token参数验证和Token信息获取方法
- 从环境变量加载Agora配置并添加配置检查
yourname před 4 měsíci
rodič
revize
16ce15358f
1 změnil soubory, kde provedl 99 přidání a 0 odebrání
  1. 99 0
      src/server/modules/agora/agora-token.service.ts

+ 99 - 0
src/server/modules/agora/agora-token.service.ts

@@ -0,0 +1,99 @@
+import { RtcTokenBuilder, RtmTokenBuilder, RtcRole, RtmRole } from 'agora-token'
+
+export class AgoraTokenService {
+  private appId: string
+  private appSecret: string
+  private tokenExpiry: number
+
+  constructor() {
+    this.appId = process.env.AGORA_APP_ID || ''
+    this.appSecret = process.env.AGORA_APP_SECRET || ''
+    this.tokenExpiry = parseInt(process.env.AGORA_TOKEN_EXPIRY || '3600')
+
+    if (!this.appId || !this.appSecret) {
+      throw new Error('Agora配置缺失:请设置AGORA_APP_ID和AGORA_APP_SECRET环境变量')
+    }
+  }
+
+  /**
+   * 生成RTC Token(用于语音转文字功能)
+   */
+  generateRtcToken(channelName: string, userId: string | number = 0): string {
+    try {
+      const currentTimestamp = Math.floor(Date.now() / 1000)
+      const privilegeExpiredTs = currentTimestamp + this.tokenExpiry
+
+      const token = RtcTokenBuilder.buildTokenWithUid(
+        this.appId,
+        this.appSecret,
+        channelName,
+        typeof userId === 'number' ? userId : parseInt(userId),
+        RtcRole.PUBLISHER,
+        privilegeExpiredTs
+      )
+
+      return token
+    } catch (error) {
+      throw new Error(`RTC Token生成失败: ${error instanceof Error ? error.message : '未知错误'}`)
+    }
+  }
+
+  /**
+   * 生成RTM Token(用于实时消息功能)
+   */
+  generateRtmToken(userId: string): string {
+    try {
+      const currentTimestamp = Math.floor(Date.now() / 1000)
+      const privilegeExpiredTs = currentTimestamp + this.tokenExpiry
+
+      const token = RtmTokenBuilder.buildToken(
+        this.appId,
+        this.appSecret,
+        userId,
+        RtmRole.Rtm_User,
+        privilegeExpiredTs
+      )
+
+      return token
+    } catch (error) {
+      throw new Error(`RTM Token生成失败: ${error instanceof Error ? error.message : '未知错误'}`)
+    }
+  }
+
+  /**
+   * 验证Token参数
+   */
+  validateTokenParams(type: 'rtc' | 'rtm', channel?: string, userId?: string): void {
+    if (type === 'rtc' && !channel) {
+      throw new Error('RTC Token需要提供channel参数')
+    }
+
+    if (type === 'rtm' && !userId) {
+      throw new Error('RTM Token需要提供userId参数')
+    }
+
+    if (channel && channel.length > 64) {
+      throw new Error('频道名称长度不能超过64个字符')
+    }
+
+    if (userId && userId.length > 64) {
+      throw new Error('用户ID长度不能超过64个字符')
+    }
+  }
+
+  /**
+   * 获取Token信息(包含过期时间)
+   */
+  getTokenInfo(token: string, type: 'rtc' | 'rtm') {
+    const currentTimestamp = Math.floor(Date.now() / 1000)
+    const expiryTimestamp = currentTimestamp + this.tokenExpiry
+
+    return {
+      token,
+      type,
+      expiresAt: expiryTimestamp,
+      expiresIn: this.tokenExpiry,
+      generatedAt: currentTimestamp
+    }
+  }
+}