公眾號遷移 原有數據庫openid 更新主體openid

  今天一個兩年前做的公眾號項目 要更改主體,隨之而來的是公眾號的遷移。 公眾號遷移後關注的粉絲也會對應的進行遷移,還會給粉絲髮送相關通知。

  大體流程如下圖

 

  遷移的具體步驟我就不細說了。今天主要說的是 遷移主體後 對應的用戶openid也會變化,也就是說你的程序如果公眾號登錄是以微信openid為唯一標識的話,

那你的用戶系統經過一次公眾號變更後就會出現問題。 老用戶再次授權後 系統可能認為是新用戶,而且通過原來的openid 也無法推送模板消息等功能。

  微信方面當然也考慮到了相關問題 。給出了相關的接口去處理這個問題,這就是今天說的openid轉換接口  。

  相關內容如下


 

  

openid轉換接口

賬號遷移後,粉絲的openid會變化,微信用戶關注不同的公眾號,對應的openid是不一樣的,遷移成功後,粉絲的openid以目標帳號(即新公眾號)對應的OpenID為準。但開發者可以通過開發接口轉換openid,開發文檔可以參考:
提供一個openid轉換的API接口,當帳號遷移後,可以通過該接口:
1. 將原帳號粉絲的openid轉換為新帳號的openid。
2. 將有授權關係用戶的openid轉換為新帳號的openid。
3. 將卡券關聯用戶的openid轉換為新帳號的openid。

◆ 原帳號:準備要遷移的帳號,當審核完成且管理員確認後即被回收。
◆ 新帳號:用來接納粉絲的帳號。新帳號在整個流程中均能正常使用。

一定要按照下面的步驟來操作。
1. 一定要在原帳號被凍結之前,最好是準備提交審核前,獲取原帳號的用戶列表。如果沒有原帳號的用戶列表,用不了轉換工具。如果原賬號被回收,這時候也沒辦法調用接口獲取用戶列表。
如何獲取用戶列表見這裡://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140840

2. 轉換openid的API接口如下,可在帳號遷移審核完成後開始調用,並最多保留15天。若帳號遷移沒完成,調用時無返回結果或報錯。帳號遷移15天後,該轉換接口將會失效、無法拉取到數據。
◆ URL://api.weixin.qq.com/cgi-bin/changeopenid?access_token=xxxxx
此處token為新帳號的token
◆ 請求方式:post
◆ 請求數據:
{
“from_appid”:”xxxxxxxx”,//此處為原帳號的appid
“openid_list”:[“oEmYbwN-n24jxvk4Sox81qedINkQ”,”oEmYbwH9uVd4RKJk7ZZg6S
zL6tTo”]//需要轉換的openid,即第1步中拉取的原帳號用戶列表,這些必須是舊賬號目前關注的才行,否則會出錯;一次最多100個,不能多。
}
◆ 輸出數據:
{
“errcode”: 0,
“errmsg”: “ok”,
“result_list”: [
{
“ori_openid”: “oEmYbwN-n24jxvk4Sox81qedINkQ”,
“new_openid”: “o2FwqwI9xCsVadFah_HtpPfaR-X4”,
“err_msg”: “ok”
},
{
“ori_openid”: “oEmYbwH9uVd4RKJk7ZZg6SzL6tTo”,
“err_msg”: “ori_openid error”//這個openid目前沒有關注舊公眾號
}
]
}
◆ 錯誤碼:
63178:from_appid參數錯誤,和調用的賬號並沒有遷移關係
Ori_openid error:openid目前沒有關注舊公眾號。或者是將from_appid搞錯了,用成了新帳號的appid。

 

 
其中我認為比較重要的內容標註了顏色 ,希望你要遷移的賬號滿足他的條件 
下面是我寫到相關實現代碼 
 1  public function getOpenId(){
 2         $rows='100';
 3         $page=input('id');
 4         $info=\db('users')->paginate($rows,'',['page'=>$page]);
 5         $data= $info->items();
 6         $open_id=array_column($data,'openid');
 7        // dump($open_id);
 8 
 9         $postData['from_appid']='******'; //老的APPID
10         $postData['openid_list']=$open_id;
11         $config=[
12             'app_id'  => '*******',         // 新的AppID
13             'secret'  => '***********',
14         ];
15         $Wechat=new Application($config);//這裡用是Easywechat
16         $Token=$Wechat->access_token;
17         $token=$Token->getToken();
18         19         $url='//api.weixin.qq.com/cgi-bin/changeopenid?access_token='.$token;
20         //$result=    $this->curlPost($url,json_encode($postData,true),'','','json');
21         $result=    $this->post_by_curl($url,json_encode($postData,true)); //自己找一個curl方法
22         $return=json_decode($result,true);
23         $result=$return['result_list'];
24 
25         foreach ($result as $k=>$v){
26            27             if ($v['err_msg']=='ok'){
28                 $update['openid']=$v['new_openid'];
29                 $update['is_update']=1;
30                 \db('users')->where('openid',$v['ori_openid'])->update($update);
31             }
32         }
33     }

 

 

 

     需要注意的是 這個接口一次只能獲取100條數據 , 話句話說 你只能一次一百條一百條的更新

            當然 你可以選擇用消息隊列進行處理這個數據   但是我選擇的是比較簡單的方法 : 前台頁面定時器請求

    下面附上html代碼 

    

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <script src="/static/js/jquery.js"></script>
 4 <head>
 5     <meta charset="UTF-8">
 6     <title>Title</title>
 7     <div id="test">1</div>
 8 </head>
 9 <body>
10         <script>
11             var i=1;
12             function  test(){
13                 var url='//百度/portal/test/getOpenId/id/'+i
14                 $.ajax({
15                     url:url,
16                     type:'GET',
17                     success:function (res) {
18                         $('#test').html(i)
19                     }
20                 })
21                 i++;
22             }
23             window.setInterval(test,5000);
24         </script>
25 </body>
26 </html>

 

  不過這個時間會比較長

  

    我寫完博客才更改了4萬條 你可以看一下你服務器的響應執行速度  適當的調整這個參數