Skip to content

Instantly share code, notes, and snippets.

@jjsty1e
Created April 7, 2017 09:43
Show Gist options
  • Save jjsty1e/39798d5a05112021897e129d6045392d to your computer and use it in GitHub Desktop.
Save jjsty1e/39798d5a05112021897e129d6045392d to your computer and use it in GitHub Desktop.
ucpaas callback
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2017-03-31
* Time: 10:44
*/
namespace AppBundle\Services;
use AppBundle\Entity\PayOrder;
use AppBundle\Entity\UcpaasClient;
use AppBundle\Entity\User;
use AppBundle\Repository\PayOrderPstnRepository;
use Doctrine\ORM\EntityManager;
use GuzzleHttp\Client;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* 使用接口拨打电话
*
* 在本类中 get开头的方法查询数据库,query开头的方法是查询第三方服务,即云之讯
*
* 根据业务进行封装,比如订单电话 `$this->payOrderCall()`, 需求电话 `$this->demandCall()`
*
* Class UcpaasPstn
* @package AppBundle\Services
*/
class UcpaasPstn
{
/**
* @var ContainerInterface $container
*/
private $container;
/**
* @var mixed 应用id
*/
private $appId;
/**
* @var string
*/
private $authorization;
/**
* @var string
*/
private $version;
/**
* @var string
*/
private $token;
/**
* @var string
*/
private $accountSid;
/**
* @var false|string
*/
private $nowTime;
/**
* @var Client
*/
private $client;
/**
* @return \Doctrine\Bundle\DoctrineBundle\Registry
*/
private function getDoctrine()
{
return $this->container->get('doctrine');
}
/**
* @param $function
* @param $operation
* @return string
*/
private function buildUri($function, $operation)
{
if (!empty($operation)) {
$operation = '/' . $operation;
}
return sprintf('/%s/Accounts/%s/%s%s?sig=%s',
$this->version,
$this->accountSid,
$function,
$operation,
$this->sigParameter
);
}
/**
* @param $bodyLength
* @return array
*/
private function buildHeader($bodyLength)
{
return [
'Accept' => 'application/json',
'Content-Type' => 'application/json;charset=utf-8',
'Authorization' => $this->authorization,
'Content-Length' => $bodyLength
];
}
/**
* @param $headers
* @param $body
* @return array
*/
private function buildRequestOption($headers, $body)
{
return [
'headers' => $headers,
'body' => $body
];
}
/**
* @param $function
* @param $operation
* @param $body
* @return array
*/
private function sendRequest($function, $operation, $body, $method = 'post')
{
if ($method == 'get') {
$queryString = http_build_query($body);
$headers = $this->buildHeader(0);
$option = $this->buildRequestOption($headers, '');
$uri = $this->buildUri($function, $operation);
$uri .= '&' . $queryString;
} else {
$body = json_encode($body);
$headers = $this->buildHeader(mb_strlen($body));
$option = $this->buildRequestOption($headers, $body);
$uri = $this->buildUri($function, $operation);
}
$response = $this->client->request($method, $uri, $option);
$response = json_decode($response->getBody()->getContents(), true);
return $response;
}
/**
* @return \AppBundle\Repository\UcpaasClientRepository
*/
private function getUcpaasClientRepository()
{
static $repository;
if (!$repository) {
$repository = $this->container->get('doctrine')->getRepository('AppBundle:UcpaasClient');
}
return $repository;
}
/**
*
* UcpaasPstn constructor.
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->version = '2014-06-30';
$this->appId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$this->accountSid = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$this->token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$this->nowTime = date('YmdHis') + 7200;
$this->authorization = trim(base64_encode($this->accountSid .':' . $this->nowTime));
$this->sigParameter = strtoupper(md5($this->accountSid . $this->token . $this->nowTime));
$this->client = new Client([
'base_uri' => 'https://api.ucpaas.com'
]);
}
/**
* 回拨电话
*
* @param $fromMobile string 主叫方的ClientId
* @param $toMobile string 被叫方的手机号码
* @param $userData string 自定义数据
* @param $maxAllowTime integer 通话最大时长,单位秒
* @return array
*/
private function call($fromMobile, $toMobile, $userData = '', $maxAllowTime = 6000)
{
$userRepository = $this->container->get('doctrine')->getRepository('AppBundle:User');
$fromUser = $userRepository->getUserByMobile($fromMobile);
$fromClient = $this->getOrCreateClient($fromUser->getMobile(), $fromUser->getUsername(), $fromUser->getId());
$body = [
'callback' => [
'appId' => $this->appId,
'fromClient' => (string) $fromClient->getClientId(),
'to' => (string) $toMobile,
'fromSerNum' => '',
'toSerNum' => '',
'record' => '1',
'userData' => (string) $userData,
'maxallowtime' => (string) $maxAllowTime
]
];
$response = $this->sendRequest('Calls', 'callBack', $body);
if ($response['resp']['respCode'] !== '000000') {
throw new \Exception(json_encode($response));
}
return [
'callId' => $response['resp']['callback']['callId'],
'requestId' => $userData,
'srcDisplayNum' => $body['fromSerNum'],
'dstDisplayNum' => $body['toSerNum']
];
}
/**
* 约谈订单电话拨打
*
* @param User $src
* @param User $dst
* @param PayOrder $order
* @param int $maxAllowTime 此处单位是分钟
* @return object
* @throws \Exception
*/
public function payOrderCall(User $src, User $dst, PayOrder $order, $maxAllowTime)
{
/**
* @var EntityManager $em
*/
$em = $this->getDoctrine()->getManager();
/**
* @var PayOrderPstnRepository $pstnRepository
*/
$pstnRepository = $this->getDoctrine()->getRepository('AppBundle:PayOrderPstn');
try {
$em->beginTransaction();
$pstn = $pstnRepository->create($src, $dst, $order);
$userData = 'payOrderPstnId:' . $pstn->getId();
$response = $this->call($src->getMobile(), $dst->getMobile(), $userData, $maxAllowTime * 60);
$pstnRepository->updatePstnCallId($pstn, $response['callId']);
$em->commit();
} catch (\Exception $exception) {
$em->rollback();
throw $exception;
}
return json_decode(json_encode($response));
}
/**
* 需求电话拨打
*
* @param $fromMobile
* @param $toMobile
* @param int $pstnId
* @param int $maxAllowTime 通话时长限制,单位:秒,默认100分钟
* @return array
*/
public function demandCall($fromMobile, $toMobile, $pstnId, $maxAllowTime = 6000)
{
return $this->call($fromMobile, $toMobile, 'demand:'.$pstnId, $maxAllowTime);
}
/**
* 获取或者创建Client
*
* @return UcpaasClient
*/
public function getOrCreateClient($mobile, $username, $userId)
{
$fromClient = $this->getUcpaasClientRepository()->getClientByMobile($mobile);
if (!$fromClient) {
$fromClient = $this->createClientId($mobile, $username, $userId);
}
return $fromClient;
}
/**
* 创建一个Client,并保存在本地数据库中
*
* 每一个Client对应系统中的一个用户
*
* @param $mobile
* @param $username
* @return UcpaasClient
*/
public function createClientId($mobile, $username, $userId)
{
$response = $this->sendRequest('Clients', '', [
'client' => [
'friendlyName' => $username,
'appId' => $this->appId,
'clientType' => '0',
'charge' => '0',
'mobile' => (string) $mobile
]
]);
$clientId = '';
$clientPwd = '';
$respCode = $response['resp']['respCode'];
// 已经绑定过,那么通过接口获取clientId
if ($respCode === '103114') {
list($clientId, $clientPwd) = $this->queryClientByMobile($mobile);
} elseif ($respCode !== '000000') {
// 其他错误,暂时直接抛出
throw new \Exception(json_encode($response));
}
$clientId = $clientId ?: $response['resp']['client']['clientNumber'];
$clientPwd = $clientPwd ?: $response['resp']['client']['clientPwd'];
$ucpaasClient = $this->getUcpaasClientRepository()->create($userId, $mobile, $clientId, $clientPwd);
return $ucpaasClient;
}
/**
* 查询远程ClientId
*
* @param $mobile
* @return array
* @throws \Exception
*/
public function queryClientByMobile($mobile)
{
$response = $this->sendRequest('ClientsByMobile', '', [
'appId' => $this->appId,
'mobile' => $mobile
], 'get');
$respCode = $response['resp']['respCode'];
if ($respCode !== '000000') {
throw new \Exception(json_encode($response));
}
$clientId = $response['resp']['client']['clientNumber'];
$clientPwd = $response['resp']['client']['clientPwd'];
return [$clientId, $clientPwd];
}
public function queryRecord($url)
{
$this->buildHeader('');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment