room_management.ts 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. import LiveClient, * as $LiveClient from "@alicloud/live20161101";
  2. import LiveInteractionClient, * as $LiveInteraction from "@alicloud/live-interaction20201214";
  3. import * as $OpenApi from "@alicloud/openapi-client";
  4. interface RoomOptions {
  5. title?: string;
  6. templateId?: string;
  7. maxUsers?: number;
  8. }
  9. interface UserInfo {
  10. id: string;
  11. name?: string;
  12. avatar?: string;
  13. isAdmin?: boolean;
  14. }
  15. interface Message {
  16. id: string;
  17. sender: UserInfo;
  18. content: string;
  19. timestamp: Date;
  20. }
  21. export class RoomManagementSystem {
  22. private liveClient: LiveClient.default;
  23. private liveInteractionClient: LiveInteractionClient.default;
  24. private appId: string;
  25. constructor() {
  26. const config = new $OpenApi.Config({
  27. accessKeyId: Deno.env.get("ALIYUN_LIVE_ACCESS_KEY_ID") || "",
  28. accessKeySecret: Deno.env.get("ALIYUN_LIVE_ACCESS_KEY_SECRET") || "",
  29. endpoint: "live.aliyuncs.com"
  30. });
  31. this.liveClient = new LiveClient.default(config);
  32. this.liveInteractionClient = new LiveInteractionClient.default(config);
  33. this.appId = Deno.env.get("ALIYUN_CHAT_APP_ID") || "";
  34. }
  35. /**
  36. * 创建房间
  37. * @param roomId 房间ID
  38. * @param options 房间选项
  39. * @returns 房间信息
  40. */
  41. async createRoom(roomId: string, options: RoomOptions = {}): Promise<{
  42. roomId: string;
  43. pushUrl: string;
  44. playUrl: string;
  45. chatToken: string;
  46. }> {
  47. try {
  48. // 创建互动直播房间
  49. const createRequest = new $LiveInteraction.CreateRoomRequest({
  50. AppId: this.appId,
  51. RoomId: roomId,
  52. Title: options.title || `Room ${roomId}`,
  53. TemplateId: options.templateId || "standard"
  54. });
  55. const createResponse = await this.liveInteractionClient.createRoom(createRequest);
  56. // 获取推流/播放地址
  57. const urlRequest = new $LiveClient.DescribeLiveStreamsOnlineListRequest({
  58. AppId: this.appId,
  59. RoomId: roomId
  60. });
  61. const urlResponse = await this.liveClient.describeLiveStreamsOnlineList(urlRequest);
  62. return {
  63. roomId,
  64. pushUrl: urlResponse.PushUrl,
  65. playUrl: urlResponse.PlayUrl,
  66. chatToken: createResponse.Token
  67. };
  68. } catch (error) {
  69. throw new Error(`Failed to create room: ${error instanceof Error ? error.message : "Unknown error"}`);
  70. }
  71. }
  72. /**
  73. * 销毁房间
  74. * @param roomId 房间ID
  75. */
  76. async destroyRoom(roomId: string): Promise<void> {
  77. try {
  78. const request = new $LiveInteraction.DestroyRoomRequest({
  79. AppId: this.appId,
  80. RoomId: roomId
  81. });
  82. await this.liveInteractionClient.destroyRoom(request);
  83. } catch (error) {
  84. throw new Error(`Failed to destroy room: ${error instanceof Error ? error.message : "Unknown error"}`);
  85. }
  86. }
  87. /**
  88. * 用户加入房间
  89. * @param roomId 房间ID
  90. * @param user 用户信息
  91. * @returns 用户Token和播放地址
  92. */
  93. async joinRoom(roomId: string, user: UserInfo) {
  94. try {
  95. const addMemberRequest = new $LiveInteraction.AddGroupMembersRequest({
  96. appId:this.appId,
  97. requestParams: {
  98. groupId: roomId,
  99. members: [user.id]
  100. }
  101. })
  102. await this.liveInteractionClient.addGroupMembers(addMemberRequest) ;
  103. } catch (error) {
  104. throw new Error(`Failed to join room: ${error instanceof Error ? error.message : "Unknown error"}`);
  105. }
  106. }
  107. /**
  108. * 用户离开房间
  109. * @param roomId 房间ID
  110. * @param userId 用户ID
  111. */
  112. async leaveRoom(roomId: string, userId: string): Promise<void> {
  113. try {
  114. const request = new $LiveInteraction.RemoveGroupMembersRequest({
  115. AppId: this.appId,
  116. RoomId: roomId,
  117. UserId: userId
  118. });
  119. await this.liveInteractionClient.leaveRoom(request);
  120. } catch (error) {
  121. throw new Error(`Failed to leave room: ${error instanceof Error ? error.message : "Unknown error"}`);
  122. }
  123. }
  124. /**
  125. * 发送消息
  126. * @param roomId 房间ID
  127. * @param sender 发送者信息
  128. * @param content 消息内容
  129. * @returns 消息ID
  130. */
  131. async sendMessage(roomId: string, sender: UserInfo, content: string): Promise<string> {
  132. try {
  133. const request = new $LiveInteraction.SendMessageRequest({
  134. AppId: this.appId,
  135. RoomId: roomId,
  136. SenderId: sender.id,
  137. Content: content
  138. });
  139. const response = await this.liveInteractionClient.sendMessage(request);
  140. return response.MessageId;
  141. } catch (error) {
  142. throw new Error(`Failed to send message: ${error instanceof Error ? error.message : "Unknown error"}`);
  143. }
  144. }
  145. /**
  146. * 获取历史消息
  147. * @param roomId 房间ID
  148. * @param limit 消息数量限制
  149. * @returns 消息列表
  150. */
  151. async getHistoryMessages(roomId: string, limit: number = 50): Promise<Message[]> {
  152. try {
  153. const request = new $LiveInteraction.GetHistoryMessagesRequest({
  154. AppId: this.appId,
  155. RoomId: roomId,
  156. Limit: limit
  157. });
  158. const response = await this.liveInteractionClient.getHistoryMessages(request);
  159. return response.Messages.map((msg: any) => ({
  160. id: msg.MessageId,
  161. sender: {
  162. id: msg.SenderId,
  163. name: msg.SenderName,
  164. avatar: msg.SenderAvatar
  165. },
  166. content: msg.Content,
  167. timestamp: new Date(msg.Timestamp)
  168. }));
  169. } catch (error) {
  170. throw new Error(`Failed to get history messages: ${error instanceof Error ? error.message : "Unknown error"}`);
  171. }
  172. }
  173. /**
  174. * 禁言用户
  175. * @param roomId 房间ID
  176. * @param userId 用户ID
  177. * @param duration 禁言时长(秒)
  178. */
  179. async muteUser(roomId: string, userId: string, duration: number = 3600): Promise<void> {
  180. try {
  181. const request = new $LiveInteraction.MuteUserRequest({
  182. AppId: this.appId,
  183. RoomId: roomId,
  184. UserId: userId,
  185. Duration: duration
  186. });
  187. await this.liveInteractionClient.muteUser(request);
  188. } catch (error) {
  189. throw new Error(`Failed to mute user: ${error instanceof Error ? error.message : "Unknown error"}`);
  190. }
  191. }
  192. /**
  193. * 踢出用户
  194. * @param roomId 房间ID
  195. * @param userId 用户ID
  196. */
  197. async kickUser(roomId: string, userId: string): Promise<void> {
  198. try {
  199. const request = new $LiveInteraction.KickUserRequest({
  200. AppId: this.appId,
  201. RoomId: roomId,
  202. UserId: userId
  203. });
  204. await this.liveInteractionClient.kickUser(request);
  205. } catch (error) {
  206. throw new Error(`Failed to kick user: ${error instanceof Error ? error.message : "Unknown error"}`);
  207. }
  208. }
  209. /**
  210. * 获取房间信息
  211. * @param roomId 房间ID
  212. * @returns 房间信息
  213. */
  214. async getRoomInfo(roomId: string): Promise<{
  215. roomId: string;
  216. playUrl: string;
  217. onlineCount: number;
  218. }> {
  219. try {
  220. // 获取直播间信息
  221. const infoRequest = new $LiveClient.DescribeLiveStreamsOnlineListRequest({
  222. AppId: this.appId,
  223. RoomId: roomId
  224. });
  225. const infoResponse = await this.liveClient.describeLiveStreamsOnlineList(infoRequest);
  226. // 获取在线人数
  227. const statsRequest = new $LiveClient.DescribeLiveDomainOnlineUserNumRequest({
  228. AppId: this.appId,
  229. RoomId: roomId
  230. });
  231. const statsResponse = await this.liveClient.describeLiveDomainOnlineUserNum(statsRequest);
  232. return {
  233. roomId,
  234. playUrl: infoResponse.PlayUrl,
  235. onlineCount: statsResponse.OnlineCount
  236. };
  237. } catch (error) {
  238. throw new Error(`Failed to get room info: ${error instanceof Error ? error.message : "Unknown error"}`);
  239. }
  240. }
  241. }