程序后台支持自动设置微信推送
浏览量:354
最近好忙,都忘记过来更新博客了,自己最近在做点有意思的事情,总结了一下微信推送的相关事情
我们是做电商的,所以微信公众后台我们设置很多关于自己常用的模板消息,并自己去推送
一、第一步
拉去微信公众后台,自己需要的配置模板消息类型,并展示到自己的后台:
<?php
/**
* 从微信获取模板列表
* lianghuiju
*/
public function wechatTplList()
{
$acces_token = $this->getAccessToken();
$url = 'https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=' . $acces_token;
return $this->http($url, 'POST');
}
/**
* 获取用户的token
* lianghuiju
*/
public function getAccessToken($refresh = false)
{
$response = $this->http(你自己的地址 . ($refresh ? '?force=1' : ''), 'GET', null, false);
$json_arr = json_decode($response, true);
if (is_array($json_arr)) {
if (@$json_arr['error'] == 0) {
return $json_arr['data']['access_token'];
} else {
throw new Exception("DP 请求错误:$response");
}
} else {
throw new Exception("DP 返回错误:$response");
}
}
/**
* 给前端展示 微信模板列表
* lianghuiju
*/
public function wechatTplList()
{
$key = 'wechatSendTplList';
$this->load->library('cache');
$list = $this->->redis->get($key);
$list = json_decode($list,true);
if(!$list){
$list = $this->wechatTplList();
$this->redis->set($key,json_encode($list),strtotime(date('Y-m-d'." 23:59:59")) - time());
}
return $list;
}
二、第二步 根据模板信息获取内容信息
<?php
/**
* 获取某个模板需要设置的信息
* lianghuiju
*/
public function getTplSetInfo()
{
$template_id = $this->input->get_post('template_id');
$info = $this->getTplSetInfo($template_id);
if($info){
$this->renderOutput( $info,0,'success');
}else{
$this->renderOutput($info,1,'fail');
}
}
/**
* 获取某个模板需要填写的信息
* @author lianghuiju
* @param $templateId 模板的id
* @return mixed
*/
public function getTplSetInfo($templateId)
{
$tplList = $this->wechatTplList();
$info = '';
foreach ($tplList['template_list'] as $key => $value){
if($value['template_id'] == $templateId){
$info = $value;
break;
}
}
# 处理数据:每个模板都是有title和remark,所以只要输有多少keyword即可
$arr = explode("\n",$info['content']);
# 部分模板会莫名的多空一行
foreach ($arr as $key => $value){
if(empty($value)){
unset($arr[$key]);
}
}
# 打破原有的数组key值,重新从0往上排序
$arr = array_values($arr);
$returnArr[0] = ['name'=>'标题','value'=>'','color'=>'','wxchatKey'=>'first'];
unset($arr[0]); # 删除开头
$len = count($arr);
unset($arr[$len]); # 删除结尾
# 循环key的部分
$num = 1;
foreach ($arr as $key => $value){
$explode_str = explode(':',$value);
$name = $explode_str[0];
$content_key = trim(str_replace('.DATA}}',' ', str_replace('{{',' ',$explode_str[1])));
$returnArr[$key] = ['name'=>$name,'value'=>'','color'=>'','wxchatKey'=>$content_key];
$num++;
}
$returnArr[] = ['name'=>'备注','value'=>'','color'=>'','wxchatKey'=>'remark'];
ksort($returnArr);
return $returnArr;
}
三、第三步 获取分组信息

四、第四步 设置要发送的人数

五、第五步 预定义时间

六、第六步 指定自己人预览还是脚本定期发送

