当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。严格来说,发送被动响应消息其实并不是一种接口,而是对微信服务器发过来消息的一次回复。
自定义回复图文是自定义回复文本,图片,图文中最为复杂的,所以就以图文为例。
//回复文本
public function reply_news(){
$keyword=I('post.keyword');
$media_id=I('post.media_id');
$title=I('post.title');
$url=I('post.url');
$content=I('content');
$content_source_url=I('post.content_source_url');
if(empty($keyword) || empty($url)){
$this->ajaxReturn(array('status'=>0,'msg'=>'必须输入关键字和选择图片'));
exit;
}
//选择本地图片,需上传到公众平台
if (empty($media_id)) {
$accessToken=getAccess_token();
include APP_PATH . 'LaneWeChat/lanewechat.php';
//上传永久图片
$api="https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=$accessToken&type=image";
$file=realpath('.' . $url);
// $data['media']=Curl::addFile($file);
$data['media']='@'.$file;
$ret=Curl::callWebServer($api,$data,'post',1,0);
//上传成功
if (isset($ret['media_id'])) {
$media_id=$ret['media_id'];
$url=$ret['url'];
}else{
$ret['fail']='本地图片上传公众平台失败';
$this->ajaxReturn(array('status'=>1,'msg'=>$ret));
exit;
}
$data['url']=$content_source_url;
$data['picurl']=$url;
$data['title']=$title;
$data['description']=$content;
$data['url']=$url;
$reply_id=M('mp_reply_news')->add($data);
$mp=getCurrentMp();
$arr['mp_id']=$mp['id'];
$arr['type']='news';
$arr['keyword']=$keyword;
$arr['reply_id']=$reply_id;
$ret=M('mp_rule')->add($arr);
if ($ret) {
$this->ajaxReturn(array('status'=>1,'msg'=>'添加成功','url'=>U('replynews')));
}else{
$this->ajaxReturn(array('status'=>1,'msg'=>'添加失败'));
}
}
}
1.首先需要写回复图文的方法,如上,其实回复图文是回复文本与回复图片的结合,只要会了文本与图片自然也会回复文本的。当然不要忘了写上传代码,如下,这两段代码要放到一个控制器当中
//接受文件上传
public function upload(){
$upload = new \Think\Upload();// 实例化上传类
$upload->maxSize = 3145728 ;// 设置附件上传大小
$upload->exts = array('jpg', 'gif', 'png', 'jpeg');// 设置附件上传类型
$upload->rootPath = './Uploads/'; // 设置附件上传根目录
$upload->savePath = ''; // 设置附件上传(子)目录
// 上传文件
$info = $upload->uploadOne($_FILES['file']);
if(!$info) {// 上传错误提示错误信息
// $this->error($upload->getError());
$this->ajaxReturn(array('code'=>'1','msg'=>$upload->getError()));
}else{// 上传成功
// $this->success('上传成功!');
$file="/Uploads/".$info['savepath'].$info['savename'];;
$this->ajaxReturn(array('code'=>'0','msg'=>"上传成功!",'url'=>$file));
}
}
2.当然回复图文消息和自定义菜单一样,也需要引入LaneWeChat,在LaneWeChat中core下的wechatrequest.lib.php中修改text方法,如下:
public static function text(&$request){
// $content = '收到文本消息';
// return ResponsePassive::text($request['fromusername'], $request['tousername'], $content);
//获取哪个公众号发过来的请求
$mpid=$_GET['id'];
$content=$request['content'];
$where['mp_id']=$mpid;
$where['keyword']=$content;
$data=M('mp_rule')->where($where)->find();
if($data){
//发送信息中有这个关键字
$reply_id=$data['reply_id'];
$type=$data['type'];//回复类型
//判断回复类型
switch($type){
case 'text':
$reply=M('mp_reply_text')->find($reply_id);
if($reply){
$reply_text=$reply['content'];
}else{
$reply_text='出错啦';
}
return ResponsePassive::text($request['fromusername'], $request['tousername'], $reply_text);
break;
case 'image':
$reply=M('mp_reply_image')->find($reply_id);
if($reply){
$media_id=$reply['media_id'];
return ResponsePassive::image($request['fromusername'], $request['tousername'], $media_id);
}else{
$reply_text='出错啦';
return ResponsePassive::text($request['fromusername'], $request['tousername'], $reply_text);
}
break;
case 'news':
$reply=M('mp_reply_news')->find($reply_id);
if($reply){
$item[]=ResponsePassive::newsItem($reply['title'],$reply['descrpition'],$reply['picurl'],$reply['url']);
// $item[]=ResponsePassive::newsItem($reply['title'],$reply['descrpition'],$reply['picurl'],$reply['url']);
// $item[]=ResponsePassive::newsItem($reply['title'],$reply['descrpition'],$reply['picurl'],$reply['url']);
return ResponsePassive::news($request['fromusername'], $request['tousername'], $item);
}else{
$reply_text='出错啦';
return ResponsePassive::text($request['fromusername'], $request['tousername'], $reply_text);
}
break;
default:
return 'success';
break;
}
}else{
return 'success';
}
}
现在说的是图文,只要改图文即可。
3.自己设计前台页,我给的只是参考,如下
<extend name="Common:base" />
<block name="body">
<h2>回复图文</h2>
<form class="layui-form" action="" style="padding-right: 10px;" method="post">
<div class="layui-form-item">
<label class="layui-form-label">回复关键词</label>
<div class="layui-input-block">
<input type="text" name="keyword" placeholder="请输入关键词" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">标题</label>
<div class="layui-input-block">
<input type="text" name="title" placeholder="请输入标题" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">封面图</label>
<div class="layui-input-block">
<input type="hidden" id="media_id" name="media_id">
<input type="hidden" id="url" name="url">
<img src="" id="img_logo" width="100" height="100" />
<button type="button" class="layui-btn" id="btn_upload">
<i class="layui-icon"></i>选择本地图片
</button>
<button type="button" class="layui-btn" id="btn_select">
<i class="layui-icon"></i>选择素材库中图片
</button>
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">内容</label>
<div class="layui-input-block">
<textarea name="content" placeholder="请输入图文内容" class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">原文地址</label>
<div class="layui-input-block">
<input type="text" name="content_source_url" placeholder="请输入原文地址如:http://xxxx.com/……" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="SBT">提交</button>
<a href="{:U('keywords',['type'=>'news'])}" class="layui-btn layui-btn-primary">返回</a>
</div>
</div>
</form>
<script>
layui.use('form', function(){
var form = layui.form
form.on('submit(SBT)', function(data){
var load = layer.load();
$.post("{:U('reply_news')}",data.field,function (res) {
if(res.status=='0'){
layer.close(load);
layer.alert(res.msg);
}
if(res.status=='1'){
layer.close(load);
layer.msg(res.msg,{time:1000},function () {
window.location.href=res.url;
});
}
})
return false;
});
});
//图片上传
layui.use('upload', function(){
var upload = layui.upload;
//执行实例
var uploadInst = upload.render({
elem: '#btn_upload', //绑定元素
accept: 'images', //允许上传的文件类型
url: "{:U('upload')}", //上传接口
done: function(res){
//上传完毕回调
if(res.code=='0'){
var url ="__ROOT__" + res.url;
console.log(url);
$("#img_logo").attr("src",url);
$("#url").val(res.url);
}else{
layer.msg(res.msg);
}
},
error: function(){
//请求异常回调
}
});
});
$("#btn_select").click(function(){
layui.use('layer', function(){
var layer = layui.layer;
layer.open({
type: 2,
title: '永久素材',
shadeClose: true,
shade: 0.5,
area: ['680px', '300px'],
content: '{:U('common/selectImage')}',
btn:['确定','取消'],
yes: function(index, layero){
var body = layer.getChildFrame('body', index);
// console.log(body.html());
var img = body.find('.select').siblings('img');
$("#img_logo").attr('src',img.attr('src'));
$("#media_id").val(img.attr('media-id'));
$("#url").val(img.attr('url'));
layer.close(index);
}
});
});
})
</script>
</block>
然后就可以实现以下功能了,点击提交即可输入到数据库。所以要有与其对应的数据库
如果想把本地的图文同步到页面中需要再控制器中写相应代码:
private $mp;
public function news(){
$model=M('mp_reply_news');
$data=$model
->alias('a')
->join('rh_mp_rule as b on b.reply_id=a.reply_id')
->select();
$this->assign('data',$data);
$this->display('news');
}
前台页如下:
<extend name="Common:base" />
<block name="body">
<h2>回复图文
<a href="{:U('replynews',['type'=>$type])}" id="addkw" class="layui-btn layui-btn-normal layui-btn-sm rha-nav-title" style="position:absolute;right:30px;">增加关键词</a>
</h2>
<table class="layui-table" lay-skin="line">
<colgroup>
<col width="120">
<col width="200">
<col width="150">
<col width="">
<col width="100" >
<col width="150">
</colgroup>
<thead>
<tr>
<th>关键词</th>
<th>标题</th>
<th>封面图</th>
<th>图文描述</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<volist name="data" id="vo">
<tr>
<td>{$vo.keyword}</td>
<!-- <td>{$vo.content}</td> -->
<td>{$vo.title}</td>
<!-- <td><img src="{$vo.picurl}" alt=""></td> -->
<td>
<div style="padding: 5px; border: #e6e6e6 solid 1px; width:160px; float: left; ">
<img class="form_logo" src="{:U('common/showMpImg')}?url={$vo.picurl}" style="max-width: none" width="160" height="100">
</div>
</td>
<td>{$vo.descrpition}</td>
<td><if condition="$vo.status eq '1'">使用中<else/>已停用</if></td>
<td>
<div class="">
<a class="rha-bt-a" href="javascript:;" onclick="editReply('{$vo.id}')">修改</a>
<if condition="$vo.status eq '1'">
<a class="rha-bt-a" href="javascript:;" onclick="updateReply('{$vo.id}','0')">停用</a>
<else/>
<a class="rha-bt-a" href="javascript:;" onclick="updateReply('{$vo.id}','1')">开启</a>
</if>
<a class="rha-bt-a" href="javascript:;" onclick="delReply('{$vo.id}')">删除</a>
</div>
</td>
</tr>
</volist>
</tbody>
</table>
</block>
如果图片出不来还需要建个控制器:
<?php
namespace Home\Controller;
use Think\Controller;
use LaneWeChat\Core\Curl;
class CommonController extends Controller
{
//微信公众平台对图片采用了防盗链设置
public function showMpImg($url){
header("content-type:image/jpeg");
echo file_get_contents($url);
// echo $url;
}
}
然后效果如下: