微信公众号的获取关注者列表接口,通过next_openid无法获取新关注的用户列表,解决方法参考

11 篇文章 0 订阅
6 篇文章 0 订阅

微信接口:

//http请求方式: GET(请使用https协议)

https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID

接口文档:获取用户列表 

 

问题:

1.如果有新用户关注或者旧用户取消关注是否会影响openid列表的顺序?

答:没有具体文档说清楚。

2.之前取回来的用户列表,过了几天,有用户取消关注,也有新用户关注了,用之前缓存的列表最后一个openid作为next_openid参数,能否能取到所有新增用户的openid?

答:有可能取不到。

 

在实际应用中,并不能用next_openid无法实现增量同步,那我们可以换个思路来实现,用接口的openid列表与已同步的openid列表作差异 对比,同步数据库中没有的用户信息。

以下是我用Yii2写的控制台程序样本,实现了增量同步,在几万用户数据的情况下运行效率相当不错。

<?php
/**
 * 
 * ==============================================
 * filename: MpController.php
 * ———————————————————————————–
 * date: 2020年5月26日 下午3:43:16
 * ———————————————————————————–
 * author: jiant
 * ==============================================
 */
namespace app\commands;

use yii\console\Controller;
use SqlFormatter;
use app\utils\Mp;
use app\models\WechatMpuser;

/**
 * yii Toolkit
 */
class MpController extends Controller
{
    /**
     * Default command.
     */
    public function actionIndex()
    {
        echo 'please specify a command you wanna run.';
    }

