TencentIm.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Master\Framework\Library\Tencent;
  4. use App\Master\Framework\Library\Library;
  5. use Hyperf\Config\Annotation\Value;
  6. use function Hyperf\Config\config;
  7. class TencentIm extends Library
  8. {
  9. public string $base_uri = "https://console.tim.qq.com";
  10. #[Value("tencent.im")]
  11. private array $config;
  12. /**
  13. * 创建群组
  14. * @param string $user_chat_id
  15. * @param string $group_no
  16. * @param string $room_name
  17. * @param string $type
  18. * @param string $notification
  19. * @return bool
  20. */
  21. public function create_group(string $user_chat_id,string $group_no,string $room_name,string $type = 'AVChatRoom', string $notification = '')
  22. {
  23. $data = [
  24. 'Owner_Account' => $user_chat_id, // 群主 ID
  25. 'Type' => $type, // 群组形态,包括 Public(陌生人社交群),Private(即 Work,好友工作群),ChatRoom(即 Meeting,会议群),AVChatRoom(直播群),Community(社群)
  26. 'GroupId' => $group_no, // 自定义群组 ID
  27. 'Name' => $room_name,
  28. 'Introduction' => json_encode([
  29. ''
  30. ]),// 群简介
  31. 'Notification' => $notification,// 群公告
  32. ];
  33. $response = $this->post('/v4/group_open_http_svc/create_group', $data);
  34. if ($response->getStatusCode() != 200) {
  35. return $this->error($response->getReasonPhrase());
  36. }
  37. $json = $response->getBody()->getContents();
  38. $body = json_decode($json, true);
  39. if (empty($body['ActionStatus']) || $body['ActionStatus'] != 'OK') {
  40. return $this->error(!empty($body['ErrorInfo']) ? $body['ErrorInfo'] : 'im error', $body ?? []);
  41. }
  42. return $this->success('创建成功', $body);
  43. }
  44. /**
  45. * 创建群组
  46. * @param string $user_chat_id
  47. * @param string $group_no
  48. * @param string $room_name
  49. * @param string $type
  50. * @param string $notification
  51. * @return bool
  52. */
  53. public function destroy_group(string $group_no)
  54. {
  55. $data = [
  56. 'GroupId' => $group_no, // 自定义群组 ID
  57. ];
  58. $response = $this->post('/v4/group_open_http_svc/destroy_group', $data);
  59. if ($response->getStatusCode() != 200) {
  60. return $this->error($response->getReasonPhrase());
  61. }
  62. $json = $response->getBody()->getContents();
  63. $body = json_decode($json, true);
  64. if (empty($body['ActionStatus']) || $body['ActionStatus'] != 'OK') {
  65. return $this->error(!empty($body['ErrorInfo']) ? $body['ErrorInfo'] : 'im error', $body ?? []);
  66. }
  67. return $this->success('关闭成功', $body);
  68. }
  69. /**
  70. * 移除房间
  71. * @param string $group_no
  72. * @param string $user_chat_id
  73. * @return bool
  74. */
  75. public function delete_group_member(string $group_no,string $user_chat_id)
  76. {
  77. $data = [
  78. 'GroupId' => $group_no, // 自定义群组 ID
  79. 'MemberToDel_Account' => [$user_chat_id]
  80. ];
  81. $response = $this->post('/v4/group_open_http_svc/delete_group_member', $data);
  82. if ($response->getStatusCode() != 200) {
  83. return $this->error($response->getReasonPhrase());
  84. }
  85. $json = $response->getBody()->getContents();
  86. $body = json_decode($json, true);
  87. if (empty($body['ActionStatus']) || $body['ActionStatus'] != 'OK') {
  88. return $this->error(!empty($body['ErrorInfo']) ? $body['ErrorInfo'] : 'im error', $body ?? []);
  89. }
  90. return $this->success('操作成功', $body);
  91. }
  92. /**
  93. * 设置/取消直播群管理员
  94. * @param string $group_no
  95. * @param string $user_chat_id
  96. * @return bool
  97. */
  98. public function modify_admin(string $group_no,string $user_chat_id,int $type = 1)
  99. {
  100. $data = [
  101. 'GroupId' => $group_no, // 自定义群组 ID
  102. 'CommandType' => $type,
  103. 'Admin_Account' => [$user_chat_id],
  104. ];
  105. $response = $this->post('/v4/group_open_avchatroom_http_svc/modify_admin', $data);
  106. if ($response->getStatusCode() != 200) {
  107. return $this->error($response->getReasonPhrase());
  108. }
  109. $json = $response->getBody()->getContents();
  110. $body = json_decode($json, true);
  111. if (empty($body['ActionStatus']) || $body['ActionStatus'] != 'OK') {
  112. return $this->error(!empty($body['ErrorInfo']) ? $body['ErrorInfo'] : 'im error', $body ?? []);
  113. }
  114. return $this->success('操作成功', $body);
  115. }
  116. /**
  117. * 禁言 or 解除
  118. * @param string $group_no
  119. * @param string $user_chat_id
  120. * @param $time // time = 0 解除
  121. * @return bool
  122. */
  123. public function forbid_send_msg(string $group_no,string $user_chat_id,int $time = 0)
  124. {
  125. $data = [
  126. 'GroupId' => $group_no, // 自定义群组 ID
  127. 'Members_Account' => [$user_chat_id],
  128. 'MuteTime' => $time
  129. ];
  130. $response = $this->post('/v4/group_open_http_svc/forbid_send_msg', $data);
  131. if ($response->getStatusCode() != 200) {
  132. return $this->error($response->getReasonPhrase());
  133. }
  134. $json = $response->getBody()->getContents();
  135. $body = json_decode($json, true);
  136. if (empty($body['ActionStatus']) || $body['ActionStatus'] != 'OK') {
  137. return $this->error(!empty($body['ErrorInfo']) ? $body['ErrorInfo'] : 'im error', $body ?? []);
  138. }
  139. return $this->success('操作成功', $body);
  140. }
  141. /**
  142. * 获取被禁言群成员列表
  143. * @param string $group_no
  144. * @return bool
  145. */
  146. public function get_group_muted_account(string $group_no)
  147. {
  148. $data = [
  149. 'GroupId' => $group_no, // 自定义群组 ID
  150. ];
  151. $response = $this->post('/v4/group_open_http_svc/get_group_muted_account', $data);
  152. if ($response->getStatusCode() != 200) {
  153. return $this->error($response->getReasonPhrase());
  154. }
  155. $json = $response->getBody()->getContents();
  156. $body = json_decode($json, true);
  157. if (empty($body['ActionStatus']) || $body['ActionStatus'] != 'OK') {
  158. return $this->error(!empty($body['ErrorInfo']) ? $body['ErrorInfo'] : 'im error', $body ?? []);
  159. }
  160. return $this->success('操作成功', $body);
  161. }
  162. /**
  163. * 获取被禁言群成员列表
  164. * @param string $group_no
  165. * @return bool
  166. */
  167. public function get_group_ban_member(string $group_no,int $limit = 100,int $Offset = 0)
  168. {
  169. $data = [
  170. 'GroupId' => $group_no, // 自定义群组 ID
  171. 'Limit' => $limit, // 单次拉取限制,最大为100
  172. 'Offset' => $Offset, // 分页标识,首次传0,如果封禁的成员数大于100,下一次拉取需要设置为后台回复的 NextOffset
  173. ];
  174. $response = $this->post('/v4/group_open_http_svc/get_group_ban_member', $data);
  175. if ($response->getStatusCode() != 200) {
  176. return $this->error($response->getReasonPhrase());
  177. }
  178. $json = $response->getBody()->getContents();
  179. $body = json_decode($json, true);
  180. if (empty($body['ActionStatus']) || $body['ActionStatus'] != 'OK') {
  181. return $this->error(!empty($body['ErrorInfo']) ? $body['ErrorInfo'] : 'im error', $body ?? []);
  182. }
  183. return $this->success('操作成功', $body);
  184. }
  185. /**
  186. * 封禁用户
  187. * @param string $group_no
  188. * @param string $user_chat_id
  189. * @param $time // time = 0 解除
  190. * @param $remark
  191. * @return bool
  192. */
  193. public function ban_group_member(string $group_no,string $user_chat_id,int $time = 0, $remark = '违规操作')
  194. {
  195. $data = [
  196. 'GroupId' => $group_no,
  197. 'Members_Account' => [$user_chat_id],
  198. 'Duration' => $time, // 封禁时长,单位:秒
  199. 'Description' => $remark// 封禁信息
  200. ];
  201. $response = $this->post('/v4/group_open_http_svc/ban_group_member', $data);
  202. if ($response->getStatusCode() != 200) {
  203. return $this->error($response->getReasonPhrase());
  204. }
  205. $json = $response->getBody()->getContents();
  206. $body = json_decode($json, true);
  207. if (empty($body['ActionStatus']) || $body['ActionStatus'] != 'OK') {
  208. return $this->error(!empty($body['ErrorInfo']) ? $body['ErrorInfo'] : 'im error', $body ?? []);
  209. }
  210. return $this->success('操作成功', $body);
  211. }
  212. /**
  213. * 解除封禁用户
  214. * @param string $group_no
  215. * @param string $user_chat_id
  216. * @return bool
  217. */
  218. public function unban_group_member(string $group_no,string $user_chat_id)
  219. {
  220. $data = [
  221. 'GroupId' => $group_no,
  222. 'Members_Account' => [$user_chat_id]
  223. ];
  224. $response = $this->post('/v4/group_open_http_svc/unban_group_member', $data);
  225. if ($response->getStatusCode() != 200) {
  226. return $this->error($response->getReasonPhrase());
  227. }
  228. $json = $response->getBody()->getContents();
  229. $body = json_decode($json, true);
  230. if (empty($body['ActionStatus']) || $body['ActionStatus'] != 'OK') {
  231. return $this->error(!empty($body['ErrorInfo']) ? $body['ErrorInfo'] : 'im error', $body ?? []);
  232. }
  233. return $this->success('操作成功', $body);
  234. }
  235. /**
  236. * 获取直播群在线人数
  237. * @param int $room_no
  238. * @return bool
  239. */
  240. public function get_online_member_num(string $room_no)
  241. {
  242. $data = [
  243. 'GroupId' => (string)$room_no
  244. ];
  245. $response = $this->post('/v4/group_open_http_svc/get_online_member_num', $data);
  246. if ($response->getStatusCode() != 200) {
  247. return $this->error($response->getReasonPhrase());
  248. }
  249. $json = $response->getBody()->getContents();
  250. $body = json_decode($json, true);
  251. if (empty($body['ActionStatus']) || $body['ActionStatus'] != 'OK') {
  252. return $this->error(!empty($body['ErrorInfo']) ? $body['ErrorInfo'] : 'im error', $body ?? []);
  253. }
  254. return $this->success('获取成功', $body);
  255. }
  256. /**
  257. * 设置计数器
  258. * @param string $room_no
  259. * @param array $counter
  260. * @return bool
  261. */
  262. public function update_group_counter(string $room_no, array $counter)
  263. {
  264. $data = [
  265. 'GroupId' => $room_no,// 群组 ID
  266. 'GroupCounter' => $counter,
  267. 'Mode' => 'Set'
  268. ];
  269. $response = $this->post('/v4/group_open_http_svc/update_group_counter', $data);
  270. if ($response->getStatusCode() != 200) {
  271. return $this->error($response->getReasonPhrase());
  272. }
  273. $json = $response->getBody()->getContents();
  274. $body = json_decode($json, true);
  275. if (empty($body['ActionStatus']) || $body['ActionStatus'] != 'OK') {
  276. return $this->error(!empty($body['ErrorInfo']) ? $body['ErrorInfo'] : 'im error', $body ?? []);
  277. }
  278. return $this->success('获取成功', $body);
  279. }
  280. /**
  281. * 设置群属性
  282. * @param string $room_no
  283. * @param array $attr
  284. * @return bool
  285. */
  286. public function modify_group_attr(string $room_no, array $attr)
  287. {
  288. $data = [
  289. 'GroupId' => $room_no,// 群组 ID
  290. 'GroupAttr' => $attr
  291. ];
  292. $response = $this->post('/v4/group_open_http_svc/modify_group_attr', $data);
  293. if ($response->getStatusCode() != 200) {
  294. return $this->error($response->getReasonPhrase());
  295. }
  296. $json = $response->getBody()->getContents();
  297. $body = json_decode($json, true);
  298. if (empty($body['ActionStatus']) || $body['ActionStatus'] != 'OK') {
  299. return $this->error(!empty($body['ErrorInfo']) ? $body['ErrorInfo'] : 'im error', $body ?? []);
  300. }
  301. return $this->success('获取成功', $body);
  302. }
  303. /**
  304. * 获取全部群组
  305. * @return bool
  306. */
  307. public function get_appid_group_list()
  308. {
  309. $data = [
  310. 'Limit' => 1000,// 群主 ID
  311. 'Next' => 0
  312. ];
  313. $response = $this->post('/v4/group_open_http_svc/get_appid_group_list', $data);
  314. if ($response->getStatusCode() != 200) {
  315. return $this->error($response->getReasonPhrase());
  316. }
  317. $json = $response->getBody()->getContents();
  318. $body = json_decode($json, true);
  319. if (empty($body['ActionStatus']) || $body['ActionStatus'] != 'OK') {
  320. return $this->error(!empty($body['ErrorInfo']) ? $body['ErrorInfo'] : 'im error', $body ?? []);
  321. }
  322. return $this->success('获取成功', $body);
  323. }
  324. /**
  325. * 获取直播推流信息
  326. * @param string $stream_name 直播间号
  327. * @param string $time 过期时间
  328. * @return string
  329. */
  330. public function getLivePushUrl(string $stream_name, string $time = '')
  331. {
  332. $key = $this->config['push_key'];
  333. $time = !empty($time) ? $time : date('Y-m-d H:i:s', strtotime('+1 day'));
  334. $domain = $this->config['push_domain'];
  335. if ($key && $time) {
  336. $txTime = strtoupper(base_convert((string)strtotime($time), 10, 16));
  337. //txSecret = MD5( KEY + streamName + txTime )
  338. $txSecret = md5($key . $stream_name . $txTime);
  339. $ext_str = "?" . http_build_query(["txSecret" => $txSecret, "txTime" => $txTime]);
  340. }
  341. return "rtmp://{$domain}/live/{$stream_name}" . ($ext_str ?? "");
  342. }
  343. /**
  344. * 获取直播播放地址
  345. * @param string $stream_name 您用来区别不同推流地址的唯一流名称
  346. * @return string
  347. */
  348. public function getLivePlayUrl(string $stream_name)
  349. {
  350. return "rtmp://{$this->config['play_domain']}/live/".$stream_name;
  351. }
  352. /**
  353. * 获取usersig签名-具体操作
  354. */
  355. public function userSig($user_id)
  356. {
  357. // 获取配置信息
  358. $userSigObj = new GetUserSig($this->config["appid"], $this->config["key"]);
  359. return $userSigObj->genUserSig($user_id);
  360. }
  361. private function post(string $uri, array $params = [])
  362. {
  363. $random = rand(10000000, 99999999);
  364. $userSig = $this->usersig($this->config['identifier']);
  365. return $this->postJson("{$uri}?sdkappid={$this->config['appid']}&identifier={$this->config['identifier']}&usersig={$userSig}&random={$random}&contenttype=json", $params);
  366. }
  367. public function setConfig(array $config): TencentIm
  368. {
  369. $this->config = $config;
  370. return $this;
  371. }
  372. }