php 腾讯即时通讯TIM操作类封装

685人浏览   2023-10-23 14:40:52

1.composer添加组件

composer require tencent/tls-sig-api-v2

2.代码

<?php
namespace app\api\service;
use app\api\exception\ApiException;
use app\api\model\UserModel;
use fast\Random;
use Tencent\TLSSigAPIv2;


/**
 * 腾讯即时通讯,只调用create()方法即可
 * Class StepsService
 * @package app\api\service
 */
class TencentIMService extends BaseService
{

    /**
     * 腾讯云 TIM sdkappid
     *
     * @var string
     */
    private $sdkappid;

    /**
     * 腾讯云 TIM key
     *
     * @var string
     */
    private $key;

    public function __construct()
    {
        $this->sdkappid = '腾讯tim应用appid';
        $this->key = '腾讯tim应用key';
        if (empty($this->sdkappid) || empty($this->key)) {
            throw new ApiException('及时通讯参数异常');
        }
    }

    /**
     * 返回请求url
     * @param $servicename
     * @param $command
     * @return string
     * @throws \Exception
     */
    private function getUrl($servicename, $command)
    {
        $ver = 'v4';
        $SDKAppID = $this->sdkappid;
        //管理员账号
        $identifier = 'administrator';
        $usersig = $this->backUserSigFromTim('administrator');
        $random = Random::numeric(32);

        $url = "https://console.tim.qq.com/$ver/$servicename/$command?sdkappid=$SDKAppID&identifier=$identifier&usersig=$usersig&random=$random&contenttype=json";

        return $url;
    }

    /**
     * 返回administrator返回Sig
     * @param $user_id 用户id(唯一)
     * @return string
     * @throws \Exception
     */
    public function backUserSigFromTim($user_id)
    {
        try {
            //服务器端计算获取秘钥
            $api = new TLSSigAPIv2($this->sdkappid, $this->key);
            $sig = $api->genUserSig($user_id, 86400 * 360);
        } catch (\Exception $e) {
            throw new ApiException('获取IM秘钥失败');
        }
        //返回秘钥
        return $sig;
    }


    /**
     * 调用tim官方api,导入用户身份信息
     * @param MUser $user
     * @throws \Exception
     */
    private function importNoToTim($no)
    {
        $url = $this->getUrl('im_open_login_svc', 'account_import');
        $req_data = [
            'Identifier' => $no,
        ];
        curl_post($url, $req_data);
    }


    /**
     * 调用tim官方api,完善用户资料(比如:昵称、头像图片、性别,自定义字段)
     * 当用户完善个人信息时,调用此方法
     * @param MUser $user
     * @throws \Exception
     */
    public function perfectUserDataToTim(UserModel $user)
    {

        $url = $this->getUrl('profile', 'portrait_set');

        $user_id = $user->id;
        $nickname = $user->nickname;
        //$avatar = getImgPath($user->avatar);
        $avatar = $user->avatar;
        $gender = $user->gender;

        $arr = [];

        if (empty($nickname) && empty($avatar)) return;

        if (!empty($nickname)) {
            $arr[] = [
                //昵称
                'Tag'   => 'Tag_Profile_IM_Nick',
                'Value' => $nickname,
            ];
        }

        if (!empty($avatar)) {
            $arr[] = [
                //头像图片地址
                'Tag'   => 'Tag_Profile_IM_Image',
                'Value' => $avatar,
            ];
        }
        if ($gender > 0) {
            if ($gender == 1) {
                //男
                $v = 'Gender_Type_Male';
            } elseif ($gender == 2) {
                //女
                $v = 'Gender_Type_Female';
            }
            $arr[] = [
                'Tag'   => 'Tag_Profile_IM_Gender',
                'Value' => $v,
            ];
        }

        if (count($arr) > 0) {
            $req_data = [
                'From_Account' => $user_id,
                'ProfileItem'  => $arr,
            ];
            curl_post($url, $req_data);
        }
    }


    /**
     * 调用tim官方api,获取之前完善的用户资料(包括自定义字段)
     * @param string no 用户唯一编码
     * @return array user_no gender tim_nickname tim_avatar tim_user_sig
     * @throws \Exception
     */
    public function getUserDataFromTim($no)
    {
        $url = $this->getUrl('profile', 'portrait_get');
        $req_data = [

            'To_Account' => [$no],
            'TagList'    => [
                //昵称
                'Tag_Profile_IM_Nick',
                //头像
                'Tag_Profile_IM_Image',
                //性别
                'Tag_Profile_IM_Gender',
            ],
        ];

        $result = curl_post($url, $req_data);

        $tim_nickname = '';
        $tim_avatar = '';
        $gender = 0;

        $result = json_decode($result, true);
        if ($result['ActionStatus'] == 'OK' && intval($result['ErrorCode']) === 0) {
            $arr = collect($result['UserProfileItem'][0]['ProfileItem'])->pluck('Value', 'Tag')->toArray();
            foreach ($arr as $k => $v) {
                if ($k == 'Tag_Profile_IM_Nick') {
                    $tim_nickname = $v;
                } elseif ($k == 'Tag_Profile_IM_Image') {
                    $tim_avatar = $v;
                } elseif ($k == 'Tag_Profile_IM_Gender') {
                    if ($v == 'Gender_Type_Unknown') {
                        //未设置
                        $gender = 0;
                    } elseif ($v == 'Gender_Type_Female') {
                        //女
                        $gender = 2;
                    } elseif ($v == 'Gender_Type_Male') {
                        //男
                        $gender = 1;
                    }
                }
            }
        }

        $demo = [
            'no'           => $no,
            'gender'       => $gender,
            'tim_nickname' => $tim_nickname,
            'tim_avatar'   => $tim_avatar,
        ];

        //https://cloud.tencent.com/document/product/269/1639
        return $demo;
    }


    /**
     * 创建一个腾讯云 IM 服务账号
     *
     * @param string $no 账号
     * @param int $expire 有效期(秒)
     * @return string
     * @throws FailedException
     */
    public function create(string $no, int $expire = 3600 * 24 * 365 * 20)
    {
        try {
            // 服务器端计算获取秘钥
            $api = new TLSSigAPIv2($this->sdkappid, $this->key);
            $sig = $api->genUserSig($no, $expire);

            $this->importNoToTim($no);

        } catch (\Exception $e) {
            print_r($e->getMessage());
            throw new ApiException('获取IM秘钥失败');
        }

        return $sig;
    }
}

相关推荐