当前位置:网站首页>微信小程序客服自动回复——PHP实现
微信小程序客服自动回复——PHP实现
2022-06-13 09:25:00 【edui】
先说怎么用,然后使用成功了自己研究代码,驱动式学习多好。
首先将这个PHP程序的文件放在你 自己的服务器里面
注意php程序里的APP_ID的值改成你自己的appid。还有APP_SECRET 的值改成你自己的appSecret。还有记好配置的token令牌,等会配置用到。然后打开消息推送
在小程序后台“开发”->“开发设置”->下拉有一个消息推送,打开。
服务器地址填写这个PHP文件的位置https://**********.php
TOKEN(令牌) ----这里随便写,反正与PHP程序里的开头那里我 的是dertertsdf
define(“TOKEN”,“dertertsdf”);//自己设置的Token
密钥随机生成
然后模式选兼容模式
接受类型选“XML”
这是配置,然后如果你急着提交会发现“taken(令牌) 失效”。。。。。就对了验证
在250行左右有一个代码,这是验证用的,因为当你打开消息推送的时候腾讯的服务器会给你写的地址发送一个请求进行验证只有你返回正确的信息才能验证成功,提交才不会出现“taken(令牌) 失效”字样。然后才会提交成功,所以当提交时不要注释
PS:建议把绑定的客服都解绑,因为我发现有时候会出现bug,会把用户联系 客服的消息转发给客服了不发送给服务器也就是自动回复那里收不到。
//注意:第一步验证时打开,验证完成之后就可以注释了
//$wechatObj->isValid();
- 修改
顺利完成了上面的步骤后你打开客服应该会有自动打招呼了。
然后就自己看代码发挥了,对应封装一个$data变量调用官方文档说的发送接口就可以了
如果想发送图片,需要先把图片发送给腾讯服务器,然后腾讯服务器会返回一个媒体的ID,用这个ID调用发送接口就可以了。程序里我也写好了输入上传图片地址返回ID的函数了。
不过我偷懒直接调用系统指令curl,所以需要PHP的shell_exec()这个函数。为了安全起见这个函数一般默认禁用的,所以需要在php配置文件里该一下,百度就可以。over
下面时所有代码。可以直接复制粘贴用【手动滑稽】
<?php
define("TOKEN","dertertsdf");//自己设置的Token
class wechatAPI{
const APP_ID = 'wx***********'; //你自己的appid
const APP_SECRET = '017ec3*****************';//你自己生成的appSecret
//用于小程序第一步验证返回
public function isValid(){
$echoStr = $_GET["echostr"];
if ($this->checkSignature()) {
echo $echoStr;
exit;
}
}
public function checkSignature(){
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
public function send($data){
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$this->getAccessToken();
$data = urldecode(json_encode($data));
$this->curl_post($url,$data);
}
//xml数据转数组
public function xml2Array($contents = NULL, $encoding = 'UTF-8', $get_attributes = 1, $priority = 'tag'){
if (!$contents)
{
return array();
}
if (!function_exists('xml_parser_create'))
{
return array ();
}
$parser = xml_parser_create('');
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $encoding);
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
xml_parse_into_struct($parser, trim($contents), $xml_values);
xml_parser_free($parser);
if (!$xml_values)
return array();
$xml_array = array ();
$parents = array ();
$opened_tags = array ();
$arr = array ();
$current = & $xml_array;
$repeated_tag_index = array ();
foreach ($xml_values as $data)
{
unset ($attributes, $value);
extract($data);
$result = array ();
$attributes_data = array ();
if (isset ($value))
{
if ($priority == 'tag')
$result = trim($value);
else
$result['value'] = trim($value);
}
if (isset ($attributes) && $get_attributes) {
foreach ($attributes as $attr => $val)
{
if ($priority == 'tag')
$attributes_data[$attr] = $val;
else
$result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
}
}
if ($type == "open")
{
$parent[$level -1] = & $current;
if (!is_array($current) || (!in_array($tag, array_keys($current)))) {
$current[$tag] = $result;
if ($attributes_data)
$current[$tag . '_attr'] = $attributes_data;
$repeated_tag_index[$tag . '_' . $level] = 1;
if (isset($tag) && $tag && isset($current[$tag])) {
$current = & $current[$tag];
}
}
else
{
if (isset ($current[$tag][0]))
{
$current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
$repeated_tag_index[$tag . '_' . $level]++;
}
else
{
$current[$tag] = array (
$current[$tag],
$result
);
$repeated_tag_index[$tag . '_' . $level] = 2;
if (isset ($current[$tag . '_attr']))
{
$current[$tag]['0_attr'] = $current[$tag . '_attr'];
unset ($current[$tag . '_attr']);
}
}
$last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
$current = & $current[$tag][$last_item_index];
}
}
elseif ($type == "complete")
{
if (!isset ($current[$tag]))
{
$current[$tag] = $result;
$repeated_tag_index[$tag . '_' . $level] = 1;
if ($priority == 'tag' && $attributes_data) {
$current[$tag . '_attr'] = $attributes_data;
}
}
else
{
if (isset ($current[$tag][0]) && is_array($current[$tag])) {
$current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
if ($priority == 'tag' && $get_attributes && $attributes_data) {
$current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
}
$repeated_tag_index[$tag . '_' . $level]++;
}
else
{
$current[$tag] = array (
$current[$tag],
$result
);
$repeated_tag_index[$tag . '_' . $level] = 1;
if ($priority == 'tag' && $get_attributes) {
if (isset ($current[$tag . '_attr']) && is_array($current[$tag]))
{
$current[$tag]['0_attr'] = $current[$tag . '_attr'];
unset ($current[$tag . '_attr']);
}
if ($attributes_data)
{
$current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
}
}
$repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
}
}
}
elseif ($type == 'close')
{
$current = & $parent[$level -1];
}
}
return ($xml_array);
}
//获取accesstoken
public function getAccessToken() {
$tokenFile = "access_token.txt";
$data = json_decode(file_get_contents($tokenFile,FILE_USE_INCLUDE_PATH));
//accesstoken有效期是7200秒,这里用到的文件缓存
//注意:文件权限问题
if (!$data->expire_time || $data->expire_time < time()) {
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".self::APP_ID."&secret=".self::APP_SECRET;
$res = json_decode(file_get_contents($url));
if($res) {
$arr = array();
$access_token = $res->access_token;
$arr['expire_time'] = time() + 7000;
$arr['access_token'] = $access_token;
$fp = fopen($tokenFile, "w");
fwrite($fp, json_encode($arr));
fclose($fp);
}
} else {
$access_token = $data->access_token;
}
return $access_token;
}
//post发送json数据
public function curl_post($url,$post_data){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$res = curl_exec($ch);
if(!$res){
throw new Exception('发送消息失败:'.curl_error($ch));
}
curl_close($ch);
}
//根据问题寻找数据库问答
public function queryData($question){
$sql = '%%'.$question.'%%';
$con=mysqli_connect('localhost','userNane','password');
if(!$con){
return "小i听不懂你在说啥,直接长按粘贴指令看看";
}
//发送编码为utf8
mysqli_query($con,"set names utf8");
mysqli_select_db($con,'magic_cube');
$result1=mysqli_query($con,"SELECT id,anser FROM qan WHERE question LIKE '$sql'");
//从结果集中取出数据,并释放内存
$data=mysqli_fetch_all($result1,MYSQLI_ASSOC);
mysqli_free_result($result1);
if(count($data) == 0){
return "小i听不懂你在说啥,直接长按粘贴指令看看";
}
return $data[0]["anser"];
}
//将临时素材上传至微信服务器返回media_id
public function uploadPicture($load){
$shell = "curl -F [email protected]".$load." 'https://api.weixin.qq.com/cgi-bin/media/upload?access_token=".$this->getAccessToken()."&type=image'";
$lists = shell_exec($shell);
$da = json_decode($lists,true);
return $da["media_id"];
}
};
$wechatObj = new wechatAPI();
//注意:第一步验证时打开,验证完成之后就可以注释了
//$wechatObj->isValid();
if($wechatObj->checkSignature() === true){
$xmlstring = file_get_contents("php://input");
$accept_info = $wechatObj->xml2Array($xmlstring)['xml'];
if($accept_info){
$ToUserName = $accept_info['ToUserName'];
$FromUserName = $accept_info['FromUserName'];
$CreateTime = $accept_info['CreateTime'];
$MsgType = $accept_info['MsgType'];
//$MsgId = $accept_info['MsgId'];
// $Encrypt = $accept_info['Encrypt'];
$data = array();
if($MsgType == 'text'){
//接收文本
$Content = $accept_info['Content'];//文本内容
// "touser": "OPENID",
// "msgtype": "link",
// "link": {
// "title": "Happy Day",
// "description": "Is Really A Happy Day",
// "url": "URL",
// "thumb_url": "THUMB_URL"
// }
if($Content == '人工客服'){
$da = $wechatObj->uploadPicture('/www/wwwroot/ponycody.online/service.jpg');
$data['touser'] = $FromUserName;
$data['msgtype'] = 'image';
$data['image']['media_id'] = $da;//urlencode 解决中文乱码问题
$wechatObj->send($data);exit;
}else{
$anser= $wechatObj->queryData($Content);
$data['touser'] = $FromUserName;
$data['msgtype'] = 'text';
$data['text']['content'] = urlencode($anser);//urlencode 解决中文乱码问题
$wechatObj->send($data);exit;
}
}else if($MsgType === 'image') {
//接收图片
$data['touser'] = $FromUserName;
$data['msgtype'] = 'text';
$data['text']['content'] = urlencode('小i还看不懂图片哦,如有需要回复“人工客服“字样进行人工客服私聊哦');//urlencode 解决中文乱码问题
$wechatObj->send($data);exit;
}else if($MsgType === 'event') {
//进入客服窗口事件
$Event = $accept_info['Event'];
$SessionFrom = $accept_info['SessionFrom'];
if($Event == 'user_enter_tempsession') {
$data['touser'] = $FromUserName;
$data['msgtype'] = 'text';
$data['text']['content'] = urlencode('您好!我是机器人小i,您可以直接长按粘贴口令加群哦');//urlencode 解决中文乱码问题
$wechatObj->send($data);exit;
}
}
echo '<xml><ToUserName><![CDATA['.$FromUserName.']]></ToUserName><FromUserName><![CDATA['.$ToUserName.']]></FromUserName><CreateTime>'.$CreateTime.'</CreateTime><MsgType><![CDATA[transfer_customer_service]]></MsgType></xml>';
}
}
边栏推荐
- C language: sanziqi
- ROS2之OpenCV人脸识别foxy~galactic~humble
- Consolas-with-Yahei
- Dynamic display of analog clock using digital clock in turtle Library
- Jenkins集成Ldap,Ldap配置错误导致jenkins用户登录失败问题解决
- Classes and objects -- Inheritance
- Amadahl's Law (a little thought)
- go-zero微服务实战系列(三、API定义和表结构设计)
- Biden: hope to sign the bipartisan gun safety reform bill as soon as possible
- Jenkins接入Openldap用戶認證
猜你喜欢
[51nod p2673] shortest path [heap optimization Dijk]
Consolas-with-Yahei
[51nod p2653] interval XOR [bit operation]
SQL ROW_ The number() function uses
[51nod p2102] or subtraction and [bit operation]
[51nod P3210] binary statistics
Learning makefile with me
[51nod p3216] Award [bit operation]
Exercise 7-7 string replacement (15 points)
Acwing785. quick sort (sort+ quick sort + merge sort)
随机推荐
Pxxx local socket communication
Figure: concept of figure
Trees and binary trees: the concept of binary trees
C # introductory series (XIII) -- getting to know the structure for the first time
JS【中高级】部分的知识点我帮你们总结好了
Exercise 7-10 finding specified characters (15 points)
[51nod 3062] n queen problem V2 [bit operation DFS]
Classes and objects -- polymorphic
C language structure
Instruction level parallelism (?)
Dpdk timer learning notes
Collection of articles on virtualization and cloud computing
LeetCode 5289. Fair distribution of cookies (DFS)
Calculate the number of days between two times (supports cross month and cross year)
[Luogu p1090, ssl1040] merged fruit [pile]
Can the operation of the new BMW I3 meet the expectations of the famous products of the 3 series?
Zigzag transformation
turtle库的使用数字时钟模拟时钟动态显示
Acwing 787. Merge sort
Heap