123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- <?php
- namespace App\Traits;
- use App\Exceptions\TencentImAccountException;
- use App\Exceptions\TencentImException;
- use App\Services\RedisService;
- use GuzzleHttp\Client;
- use Illuminate\Support\Arr;
- use Tencent\TLSSigAPIv2;
- trait TencentIm
- {
- protected $restApiName;
- protected $identifier;
- protected $TENCENT_IM_USER_SIG_EXPIRE = 86400 * 180; //签名过期时间,单位秒,默认 180 天(同步SDK)
- protected $TENCENT_IM_BASE_API_HOST = 'https://console.tim.qq.com/'; //基础请求接口域名
- protected $REST_APT_MAX_ITEM = 100;
- /**
- * 验证是否配置完善
- * @return bool
- * @throws TencentImException
- */
- static public function verifyConfig()
- {
- if (!config('im.sdk_app_id') || !config('im.identifier') || !config('im.secret_key')) {
- throw new TencentImException('未配置完善,请检查!');
- }
- return true;
- }
- /**
- * 获取配置
- * @return array
- * @throws TencentImException
- */
- static public function getTencentImConfig()
- {
- self::verifyConfig();
- return [
- 'sdk_app_id' => config('im.sdk_app_id'),
- 'secret_key' => config('im.secret_key'),
- 'identifier' => config('im.identifier')
- ];
- }
- /**
- * 获取签名
- * @param string $identifier
- * @return string
- * @throws TencentImException
- */
- public function getUserSig(string $identifier): string
- {
- if (RedisService::redis()->exists('tencentIm:userSign:' . $identifier)) {
- return RedisService::redis()->get('tencentIm:userSign:' . $identifier);
- }
- $userSig = self::generateUserSig($identifier);
- RedisService::redis()->SETEX('tencentIm:userSign:' . $identifier, $this->TENCENT_IM_USER_SIG_EXPIRE - 10, $userSig);
- return $userSig;
- }
- /**
- * 生成签名
- * @param string $identifier
- * @param float|int $expire
- * @return string
- * @throws TencentImException
- */
- public function generateUserSig(string $identifier, $expire = null)
- {
- $imConfig = self::getTencentImConfig();
- $tlsApi = new TLSSigAPIv2(Arr::get($imConfig, 'sdk_app_id'), Arr::get($imConfig, 'secret_key'));
- $userSig = $tlsApi->genSig($identifier, $expire ?? $this->TENCENT_IM_USER_SIG_EXPIRE);
- return $userSig;
- }
- /**
- * 获取IM接口请求公共参数
- * @return string
- * @throws TencentImException
- */
- public function generateTencentImRestApiPublicParams()
- {
- self::verifyConfig();
- $params = [
- 'sdkappid' => config('im.sdk_app_id'),
- 'identifier' => config('im.identifier'),
- 'usersig' => $this->getUserSig(config('im.identifier')),
- 'random' => rand(0, 4294967295),
- 'contenttype' => 'json'
- ];
- return http_build_query($params);
- }
- /**
- * 获取腾讯IM RESTAPI 基础 HOST
- * @return string
- * @throws TencentImException
- */
- public function getTencentImRestApiBaseHost()
- {
- if (is_null($this->restApiName)) {
- throw new TencentImException('未设置请求接口');
- }
- return $this->TENCENT_IM_BASE_API_HOST . $this->restApiName . '?' . $this->generateTencentImRestApiPublicParams();
- }
- /**
- * 检测单次api请求是否超过上限
- * @param array $accounts
- * @return bool
- * @throws TencentImAccountException
- */
- public function verifyRestApiMaxItem(array $accounts)
- {
- if (count($accounts) > $this->REST_APT_MAX_ITEM) {
- throw new TencentImAccountException('单次最多处理100个用户名');
- }
- return true;
- }
- /**
- * 请求接口
- * @param string $requestUrl
- * @param array $apiData
- * @param string $method
- * @param string $paramsType
- * @return \Psr\Http\Message\ResponseInterface
- * @throws \GuzzleHttp\Exception\GuzzleException
- */
- public function requestApi(string $requestUrl, array $apiData, string $paramsType = 'json', string $method = 'POST')
- {
- $client = new Client();
- if ($paramsType === 'json') {
- $apiData = json_encode($apiData);
- }
- $response = $client->request($method, $requestUrl, [
- 'headers' => ['Accept' => 'multipart/json'],
- 'body' => $apiData,
- ]);
- $result = json_decode($response->getBody(), true);
- return $result;
- }
- /**
- * 验证接口返回
- * @param $apiResult
- * @return bool
- * @throws TencentImException
- */
- static public function verifyApiResult($apiResult)
- {
- if (!is_array($apiResult)) {
- throw new TencentImException('IM 请求失败');
- }
- if (count(array_diff(['ActionStatus', 'ErrorCode', 'ErrorInfo'], array_keys($apiResult))) > 0) {
- throw new TencentImException('IM 接口返回异常');
- }
- if (($apiResult['ActionStatus'] != 'OK') || ($apiResult['ErrorCode'] != 0)) {
- throw new TencentImException('操作失败: ' . $apiResult['ErrorInfo']);
- }
- return true;
- }
- }
|