226 lines
9.3 KiB
PHP
226 lines
9.3 KiB
PHP
<?php
|
|
defined('BASEPATH') or exit('No direct script access allowed');
|
|
|
|
use GuzzleHttp\Client;
|
|
use GuzzleHttp\Exception\GuzzleException;
|
|
|
|
/**
|
|
* 汽车之家外呼接口(小程序)
|
|
*/
|
|
class CallOutWechat
|
|
{
|
|
const METHOD_GET = 'GET';
|
|
const METHOD_POST = 'POST';
|
|
|
|
protected $baseUrl = 'http://61.144.161.163:28098/crm-api/'; //正式接口地址
|
|
protected $aesKey = 'Crm0123456Abcdef'; //AES秘钥
|
|
protected $iv = 'Crm0123456Abcdef';
|
|
protected $belongPool = 16;
|
|
protected $useName = 'HAOCHEBU';
|
|
protected $password = 'nxoBq2cp@xYC#UZ*5N';
|
|
protected $ci;
|
|
protected $redis;
|
|
private $logDir = 'carHome';
|
|
const LOGIN_URL = 'login'; //登录接口
|
|
const OUT_BOUND_URL = 'call/v1.0/outbound'; //双呼接口
|
|
const BIND_URL = 'call/v1.0/bind'; //单呼接口
|
|
const GET_AUDIO_URL = 'call/v1.0/getAudio?reckeystr=%s'; //获取音频接口
|
|
const SUCCESS_CODE = 200;//接口成功返回码
|
|
|
|
public function __construct()
|
|
{
|
|
$this->ci = &get_instance();
|
|
if (!is_product()) { //测试环境
|
|
$this->baseUrl = 'http://61.144.161.163:18098/crm-api/';
|
|
$this->belongPool = 2;
|
|
$this->useName = 'carhome';
|
|
$this->password = 'Yzy@95511';
|
|
}
|
|
$this->ci->load->library('myResponse');
|
|
$this->redis = &load_cache();
|
|
}
|
|
|
|
/**
|
|
* 获取token
|
|
* @return MyResponse
|
|
*/
|
|
public function getToken()
|
|
{
|
|
try {
|
|
$cKey = "AUTO_OUT_CALL_TOKEN";
|
|
$token = $this->redis->get($cKey);
|
|
if (!$token) {
|
|
$url = $this->baseUrl . self::LOGIN_URL;
|
|
$enPassword = $this->encryption($this->password);
|
|
$data = [
|
|
'username' => $this->useName,
|
|
'password' => $enPassword,
|
|
];
|
|
list($req, $code) = $this->send($url, $data, self::METHOD_POST, false);
|
|
if (!$code || $code != 200) {
|
|
throw new Exception($req);
|
|
}
|
|
$reqData = json_decode($req, true);
|
|
if ($reqData['code'] != self::SUCCESS_CODE) {
|
|
throw new Exception($req['msg'] ?: '获取token失败');
|
|
}
|
|
$expires = (int)($reqData['expires'] / 1000);
|
|
$timeOut = $expires - time();
|
|
$token = $reqData['token'];
|
|
$this->redis->save($cKey, $token, $timeOut);
|
|
}
|
|
return new MyRESPONSE(EXIT_SUCCESS, '提交成功', ['token' => $token]);
|
|
} catch (Exception $e) {
|
|
return new MyResponse(EXIT_ERROR, $e->getMessage());
|
|
}
|
|
}
|
|
|
|
public function outBind($requestId, $orderId, $agentPhoneNo, $customerPhoneNo, $callBackPhoneNo = '', $callbackTime = 5)
|
|
{
|
|
try {
|
|
$url = $this->baseUrl . self::OUT_BOUND_URL;
|
|
$enAgentPhoneNo = $this->encryption($agentPhoneNo);
|
|
$enCustomerPhoneNo = $this->encryption($customerPhoneNo);
|
|
$reqData = [
|
|
'requestId' => $requestId,
|
|
'para' => [
|
|
//订单号(通话唯一标识,外呼结果回传)
|
|
'orderId' => $orderId,
|
|
//agentPhoneNo 为坐席分机,可传坐席接听手机号码或者固话。坐席分机如采用 AES 加密,调用系统传加密后的号码
|
|
'agentPhoneNo' => $enAgentPhoneNo,
|
|
//回呼号码,客户回拨到号码,为空则回到坐席号码,加密规则与坐席分机一致
|
|
'callBackPhoneNo' => $callBackPhoneNo,
|
|
//客户号码,加密规则与坐席分机一致
|
|
'customerPhoneNo' => $enCustomerPhoneNo,
|
|
//坐席工号(无坐席可以为空)
|
|
'agentId' => '',
|
|
//外显类型(根据号码情况传) 0:云中继,固话外显 1:手机号外显
|
|
'displayedPhoneNo' => '0',
|
|
//int 平台分配
|
|
'belongPool' => $this->belongPool,
|
|
//int 回拨绑定时长(分钟)
|
|
'callbackTime' => $callbackTime,
|
|
]
|
|
];
|
|
list($req, $code) = $this->send($url, $reqData, self::METHOD_POST);
|
|
if ($code != 200) {
|
|
throw new Exception($req);
|
|
}
|
|
$reqData = json_decode($req, true);
|
|
if ($reqData['code'] != self::SUCCESS_CODE) {
|
|
throw new Exception($req['msg'] ?: '绑定失败');
|
|
}
|
|
return new MyRESPONSE(EXIT_SUCCESS, '提交成功');
|
|
} catch (Exception $e) {
|
|
return new MyResponse(EXIT_ERROR, $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 单呼绑定
|
|
* @return MyResponse
|
|
*/
|
|
public function bind($requestId, $orderId, $agentPhoneNo, $customerPhoneNo, $callBackPhoneNo = '', $callTime = 5, $callbackTime = 5)
|
|
{
|
|
try {
|
|
$url = $this->baseUrl . self::BIND_URL;
|
|
$enAgentPhoneNo = $this->encryption($agentPhoneNo);
|
|
$enCustomerPhoneNo = $this->encryption($customerPhoneNo);
|
|
$reqData = [
|
|
'requestId' => $requestId,
|
|
'para' => [
|
|
//订单号(通话唯一标识,外呼结果回传)
|
|
'orderId' => $orderId,
|
|
//agentPhoneNo 为坐席分机,可传坐席接听手机号码或者固话。坐席分机如采用 AES 加密,调用系统传加密后的号码
|
|
'agentPhoneNo' => $enAgentPhoneNo,
|
|
//回呼号码,客户回拨到号码,为空则回到坐席号码,加密规则与坐席分机一致
|
|
'callBackPhoneNo' => $callBackPhoneNo,
|
|
//客户号码,加密规则与坐席分机一致
|
|
'customerPhoneNo' => $enCustomerPhoneNo,
|
|
//坐席工号(无坐席可以为空)
|
|
'agentId' => '',
|
|
//外显类型(根据号码情况传) 0:云中继,固话外显 1:手机号外显
|
|
'displayedPhoneNo' => '0',
|
|
//int 平台分配
|
|
'belongPool' => $this->belongPool,
|
|
//int 外呼绑定时长(分钟)
|
|
'callTime' => $callTime,
|
|
//int 回拨绑定时长(分钟)
|
|
'callbackTime' => $callbackTime,
|
|
]
|
|
];
|
|
list($req, $code) = $this->send($url, $reqData, self::METHOD_POST);
|
|
if ($code != 200) {
|
|
throw new Exception($req);
|
|
}
|
|
$reqData = json_decode($req, true);
|
|
if ($reqData['code'] != self::SUCCESS_CODE) {
|
|
throw new Exception($req['msg'] ?: '绑定失败');
|
|
}
|
|
return new MyRESPONSE(EXIT_SUCCESS, '提交成功', $reqData['data']);
|
|
} catch (Exception $e) {
|
|
return new MyResponse(EXIT_ERROR, $e->getMessage());
|
|
}
|
|
}
|
|
|
|
public function getAudio($recKeyStr)
|
|
{
|
|
try {
|
|
$url = $this->baseUrl . sprintf(self::GET_AUDIO_URL, $recKeyStr);
|
|
list($req, $code) = $this->send($url, [], self::METHOD_GET, true, false);
|
|
return new MyRESPONSE(EXIT_SUCCESS, '提交成功', $req);
|
|
} catch (Exception $e) {
|
|
var_dump($e);
|
|
return new MyResponse(EXIT_ERROR, $e->getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 加密
|
|
*
|
|
* @param string $data
|
|
* @return string
|
|
*/
|
|
public function encryption($data)
|
|
{
|
|
$encrypted = openssl_encrypt($data, 'AES-128-CBC', $this->aesKey, OPENSSL_RAW_DATA, $this->iv);
|
|
// 转换为16进制表示
|
|
return bin2hex($encrypted);
|
|
}
|
|
|
|
|
|
public function send($url, $data = [], $type = self::METHOD_GET, $needToken = true, $saveLog = true)
|
|
{
|
|
$logPath = "callOutWechatSend.log";
|
|
try {
|
|
$headers = [
|
|
'Content-Type' => 'application/json'
|
|
];
|
|
if ($needToken) {
|
|
$tokenReq = $this->getToken();
|
|
if (!$tokenReq->isSuccess()) {
|
|
throw new Exception($tokenReq->getMessage());
|
|
}
|
|
$headers['Authorization'] = 'Bearer ' . $tokenReq->getData()['token'];
|
|
}
|
|
$options = [
|
|
'headers' => $headers,
|
|
];
|
|
if ($data) {
|
|
$options['json'] = $data;
|
|
}
|
|
$client = new Client();
|
|
debug_log("请求地址: {$url}", $logPath, $this->logDir);
|
|
debug_log("请求参数:" . json_encode($data, JSON_UNESCAPED_UNICODE), $logPath, $this->logDir);
|
|
$response = $client->request($type, $url, $options);
|
|
$responseContent = $response->getBody()->getContents();
|
|
if ($saveLog) {
|
|
debug_log("返回结果:" . $responseContent, $logPath, $this->logDir);
|
|
}
|
|
return [$responseContent, $response->getStatusCode()];
|
|
} catch (Exception $e) {
|
|
debug_log($e->getMessage(), $logPath, $this->logDir);
|
|
return [$e->getMessage(), 0];
|
|
}
|
|
}
|
|
} |