晓夏

北漂的女孩

Good Luck To You!

程序后台支持自动设置微信推送

浏览量:350

最近好忙,都忘记过来更新博客了,自己最近在做点有意思的事情,总结了一下微信推送的相关事情

我们是做电商的,所以微信公众后台我们设置很多关于自己常用的模板消息,并自己去推送

一、第一步

拉去微信公众后台,自己需要的配置模板消息类型,并展示到自己的后台:

<?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;
}

图片.png

二、第二步  根据模板信息获取内容信息

<?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;
}

图片.png

三、第三步  获取分组信息

图片.png

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

图片.png

五、第五步     预定义时间

图片.png

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

图片.png

最后,发送脚本设置

/**
 * 定时任务,向分组用户发送模板消息
 *  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");
}

神回复

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。