    /**
     * 定时同步
     */
    public function actionSyncMpuser()
    {
        $this->getServiceMpuser();
        $this->getBookMpuser();
    }
    /**
     * 全量同步
     */
    public function actionSyncMpuserAll()
    {
        $all = true;
        $this->getServiceMpuser($all);
        $this->getBookMpuser($all);
    }
    /**
     * 
     */
    public function getServiceMpuser($all = false)
    {
        date_default_timezone_set("Asia/Shanghai"); 
        echo 'Check service user data.' . date('Y-m-d H:i:s') . PHP_EOL;
        
        $next_openid = '';
        $openids =[];
        $total = 0;
        do{$openidsRes = Mp::getServiceOpenids($next_openid);
//             var_dump($openidsRes);exit;
            
            if(isset($openidsRes->errcode)){
                echo 'errcode:' .$openidsRes->errcode . ', errmsg:' . $openidsRes->errmsg . PHP_EOL;
                break;
            }
            $total = $openidsRes->total;
            $next_openid = $openidsRes->next_openid;
            if($openidsRes->count > 0){
                $openids = array_merge($openids,$openidsRes->data->openid);
            }
        }while($next_openid && $next_openid !='');
        
        //新数据比对
        if(!$all){
            //取出数据库有的openid
            $database_openids_sql = WechatMpuser::find()->where(['platform_type'=>WechatMpuser::PLATFORM_TYPE_SERVICE])
            ->select(['openid']);
//             var_dump($database_openids_sql->createCommand()->getRawSql());exit;
            $database_openids = $database_openids_sql->column();
//             var_dump($database_openids);exit;
            if($total > 0 && $total == count($openids)){
                $new_openids = array_diff($openids,$database_openids);
            }
            else{
                $new_openids = [];
            }
        }
        else{
            $new_openids = $openids;
        }
//         print_r($new_openids);exit;
        
        //入库
        foreach ($new_openids as $val){
            $userInfo = Mp::getServiceUserinfo($val, '');
//              var_dump($userInfo);
            if(isset($userInfo->unionid) && $userInfo->unionid != ''){
                $form = WechatMpuser::findOne(['unionid'=>$userInfo->unionid,'platform_type'=>WechatMpuser::PLATFORM_TYPE_SERVICE]);
                if(!$form){
                    $form = new WechatMpuser();
                }
                $form->openid = $userInfo->openid;
                $form->subscribe = $userInfo->subscribe;
                $form->unionid = $userInfo->unionid;
                $form->nickname = base64_encode($userInfo->nickname);
                $form->sex = $userInfo->sex;
                $form->city = $userInfo->city;
                $form->province = $userInfo->province;
                $form->country = $userInfo->country;
                $form->headimgurl = $userInfo->headimgurl;
                $form->subscribe_time = $userInfo->subscribe_time;
                $form->add_time = time();
                $form->platform_type = WechatMpuser::PLATFORM_TYPE_SERVICE;
                $res = $form->save();
                $saveMessage = $res?'success':'fail';
                
                echo $saveMessage  .': ' . 'service openid->' . $val . ',nickname->' . base64_decode($form->nickname)  .  PHP_EOL;
            }
            elseif(isset($userInfo->subscribe) && $userInfo->subscribe==0){
                //删除取关的用户
                WechatMpuser::deleteAll(['openid'=>$val,'platform_type'=>WechatMpuser::PLATFORM_TYPE_SERVICE]);
                
                $saveMessage = 'fail,not subscribe';
                echo $saveMessage  .': ' . 'service openid->' . $val .  PHP_EOL;
            }
            elseif(isset($userInfo->errcode) && $userInfo->errcode == 40003 ){
                $saveMessage = $userInfo->errmsg;
                echo $saveMessage  .': ' . 'service openid->' . $val  . PHP_EOL;
            }
            else{
                //删除取关的用户
                WechatMpuser::deleteAll(['openid'=>$val,'platform_type'=>WechatMpuser::PLATFORM_TYPE_SERVICE]);
                
                $saveMessage = $userInfo->errmsg;
                echo $saveMessage  .': ' . 'service openid->' . $val  . PHP_EOL;
            }
        }
        $saveMessage = 'Synchronization completed, impact: '.count($new_openids).' data.';
        echo $saveMessage . PHP_EOL;
    }
    /**
     * 
     */
    public function getBookMpuser($all = false)
    {
        date_default_timezone_set("Asia/Shanghai"); 
        echo 'Check book user data.' . date('Y-m-d H:i:s') . PHP_EOL;
        
        $next_openid = '';
        $openids =[];
        $total = 0;
        do{$openidsRes = Mp::getBookOpenids($next_openid);
//             var_dump($openidsRes);
            
            if(isset($openidsRes->errcode)){
                echo 'errcode:' .$openidsRes->errcode . ', errmsg:' . $openidsRes->errmsg . PHP_EOL;
                break;
            }
            $total = $openidsRes->total;
            $next_openid = $openidsRes->next_openid;
            if($openidsRes->count > 0){
                $openids = array_merge($openids,$openidsRes->data->openid);
            }
        }while($next_openid && $next_openid !='');
        
        //新数据比对
        if(!$all){
            //取出数据库有的openid
            $database_openids_sql = WechatMpuser::find()->where(['platform_type'=>WechatMpuser::PLATFORM_TYPE_BOOK])
            ->select(['openid']);
//             var_dump($database_openids_sql->createCommand()->getRawSql());exit;
            $database_openids = $database_openids_sql->column();
//             var_dump($database_openids);exit;
            if($total > 0 && $total == count($openids)){
                $new_openids = array_diff($openids,$database_openids);
            }
            else{
                $new_openids = [];
            }
        }
        else{
            $new_openids = $openids;
        }
//         print_r($new_openids);exit;
        
        //入库
        foreach ($new_openids as $val){
            $userInfo = Mp::getBookUserinfo($val, '');
//             var_dump($userInfo);
            if(isset($userInfo->unionid) && $userInfo->unionid != ''){
                $form = WechatMpuser::findOne(['unionid'=>$userInfo->unionid,'platform_type'=>WechatMpuser::PLATFORM_TYPE_BOOK]);
                if(!$form){
                    $form = new WechatMpuser();
                }
                $form->openid = $userInfo->openid;
                $form->subscribe = $userInfo->subscribe;
                $form->unionid = $userInfo->unionid;
                $form->nickname = base64_encode($userInfo->nickname);
                $form->sex = $userInfo->sex;
                $form->city = $userInfo->city;
                $form->province = $userInfo->province;
                $form->country = $userInfo->country;
                $form->headimgurl = $userInfo->headimgurl;
                $form->subscribe_time = $userInfo->subscribe_time;
                $form->add_time = time();
                $form->platform_type = WechatMpuser::PLATFORM_TYPE_BOOK;
                $res = $form->save();
                $saveMessage = $res?'success':'fail';
                
                echo $saveMessage  .': ' . 'book openid->' . $val . ',nickname->' . base64_decode($form->nickname)  .  PHP_EOL;
            }
            elseif(isset($userInfo->subscribe) && $userInfo->subscribe==0){
                //删除取关的用户
                WechatMpuser::deleteAll(['openid'=>$val,'platform_type'=>WechatMpuser::PLATFORM_TYPE_BOOK]);
                
                $saveMessage = 'fail,not subscribe';
                echo $saveMessage  .': ' . 'book openid->' . $val  . PHP_EOL;
            }
            elseif(isset($userInfo->errcode) && $userInfo->errcode == 40003 ){
                //删除取关的用户
                WechatMpuser::deleteAll(['openid'=>$val,'platform_type'=>WechatMpuser::PLATFORM_TYPE_BOOK]);
                
                $saveMessage = $userInfo->errmsg;
                echo $saveMessage  .': ' . 'book openid->' . $val  . PHP_EOL;
            }
            else{
                $saveMessage = $userInfo->errmsg;
                echo $saveMessage  .': ' . 'book openid->' . $val  . PHP_EOL;
            }
        }
        $saveMessage = 'Synchronization completed, impact: '.count($new_openids).' data.';
        echo $saveMessage . PHP_EOL;
    }
}

写在最后:

该接口有调用次数限制,详见 接口调用频次限制说明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值