最后,发送脚本设置
/**
* 定时任务,向分组用户发送模板消息
* lianghuiju
*/
public function timeTask()
{
# 防骚扰检测
$this->checkTime();
$testOpenId = '自己的openid'; # 梁慧菊
$send_suc = 0;
$res = $this->wechatSendTpl->getOneTimeTask($this->type);//获取推送类型
$accessToken = $this->get_access_token();
echo "<pre>";
var_dump($res);
if($res) {
# 获取要发送的openid 每次获取分组的100个 opendid
$openids = $this->getSendOpenId($res);
$post_msg = [];
foreach ($openids as $openid){
$post_msg[] = $this->getPostData($openid,$res,$accessToken);
//测试站发送一个就行 省得收到这么多次推送
if(ENVIRONMENT !== 'production'){
break;
}
}
$send_res = $this->http_multi($post_msg);
if(is_array($send_res)){
foreach ($send_res as $item){
if(json_decode($item,true)['errcode'] == 0) $send_suc ++;
}
# 更改发送记录
$this->wechatSendTpl->updateSendNum($send_suc,100 - $send_suc,$res['id'],$this->cacheKey,$this->workKey);
}
}
}
/**
* 获取要发送的openid
* @author lianghuiju
* @param $res
* @return array
*/
protected function getSendOpenId($res)
{
# 检测工作redis是否还有openid
$numLeft = $this->cache->redis->SCARD($this->workKey.$res['id']);
if(!$numLeft){
$this->getNewWorkSpace($res);
}
$openids = $this->cache->redis->spop($this->workKey.$res['id']);
$openidsArr = explode(',',$openids);
return $openidsArr;
}
/**
* 获取一个新的openid的工作目录
* @author lianghuiju
* @param $res
* @return mixed
*/
protected function getNewWorkSpace($res)
{
$this->load->driver('cache');
$key = $this->cacheKey.$res['id']; # 不要更改名字
$is_exist = $this->checkKeyExists($key);
if(!$is_exist){
$group = explode(',',trim($res['group_name']));
$file = $this->wechatSendTpl->getSendFile($group);
# 将所有的文件写入redis
foreach ($file as $item){
$this->cache->redis->lpush($key,$item);
}
}
# 获取一个文件
$openidFile = $this->cache->redis->rpop($key);
# 所有的文件都已经发送完毕,但仍未到限制数量,则标记任务已经结束
if(!$openidFile){
$this->wechatSendTpl->sendTaskOver($res['id'],$this->cacheKey,$this->workKey);
}
# 将openid加入集合
$openids = $this->qcloud->get_openids($openidFile);
$openisArr = array_chunk($openids,100);
# 循环一万次实在是太慢了:简化一下变为100次
$openisArrString = [];
foreach ($openisArr as $value){
$openisArrString[] = implode(',',$value);
}
foreach ($openisArrString as $string){
$this->cache->redis->sadd($this->workKey.$res['id'],$string);
}
return $openidFile;
}
/**
* 查看key是否存在
* @author wangxiaoning@chuchujie.com
*/
public function checkKeyExists($checkkey)
{
$flag = false;
$memberKey = "send_task";
$this->load->driver('cache');
# 先检测是否存在
$member = $this->cache->redis->SMEMBERS($memberKey);
if($member && in_array($checkkey,$member)){
$flag = true;
}else{
# 将这个key 加进去
$this->cache->redis->SADD($memberKey,$checkkey);
}
return $flag;
}
public function http_multi($urlarr = array())
{
$result = $res = $ch = array();
$nch = 0;
$mh = curl_multi_init();
foreach ($urlarr as $nk => $url) {
$ch[$nch] = curl_init();
curl_setopt_array($ch[$nch], array(
CURLOPT_URL => $url['url'],
CURLOPT_USERAGENT => "Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $url['data'],
CURLOPT_TIMEOUT => 5,
));
curl_multi_add_handle($mh, $ch[$nch]);
++$nch;
}
/* wait for performing request */
do {
$mrc = curl_multi_exec($mh, $running);
} while (CURLM_CALL_MULTI_PERFORM == $mrc);
while ($running && $mrc == CURLM_OK) {
// wait for network
while (curl_multi_exec($mh, $running) === CURLM_CALL_MULTI_PERFORM);
if (curl_multi_select($mh, 0.5) > -1) {
// pull in new data;
do {
$mrc = curl_multi_exec($mh, $running);
} while (CURLM_CALL_MULTI_PERFORM == $mrc);
}
}
if ($mrc != CURLM_OK) {
log_message('NOTE', "CURL Data Error");
}
/* get data */
$nch = 0;
foreach ($urlarr as $moudle => $node) {
if (($err = curl_error($ch[$nch])) == '') {
$res[$nch] = curl_multi_getcontent($ch[$nch]);
$result[$moudle] = $res[$nch];
$curl_info = curl_getinfo($ch[$nch]);
log_message('NOTE', "http_multi_wechatTplGroupSend:".$nch.":".json_encode($curl_info));
} else {
log_message('NOTE', "http_multi_wechatTplGroupSend:curl error:".$err);
}
curl_multi_remove_handle($mh, $ch[$nch]);
curl_close($ch[$nch]);
++$nch;
}
curl_multi_close($mh);
return $result;
}
/**
* 获取token
* @return bool|string
*/
function get_access_token()
{
return file_get_contents("http://www.lianghuiju.com/token.php");
} 
神回复
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。