绑定
更新时间:2023-09-07
接口描述
AXB绑定接口可以实现在一对一的场景中的号码隐私保护,在使用该接口前需要明确AXB三者角色,比如在外卖的场景中,A可以是用户的联系方式,X是中间隐私号码,B可以是外卖员的联系方式。在绑定成功后,A或者B拨打X号码都可以找到对方,而双方显示的都是这个X号码。
请求结构
Plain Text
1POST /cloud/api/v{version}/axb/binding HTTP/1.1
2Host: pns.baidubce.com
3Content-Type: application/json; charset=utf-8
4x-bce-date: 2019-10-30T10:55:26Z
5Authorization: authorization string
6{
7 "telA": "A号码",
8 "telB": "B号码",
9 "areaCode": "需要X号码所属区号",
10 "record": "是否录音,1:录音;0:不录音",
11 "expiration": "绑定失效时间(秒)",
12 "customer": "业务侧随传数据,可以是json和任意字符串"
13}
请求域名
参考API文档中的服务域名
请求头域
除公共头域外,无其它特殊头域。
请求参数
参数名称 | 类型 | 是否必须 | 参数位置 | 描述 |
---|---|---|---|---|
version | String | 是 | URL参数 | API版本号,参考通用说明中的API版本号,目前为1 |
telA | String | 是 | RequestBody参数 | 主叫号码 格式:手机或固话座机 |
telB | String | 是 | RequestBody参数 | 被叫号码 格式:手机或固话座机 |
telX | String | 否 | RequestBody参数 | 中间X号码,不传平台自动分配申请的X号码 |
areaCode | String | 是 | RequestBody参数 | 需要的 X 号码所属于区号 |
expiration | String | 是 | RequestBody参数 | 绑定关系有效时长,必须大于0,单位:秒 |
record | String | 是 | RequestBody参数 | 录音状态record,1-需要录音;0-不需要录音;供应商要求,此处必须为1 |
customer | Json | 否 | RequestBody参数 | 业务侧随传数据,可以是json和任意字符串 |
forceRandomX | Json | 否 | RequestBody参数 | 值:1,当手机号的运营商只有为移动的时候才必传,其他情况不可以传 |
响应头域
除了公共头域外,如果发生网关错误,可能头域中存在以下特殊头域:
参数名 | 类型 | 说明 |
---|---|---|
X-Bce-Error-Code | String | 表示异常情况下的错误码 |
X-Bce-Error-Message | String | 表示异常情况下的错误信息 |
响应参数
参数名称 | 类型 | 描述 |
---|---|---|
code | String | 平台返回的错误码,0表示成功 |
msg | String | 平台返回的错误消息 |
data | Json | 平台返回的响应数据 |
绑定操作成功后的响应数据data:
参数名称 | 类型 | 描述 |
---|---|---|
bindId | String | AXB绑定ID |
telX | String | AXB绑定X号码 |
错误码
请参照前文的网关错误码和平台错误码。
请求示例
Plain Text
1POST /cloud/api/v{version}/axb/binding HTTP/1.1
2Host: pns.baidubce.com
3Content-Type: application/json; charset=utf-8
4x-bce-date: 2019-10-30T10:55:26Z
5Authorization: bce-auth-v1/318857a8f08b11e9845ca7e54775a0c2/2019-10-17T03:07:21Z/1800/host/212eef8cfe1ac94be56c4afedb9360bba621ef646c3c8288971d36801d70501a
6{
7 "telA": "17600901081",
8 "telB": "13911528327",
9 "areaCode": "10",
10 "record": "1",
11 "expiration": "600",
12 "customer": ""
13}
PHP代码示例
Plain Text
1<?php
2
3
4function gmtime()
5{
6 return (time() - date('Z'));
7}
8
9function debug($k,$v){
10
11 echo "\n======={$k}======\n";
12 var_export($v);
13
14 echo "\n=====end====\n";
15}
16
17/**
18 * Http Client
19 */
20class AipHttpClient{
21
22 /**
23 * HttpClient
24 * @param array $headers HTTP header
25 */
26 public function __construct($headers=array()){
27 $this->headers = $this->buildHeaders($headers);
28 $this->connectTimeout = 60000;
29 $this->socketTimeout = 60000;
30 $this->conf = array();
31
32 }
33
34 /**
35 * 连接超时
36 * @param int $ms 毫秒
37 */
38 public function setConnectionTimeoutInMillis($ms){
39 $this->connectTimeout = $ms;
40 }
41
42 /**
43 * 响应超时
44 * @param int $ms 毫秒
45 */
46 public function setSocketTimeoutInMillis($ms){
47 $this->socketTimeout = $ms;
48 }
49
50 /**
51 * 配置
52 * @param array $conf
53 */
54 public function setConf($conf){
55 $this->conf = $conf;
56 }
57
58 /**
59 * 请求预处理
60 * @param resource $ch
61 */
62 public function prepare($ch){
63 foreach($this->conf as $key => $value){
64 curl_setopt($ch, $key, $value);
65 }
66 }
67
68 /**
69 * @param string $url
70 * @param array $data HTTP POST BODY
71 * @param array $param HTTP URL
72 * @param array $headers HTTP header
73 * @return array
74 */
75 public function post($url, $data=array(), $params=array(), $headers=array()){
76 $url = $this->buildUrl($url, $params);
77 $headers = array_merge($this->headers, $this->buildHeaders($headers));
78 debug('headers',$headers);
79 debug('body',$data);
80
81 $ch = curl_init();
82
83 $this->prepare($ch);
84 curl_setopt($ch, CURLOPT_URL, $url);
85 curl_setopt($ch, CURLOPT_POST, 1);
86 curl_setopt($ch, CURLOPT_HEADER, false);
87 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
88 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
89 curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
90 curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($data) ? http_build_query($data) : $data);
91 curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->socketTimeout);
92 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $this->connectTimeout);
93 curl_setopt($ch, CURLOPT_VERBOSE, true);
94 curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
95 echo "Curl options:\n";
96 var_dump(curl_getinfo($ch));
97 $content = curl_exec($ch);
98 echo "Response content:\n";
99 var_dump($content); // 输出返回的内容
100 $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
101
102 if($code === 0){
103 throw new Exception(curl_error($ch));
104 }
105
106 curl_close($ch);
107
108
109 return array(
110 'code' => $code,
111 'content' => $content,
112 );
113 }
114
115
116 /**
117 * @param string $url
118 * @param array $param HTTP URL
119 * @param array $headers HTTP header
120 * @return array
121 */
122 public function get($url, $params=array(), $headers=array()){
123 $url = $this->buildUrl($url, $params);
124 $headers = array_merge($this->headers, $this->buildHeaders($headers));
125
126 $ch = curl_init();
127 $this->prepare($ch);
128 curl_setopt($ch, CURLOPT_URL, $url);
129 curl_setopt($ch, CURLOPT_HEADER, false);
130 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
131 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
132 curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
133 curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->socketTimeout);
134 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $this->connectTimeout);
135 $content = curl_exec($ch);
136 $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
137
138 if($code === 0){
139 throw new Exception(curl_error($ch));
140 }
141
142 curl_close($ch);
143 return array(
144 'code' => $code,
145 'content' => $content,
146 );
147 }
148
149 /**
150 * 构造 header
151 * @param array $headers
152 * @return array
153 */
154 private function buildHeaders($headers){
155 $result = array();
156 foreach($headers as $k => $v){
157 $result[] = sprintf('%s:%s', $k, $v);
158 }
159 return $result;
160 }
161
162 /**
163 *
164 * @param string $url
165 * @param array $params 参数
166 * @return string
167 */
168 private function buildUrl($url, $params){
169 if(!empty($params)){
170 $str = http_build_query($params);
171 return $url . (strpos($url, '?') === false ? '?' : '&') . $str;
172 }else{
173 return $url;
174 }
175 }
176}
177
178
179
180/**
181 *
182 */
183class BaiDuYun
184{
185 /**
186 * $conf=['access'=>'xxx','secret'=>'xxx'] https://cloud.baidu.com/doc/Reference/s/9jwvz2egb
187 *
188 *
189 * @method __construct
190 *
191 * @param array $conf [description]
192 */
193 function __construct($conf=[])
194 {
195 $this->conf=$conf;
196 $this->client= new AipHttpClient([
197 'Content-Type'=>'application/json; charset=utf-8',
198
199 ]);
200
201 $this->addtionHeaders=[ 'x-bce-date'=> date('Y-m-d\TH:i:s\Z',gmtime())];
202
203 $this->version=1;
204 $this->APIBASE="https://pns.baidubce.com";
205 }
206
207
208
209
210 private function auth($Method,$api){
211 return $this->authStringPrefix()."/host;x-bce-date/".$this->Signature($Method,$api);
212 }
213 private function Signature($Method,$api){
214
215 $c=$this->CanonicalRequest($Method,$api);
216 $sk=$this->SigningKey();
217 debug("CanonicalRequest",$c);
218 debug("SigningKey",$sk);
219
220 return self::sha256($sk,$c);
221
222 }
223
224 private function SigningKey(){
225
226
227 $s= self::sha256($this->conf['secret'],trim($this->authStringPrefix()));
228
229 return $s;
230
231 }
232 static function sha256($a,$b){
233
234
235 return hash_hmac('sha256',$b,$a);
236
237 }
238
239
240 private function authStringPrefix(){
241
242 $t= date('Y-m-d\TH:i:s\Z',gmtime());
243 // $t='2019-12-03T18:03:23Z';
244
245 return "bce-auth-v1/{$this->conf['access']}/{$t}/1800";
246 }
247
248 private function CanonicalRequest($Method,$api){
249
250 $data[]=$Method;
251 $u=parse_url($api);
252 $data[]=str_replace('%2F','/',urlencode($u['path']));
253 if(isset($u['query'])){
254 parse_str($u['query'],$qs);
255 ksort($qs);
256 foreach ($qs as $k => $v) {
257 $q[]=urlencode($k).'='.urlencode($v);
258 }
259 $data[]= implode("&", $q);
260 }else{
261 $data[]='';
262 }
263
264 $a=["host:".$u['host'],];
265 foreach ( $this->addtionHeaders as $k => $v) {
266
267 $a[]="{$k}:".urlencode($v);
268 }
269 $data[]=implode("\n", $a);
270 return implode("\n", $data);
271
272 }
273
274
275 public function Post($api,$data=null){
276 $api=$this->APIBASE.$api;
277 var_dump($api);
278 $this->addtionHeaders["Authorization"]=$this->auth("POST",$api);
279 $res=$this->client->post($api,$data?json_encode($data):null,[],$this->addtionHeaders);
280 if($res['code']!=200){
281 throw new \Exception($res['content'], $res['code']);
282 }
283 return json_decode( $res['content'],1);
284
285 }
286
287 /**
288 * [AxbBinding description] 百度云PNS-AXB模式绑定接口
289 *
290 * @method AxbBinding
291 * @param telA String 是 RequestBody参数 主叫号码 格式:手机或固话座机
292 * @param telB String 是 RequestBody参数 被叫号码 格式:手机或固话座机
293 * @param telX String 否 RequestBody参数 中间X号码,不传平台自动分配申请的X号码
294 * @param areaCode String 是 RequestBody参数 需要的 X 号码所属于区号
295 * @param expiration String 是 RequestBody参数 绑定关系有效时长,必须大于0
296 * @param record String 是 RequestBody参数 录音状态record,1-需要录音;0-不需要录音
297 * @param customer Json 否 RequestBody参数 业务侧随传数据,可以是json和任意字符串
298 **/
299 public function AxbBinding($tela,$telb,$telx="",$expiration=1800,$areaCode="10",$record=1,$customer=''){
300
301 $api="/cloud/api/v{$this->version}/axb/binding";
302 $data=[
303 "telA"=>$tela,
304 "telB"=>$telb,
305 "areaCode"=>$areaCode,
306 "record"=>$record,
307 "expiration"=>$expiration,
308 "customer"=>$customer
309 ];
310
311 if($telx){
312 $data['telX']= $telx;
313 }
314 return $this->Post($api,$data);
315
316 }
317
318
319 /**
320 * [AxbUnbinding description] 百度云PNS-AXB模式解绑接口
321 * 参数名称 类型 是否必须 参数位置 描述
322 * @param version String 是 URL参数 API版本号
323 * @param bindId String 是 URL参数 绑定ID
324 *
325 * @method AxbUnbinding
326 *
327 * @param [type] $bindId [description]
328 */
329 public function AxbUnbinding($bindId){
330
331 $api="/cloud/api/v{$this->version}/axb/unbinding/{$bindId}";
332 return $this->Post($api);
333
334 }
335
336 /**
337 * [AxBinding description] 百度云PNS-AX模式绑定接口
338 *
339 * @method AxBinding
340 * @param telA String 是 RequestBody参数 主叫号码 格式:手机或固话座机
341 * @param telX String 否 RequestBody参数 中间X号码,不传平台自动分配申请的X号码
342 * @param areaCode String 是 RequestBody参数 需要的 X 号码所属于区号
343 * @param expiration String 是 RequestBody参数 绑定关系有效时长,必须大于0
344 * @param record String 是 RequestBody参数 录音状态record,1-需要录音;0-不需要录音
345 * @param customer Json 否 RequestBody参数 业务侧随传数据,可以是json和任意字符串
346 **/
347 public function AxBinding($tela,$telx="",$expiration=1800,$areaCode="10",$record=1,$customer=''){
348
349 $api="/cloud/api/v{$this->version}/ax/binding";
350 $data=[
351 "telA"=>$tela,
352 "areaCode"=>$areaCode,
353 "record"=>$record,
354 "expiration"=>$expiration,
355 "customer"=>$customer
356 ];
357
358 if($telx){
359 $data['telX']= $telx;
360 }
361 return $this->Post($api,$data);
362
363 }
364
365 /**
366 * [AxUnbinding description] 百度云PNS-AX模式解绑接口
367 * 参数名称 类型 是否必须 参数位置 描述
368 * @param version String 是 URL参数 API版本号
369 * @param bindId String 是 URL参数 绑定ID
370 *
371 * @method AxUnbinding
372 *
373 * @param [type] $bindId [description]
374 */
375 public function AxUnbinding($bindId){
376
377 $api="/cloud/api/v{$this->version}/ax/unbinding/{$bindId}";
378 return $this->Post($api);
379
380 }
381}
382
383
384//demo access: 用户ak信息 secret: 用户sk信息
385$conf=['access'=>'您的ak','secret'=>'您的sk'];
386$bd = new BaiDuYun($conf);
387
388//$bd->AxbBinding("18011112222","18911112222");
389//$bd->AxBinding("18620084369"); // 绑定
390$bd->AxUnBinding("37062165846201367xx"); //解绑
响应示例
Plain Text
1HTTP/1.1 200 OK
2Content-Type: application/json;charset=UTF-8
3Date: Wed, 08 Jul 2019 03:28:11 GMT
4x-bce-request-id: d8752367-38e8-45e4-b4c7-e53be3137ce5
5X-Bce-Gateway-Region: BJ
6{
7 "code":"0",
8 "msg":"成功",
9 "data":{
10 "bindId":"1535822891021508888",
11 "telX":"17810301111"
12 }
13}