PHP 微信公众号之客服完整讲解
//获取access_token
private static function get_access_token($app_id)
{
$getAuthorizerInfo = wx_auth::getAuthorizerInfo($app_id);
$access_token = wx_auth::getAuthorizerAccessToken($app_id, $getAuthorizerInfo['authorization_info']['authorizer_refresh_token']);
return $access_token;
} //客服回复用户信息
public static function reply_customer($open_id, $content)
{
$app_id = WxUser::getWxUserInfoByOpenId($open_id)['app_id']; $data = '{"touser":"' . $open_id . '","msgtype":"text","text":{"content":"' . $content . '"}}';
$access_token = self::get_access_token($app_id);
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" . $access_token;
$result = wx_tools::postCurl($url, $data);
return json_decode($result, true); } //获取所有客服账号
public static function get_customer_account_list($app_id)
{
$access_token = self::get_access_token($app_id); $url = "https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=" . $access_token;
$result = wx_tools::getCurl($url);
return json_decode($result, true);
} //邀请微信号到客服
public static function invite_customer_account($kf_account, $invite_wx, $app_id)
{
$access_token = self::get_access_token($app_id); $data = '{"kf_account":"' . $kf_account . '","invite_wx":"' . $invite_wx . '"}';
$url = "https://api.weixin.qq.com/customservice/kfaccount/inviteworker?access_token=" . $access_token;
$result = wx_tools::postCurl($url, $data);
return json_decode($result, true);
} //添加客服账号
public static function add_customer_account($kf_account, $nickname, $password, $app_id)
{
$access_token = self::get_access_token($app_id); $data = '{"kf_account":"' . $kf_account . '","nickname":"' . $nickname . '","text":"' . $password . '"}';
$url = "https://api.weixin.qq.com/customservice/kfaccount/add?access_token=" . $access_token;
$result = wx_tools::postCurl($url, $data);
return json_decode($result, true);
} //设置微信头像
public static function upload_head_img($app_id, $kf_account, $file)
{
$access_token = self::get_access_token($app_id); $url = 'https://api.weixin.qq.com/customservice/kfaccount/uploadheadimg?access_token=' . $access_token . '&kf_account=' . $kf_account;
$tmp_name = $file['tmp_name'];
$type = $file['type'];
$path = $file['name']; $result = wx_tools::curl_post_file($url, $tmp_name, $type, $path);
return $result;
} //修改客服账号
public static function modify_customer_account($kf_account, $nickname, $password, $app_id)
{
$access_token = self::get_access_token($app_id); $data = '{"kf_account":"' . $kf_account . '","nickname":"' . $nickname . '","text":"' . $password . '"}';
$url = "https://api.weixin.qq.com/customservice/kfaccount/update?access_token=" . $access_token;
$result = wx_tools::postCurl($url, $data);
return json_decode($result, true);
} //删除客服帐号
public static function remove_customer_account($kf_account, $app_id)
{
$access_token = self::get_access_token($app_id); $data = '{"kf_account":"' . $kf_account . '"}';
$url = "https://api.weixin.qq.com/customservice/kfaccount/del?access_token=" . $access_token;
$result = wx_tools::postCurl($url, $data);
return json_decode($result, true);
} //获取用户与客服之间的聊天记录 public static function get_customer_service_chat_record($starttime, $endtime, $msgid, $number, $app_id)
{
$access_token = self::get_access_token($app_id); $data = '{"starttime":"' . $starttime . '","endtime":"' . $endtime . '","msgid":"' . $msgid . '","number":"' . $number . '"}';
$url = "https://api.weixin.qq.com/customservice/msgrecord/getmsglist?access_token=" . $access_token;
$result = wx_tools::postCurl($url, $data);
return json_decode($result, true);
}
我自己的wx_tools 文件
/**
* 以post方式提交xml到对应的接口url
* @param string $url 提交地址
* @param string $param 需要post的xml数据
* @param bool $file 是否上传文件
* @param bool|array $cert 是否需要证书,默认不需要 如果是数组代表有证书地址 请按以下格式 array('cert' => 'cert.pem', 'key' => 'key.pem', 'rootca' => 'rootca.pem');
* @param int $second
* @return mixed
*/
public static function postCurl($url, $param, $file = false, $cert = false, $second = 30)
{
$curl = curl_init();
//设置超时
curl_setopt($curl, CURLOPT_TIMEOUT, $second);
if (stripos($url, "https://") !== FALSE) {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
}
if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) {
$is_file = true;
} else {
$is_file = false;
if (defined('CURLOPT_SAFE_UPLOAD')) {
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, false);
}
}
if (is_string($param)) {
$str_post = $param;
} elseif ($file) {
if ($is_file) {
foreach ($param as $key => $val) {
if (substr($val, 0, 1) == '@') {
$param[$key] = new \CURLFile(realpath(substr($val, 1)));
}
}
}
$str_post = $param;
} else {
$post = array();
foreach ($param as $key => $val) {
$post[] = $key . "=" . urlencode($val);
}
$str_post = join("&", $post);
} //设置证书 todo 未验证
if (is_array($cert)) {
//请确保您的libcurl版本是否支持双向认证,版本高于7.20.1 使用证书:cert 与 key 分别属于两个.pem文件
curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($curl, CURLOPT_SSLCERT, $cert['cert']);
curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($curl, CURLOPT_SSLKEY, $cert['key']);
//红包使用
if (empty($cert['rootca'])) {
curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($curl, CURLOPT_CAINFO, $cert['rootca']);
}
} curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $str_post);
$content = curl_exec($curl);
$status = curl_getinfo($curl);
if (intval($status["http_code"]) == 200) {
curl_close($curl);
// ApiLog::setMessage(\Yii::$app->session->get('request_base_api_log_id'),['url' => $url, 'message'=> $content], 1);
return $content;
} else {
$error = curl_errno($curl);
curl_close($curl);
// $this->err_code = $error;
// $this->err_msg = $this->curl_error[$error];
// ApiLog::setMessage(\Yii::$app->session->get('request_base_api_log_id'),['url' => $url, 'message'=> $content], 0);
return false;
}
} /**
* CURL GET 请求
* @param $url
* @return bool|mixed
*/
public static function getCurl($url)
{
$curl = curl_init();
if (stripos($url, "https://") !== FALSE) {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
}
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$content = curl_exec($curl);
$status = curl_getinfo($curl); if (intval($status["http_code"]) == 200) {
curl_close($curl);
// ApiLog::setMessage(\Yii::$app->session->get('request_base_api_log_id'),['url' => $url, 'message'=> $content], 1);
return $content;
} else {
$error = curl_errno($curl);
curl_close($curl);
file_put_contents('../web/logs/notify/error' . date('YmdHi') . '.txt', $error);
// ApiLog::setMessage(\Yii::$app->session->get('request_base_api_log_id'),['url' => $url, 'message'=> $content], 0);
// $this->err_code = $error;
// $this->err_msg = $this->curl_error[$error];
return false;
}
} /**
* 微信api不支持中文转义的json结构
* @param $arr
* @return string
*/
public static function jsonEncode($arr)
{
if (count($arr) == 0) return "[]";
$parts = array();
$is_list = false;
//Find out if the given array is a numerical array
$keys = array_keys($arr);
$max_length = count($arr) - 1;
if (($keys [0] === 0) && ($keys [$max_length] === $max_length)) { //See if the first key is 0 and last key is length - 1
$is_list = true;
for ($i = 0; $i < count($keys); $i++) { //See if each key correspondes to its position
if ($i != $keys [$i]) { //A key fails at position check.
$is_list = false; //It is an associative array.
break;
}
}
}
foreach ($arr as $key => $value) {
if (is_array($value)) { //Custom handling for arrays
if ($is_list)
$parts [] = self::jsonEncode($value); /* :RECURSION: */
else
$parts [] = '"' . $key . '":' . self::jsonEncode($value); /* :RECURSION: */
} else {
$str = '';
if (!$is_list)
$str = '"' . $key . '":';
//Custom handling for multiple data types
if (!is_string($value) && is_numeric($value) && $value < 2000000000)
$str .= $value; //Numbers
elseif ($value === false)
$str .= 'false'; //The booleans
elseif ($value === true)
$str .= 'true';
else
$str .= '"' . addslashes($value) . '"'; //All other things
// :TODO: Is there any more datatype we should be in the lookout for? (Object?)
$parts [] = $str;
}
}
$json = implode(',', $parts);
if ($is_list)
return '[' . $json . ']'; //Return numerical JSON
return '{' . $json . '}'; //Return associative JSON
} /**
* 数据解析
* @param $data
* @return bool|mixed
*/
public static function parseData($data)
{
$data = json_decode($data, true);
return $data;
} /**
* 使用curl 文件上传 版本大于5.5
* @param $url
* @param $tmp_name
* @param $type
* @param $path
* @return int|mixed
*/
public static function curl_post_file($url, $tmp_name, $type, $path)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, true);
$data = ['file' => new \CURLFile($tmp_name, $type, $path)];
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_USERAGENT, "TEST");
$result = curl_exec($curl);
$status = curl_getinfo($curl);
if (intval($status["http_code"]) == 200) {
curl_close($curl);
return $result;
}
$error = curl_errno($curl);
curl_close($curl);
return $error;
}
PHP 微信公众号之客服完整讲解的更多相关文章
- 微信公众号发送客服消息提示errcode":45015,"errmsg":"response out of time limit or subscription is canceled hint:解决办法【已解决】
微信公众号发送客服消息提示errcode":45015,"errmsg":"response out of time limit or subscription ...
- 使用 Chrome 对长网页(知乎、微信公众号文章)进行完整截图
当需要对一个较长的网页进行完整截图时,可以直接使用谷歌浏览器(Chrome)自带的截图功能完成,不需要依赖第三方截图软件. 1. 打开网页 以微信公众号的页面作为示例:https://mp.weixi ...
- 使用signalr实现网页和微信公众号实时聊天(上)
最近项目中需要实现客户在公众号中和客服(客服使用后台网站系统)进行实时聊天的功能.折腾了一段时间,实现了这个功能.现在将过程记录下,以便有相同需求的同行可以参考,也是自己做个总结.这篇是上,用手机编辑 ...
- weixin-java-mp集成微信公众号自带客服功能
电脑端登录公众号管理后台,[添加功能插件]开通客服功能,输入"人工客服"接入客服热线 底部有我的微信二维码,如有问题,可加好友进行技术交流! weixi ...
- JAVA微信公众号网页开发——将接收的消息转发到微信自带的客服系统
如果公众号处于开发模式,普通微信用户向公众号发消息时,微信服务器会先将消息POST到开发者填写的url上,无法直接推送给微信自带的客服功能.如果需要把用户推送的普通消息推送到客服功能中,就需要进行代码 ...
- 使用小书匠及markdown here编辑博客和微信公众号
1. 使用小书匠连接Evernote并发布笔记到博客园 1.1 小书匠初探 我平时的信息收集的主要方法是采用Pocket+Evernote. 简单来说: 如果访问到非常有用,而且是必须要立刻记录的内容 ...
- C#开发微信门户及应用(37)--微信公众号标签管理功能
微信公众号,仿照企业号的思路,增加了标签管理的功能,对关注的粉丝可以设置标签管理,实现更加方便的分组管理功能.开发者可以使用用户标签管理的相关接口,实现对公众号的标签进行创建.查询.修改.删除等操作, ...
- tp6微信公众号开发者模式token认证
微信公众号开发完整教程(一) PHP7.0版本,TP5.0框架 技术标签: 微信公众号开发 因为工作的需要,这一两年对微信公众号和小程序,项目制作的比较多.所以我才打算写一篇全面的 ...
- 解决升级PHP7后 微信公众号收不到消息
服务器配置Linux+Nginx+PHP5.5+mysql index方法配置微信的关注回复.菜单事件.多客服.自动回复等 public function actionIndex() { if (is ...
随机推荐
- EFCodeFirst 数据迁移问题~
问题描述:将项目从TFS载下来 然后敲update-database 进行数据迁移 提示:Update-Database : 无法将“Update-Database”项识别为 cmdlet.函数.脚 ...
- 使用@Cacheable 踩过的坑
public class XXX{ @Resourceprivate XXX self;//@Cacheable通过内部调用将不会使用缓存,从Spring4.3开始可以通过注入self,再通过self ...
- SublimeText插件 : sass语法高亮
安装 :sublime中安装sass插件和sass build插件 就可以高亮显示sass 步骤:安装 sass插件和sass build (安装过程不细说) 步骤2:打开.sass文件,进行以下设 ...
- CSS实现多重边框和内凹圆角
CSS实现多重边框 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset=&q ...
- 02、体验Spark shell下RDD编程
02.体验Spark shell下RDD编程 1.Spark RDD介绍 RDD是Resilient Distributed Dataset,中文翻译是弹性分布式数据集.该类是Spark是核心类成员之 ...
- MySQL入门很简单: 5 索引
1. 索引的含义和特点 索引:创建在表上,是对数据库表中一列或多列的值进行排序的一种结构. 存储类型: B性树(BTREE)索引和哈希(HASH)索引: InnoDB和MyISAM支持BTREE索引, ...
- HDU(1754),线段树,单点替换,区间最值
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 线段树模板题,update功能是单点替换,query是访问区间最大值. #include < ...
- NYOJ(325)+NYOJ(456),01背包
题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=325 http://acm.nyist.net/JudgeOnline/problem. ...
- HTML5<fieldset>标签
1.<fieldset>标签对表单中的相关元素进行分组. 2.<fieldset>标签会在相关表单元素周围绘制边框. <!DOCTYPE html><html ...
- C#中的委托是什么?事件是不是一种委托?
C#中的委托是什么? 委托可以把一个方法作为参数代入另一个方法. 委托可以理解为指向一个函数的引用. 事件是不是一种委托?事件是一种特殊的委托.