V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
laoyu
V2EX  ›  程序员

求帮忙看下微信公众平台接口的代码

  •  
  •   laoyu · 2013-03-25 22:34:47 +08:00 · 4492 次点击
    这是一个创建于 4291 天前的主题,其中的信息可能已经有所发展或是发生改变。
    因为微信公众平台26号更新,所以怕以下代码失效。

    “新用户订阅,将由之前推送一条“Hello2BizUser”文本,变化为推送一条“subscribe”的事件。”

    不懂这个,哪问朋友指点一下该怎么改,应该会受影响吧。



    ===================代码如下=====================




    <?php
    /*
    Plugin Name: 微信公众平台搜索插件
    Plugin URI: http://ftqq.com/
    Description: 微信公众平台插件,允许用户通过微信关键字获取相关的文章内容。假设当前wordpress的地址为http://ftqq.com,那么安装完插件后,在微信中需要填写的接口地址为http://ftqq.com/wp-content/plugins/wx-search/wx-search.php
    Version: 1.0
    Author: [email protected]
    Author URI: http://ftqq.com
    License: BSD
    */


    // 此token必须和微信公众平台中的设置保持一致
    // 设置页面 http://mp.weixin.qq.com/cgi-bin/callbackprofile?t=wxm-callbackapi&type=info&lang=zh_CN
    define("TOKEN", "xxxxx");


    // 此图片用于搜索出来的文章不包含图片时的默认图片,直接从wordpress的媒体库中挑一张即可。
    // 采用相对路径
    define("DEFAULT_COVER", "/#");

    define("WELCOME" , "欢迎您......");

    // 假设当前wordpress的地址为http://ftqq.com,
    // 那么安装完插件后,在微信中需要填写的接口地址为http://ftqq.com/wp-content/plugins/wx-search/wx-search.php


    // 以下内容不需要改动

    $wechatObj = new wechatCallbackapiTest();


    if( isset($_REQUEST['echostr']) )
    $wechatObj->valid();
    elseif( isset( $_REQUEST['signature'] ) )
    {
    chdir('../../../');
    include( 'wp-load.php' );
    $wechatObj->responseMsg();
    }



    class wechatCallbackapiTest
    {
    public function valid()
    {
    $echoStr = $_GET["echostr"];

    //valid signature , option
    if($this->checkSignature()){
    echo $echoStr;
    exit;
    }
    }

    public function responseMsg()
    {
    //get post data, May be due to the different environments
    $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

    //extract post data
    if (!empty($postStr)){

    $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
    $fromUsername = $postObj->FromUserName;
    $toUsername = $postObj->ToUserName;
    $keyword = trim($postObj->Content);
    $time = time();

    if(!empty( $keyword ))
    {
    //file_put_contents( 'keyword.txt' , $keyword );

    if($articles = ws_get_article( $keyword ))
    {
    ob_start();
    ?><xml>
    <ToUserName><![CDATA[<?=$fromUsername?>]]></ToUserName>
    <FromUserName><![CDATA[<?=$toUsername?>]]></FromUserName>
    <CreateTime><?=$time?></CreateTime>
    <MsgType><![CDATA[news]]></MsgType>
    <Content><![CDATA[搜索结果]]></Content>
    <ArticleCount><?=count($articles)?></ArticleCount>
    <Articles><?php foreach( $articles as $item ): ?>
    <item>
    <Title><![CDATA[<?=$item['title']?>]]></Title>
    <Description><![CDATA[<?=$item['content']?>]]></Description>
    <PicUrl><![CDATA[<?=$item['pic']?>]]></PicUrl>
    <Url><![CDATA[<?=$item['url']?>]]></Url>
    </item>
    <?php endforeach; ?></Articles>
    <FuncFlag>0</FuncFlag>
    </xml><?php
    $xml = ob_get_contents();
    //file_put_contents('xml.txt', $xml);
    header('Content-Type: text/xml');
    echo trim($xml);

    }else
    {
    if( $keyword == 'Hello2BizUser' )
    {?>
    <xml>
    <ToUserName><![CDATA[<?=$fromUsername?>]]></ToUserName>
    <FromUserName><![CDATA[<?=$toUsername?>]]></FromUserName>
    <CreateTime><?=time()?></CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[<?=WELCOME?>]]></Content>
    </xml>
    <?php }
    else{
    ?>
    <xml>
    <ToUserName><![CDATA[<?=$fromUsername?>]]></ToUserName>
    <FromUserName><![CDATA[<?=$toUsername?>]]></FromUserName>
    <CreateTime><?=time()?></CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[没有找到包含关键字的文章,试试其他关键字?]]></Content>
    </xml>
    <?php
    } }
    }else{
    echo "请输入关键字,我们将返回对应的文章...";
    }

    }else {
    echo "";
    exit;
    }
    }

    private function checkSignature()
    {
    $signature = $_GET["signature"];
    $timestamp = $_GET["timestamp"];
    $nonce = $_GET["nonce"];

    $token = TOKEN;
    $tmpArr = array($token, $timestamp, $nonce);
    sort($tmpArr);
    $tmpStr = implode( $tmpArr );
    $tmpStr = sha1( $tmpStr );

    if( $tmpStr == $signature ){
    return true;
    }else{
    return false;
    }
    }
    }

    function ws_get_article( $keyword , $limit = 10 )
    {
    query_posts( array( 's' => $keyword ) );
    $i = 0;
    $results = array();
    while( have_posts() && ($i < 10) )
    {
    the_post();
    $result['title'] = get_the_title();
    $result['content'] = mb_strimwidth(get_the_content() , 0 , 200 , '...' , 'UTF-8' );
    $result['url'] = get_site_url().'/?p='.get_the_id();
    $result['pic'] = thumbnail_url(get_the_post_thumbnail());
    if( !$result['pic'] ) $result['pic'] = get_site_url(). DEFAULT_COVER;



    $results[] = $result;
    $i++;
    }

    if( count( $results ) > 0 ) return $results ;
    else return false;

    }

    function thumbnail_url( $html )
    {
    $reg = '/src="(.+?)"/is';
    if(preg_match( $reg , $html , $out ))
    {
    return $out[1];
    }

    return false;
    }
    25 条回复    1970-01-01 08:00:00 +08:00
    wzxjohn
        1
    wzxjohn  
       2013-03-25 23:22:12 +08:00   ❤️ 1
    if( $keyword == 'Hello2BizUser' )
    这一句改为
    if( $keyword == 'subscribe' )
    laoyu
        2
    laoyu  
    OP
       2013-03-25 23:30:02 +08:00
    @wzxjohn 多谢了,我本来也想这样直接改,可是不懂,多谢多谢
    wzxjohn
        3
    wzxjohn  
       2013-03-25 23:38:17 +08:00
    @laoyu 等等。。。我仔细看了一下文档好像这么改不行。。。微信引入了事件机制之后估计代码要大改。我再看看。。。
    laoyu
        4
    laoyu  
    OP
       2013-03-25 23:41:57 +08:00
    @wzxjohn 好的 多谢您。
    laoyu
        5
    laoyu  
    OP
       2013-03-26 00:47:44 +08:00
    先睡了,明天要起早,如果比较容易的话,希望知道的朋友帮帮忙,多谢大家。
    Lucius
        6
    Lucius  
       2013-03-26 14:37:20 +08:00
    同问
    wzxjohn
        7
    wzxjohn  
       2013-03-26 14:54:56 +08:00   ❤️ 3
    @laoyu
    @Lucius
    $keyword = trim($postObj->Content);
    这一句做修改,改为
    if ($postObj->MsgType == "event")
    {
    $keyword = trim($postObj->Event);
    }
    else
    {
    $keyword = trim($postObj->Content);
    }
    同时,将
    if( $keyword == 'Hello2BizUser' )
    这一句改为
    if( $keyword == 'subscribe' )
    完毕。
    laoyu
        8
    laoyu  
    OP
       2013-03-26 15:33:00 +08:00
    @wzxjohn 真心感谢,我虽然还没改,但是以前的代码还能用,不知道更新了什么。
    Lucius
        9
    Lucius  
       2013-03-26 15:52:48 +08:00
    @wzxjohn
    非常感谢! 测试成功
    tempdban
        10
    tempdban  
       2013-03-26 15:54:25 +08:00 via iPhone
    @wzxjohn 我要是直接回复subscribe呢 这功能逻辑不就混乱了么……
    Lucius
        11
    Lucius  
       2013-03-26 15:56:18 +08:00
    @wzxjohn

    就是用户第一次关注的时候 之前是推送一条“Hello2BizUser”文本给你
    26号变化为推送一条“subscribe”的事件。

    必须相应修改,第一次关注后 公共账号才会将 WELCOME "欢迎您......"这句话发送给用户
    Lucius
        12
    Lucius  
       2013-03-26 15:56:57 +08:00   ❤️ 1
    @laoyu

    就是用户第一次关注的时候 之前是推送一条“Hello2BizUser”文本给你
    26号变化为推送一条“subscribe”的事件。

    必须相应修改,第一次关注后 公共账号才会将 WELCOME "欢迎您......"这句话发送给用户
    laoyu
        13
    laoyu  
    OP
       2013-03-26 15:57:31 +08:00
    @tempdban 这个subscribe是指的什么?求教
    Lucius
        14
    Lucius  
       2013-03-26 15:59:35 +08:00
    @tempdban

    @wzxjohn 的这个改法似乎不是微信这次改动的本意,只是把XML里面的subscribe事件转换成subscribe文本 不过对普通用户的体验来说应该是没什么影响啦~
    Lucius
        15
    Lucius  
       2013-03-26 16:02:52 +08:00
    @laoyu subscribe是一个事件类型 用来识别用户目前有没有关注这个公众账号
    Lucius
        16
    Lucius  
       2013-03-26 16:10:14 +08:00
    @tempdban
    把if( $keyword == 'Hello2BizUser' )改成if ($postObj->MsgType == "event")
    应该就没有逻辑错误了吧
    yyl1987611
        17
    yyl1987611  
       2013-03-26 16:14:05 +08:00
    @laoyu 收到啊对萨撒旦
    laoyu
        18
    laoyu  
    OP
       2013-03-26 16:32:20 +08:00
    @Lucius 恩,我没试 确实直接回复subscribe 回返回欢迎文字
    tempdban
        19
    tempdban  
       2013-03-26 16:43:02 +08:00 via iPhone   ❤️ 1
    @Lucius 大哥 不是有意挑刺 event里不止subscribe吧 真么弄给人感觉好凑合
    wzxjohn
        20
    wzxjohn  
       2013-03-26 20:17:25 +08:00 via iPad
    @laoyu
    @Lucius
    一般看不出效果。你可以取消关注然后再关注一次就可以了。


    @tempdban
    event里面确实不止subscribe,但是一般的公众帐号只能用到这个。。。而且考虑一般用户不会直接发送subscribe所以我认为这样就可以了。。。当然最好是把判断写全。。。
    tempdban
        21
    tempdban  
       2013-03-26 23:03:31 +08:00 via iPhone
    @wzxjohn 恩 我有个问题 你们平时是怎么测试的呢 直接用生产环境
    laoyu
        22
    laoyu  
    OP
       2013-03-26 23:08:16 +08:00
    @tempdban 开小号,我只会用这种最笨的办法。
    wzxjohn
        23
    wzxjohn  
       2013-03-27 08:37:55 +08:00
    @tempdban
    开小号+1。不然没办法。我手里有一堆微信号= =|||
    wzxjohn
        24
    wzxjohn  
       2013-03-27 08:42:16 +08:00
    @Lucius

    $keyword = trim($postObj->Event);
    改成
    if ($keyword == "subscribe")
    {?>
    <xml>
    <ToUserName><![CDATA[<?=$fromUsername?>]]></ToUserName>
    <FromUserName><![CDATA[<?=$toUsername?>]]></FromUserName>
    <CreateTime><?=time()?></CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[<?=WELCOME?>]]></Content>
    </xml>
    <?php }

    同时将
    if( $keyword == 'Hello2BizUser' )
    这段删去就可以了。把event类型的消息提前处理掉,还能省去搜索文章的时间。
    @laoyu
    itommy
        25
    itommy  
       2013-03-27 12:16:46 +08:00
    @wzxjohn
    @laoyu
    @tempdban
    为什么不在local上测试这个?写个class就可以在browser里面测试啦。而且如果你把token和$postObj->ToUserName 也加进去一个接口可以对应无数个微信号。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1116 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 18:51 · PVG 02:51 · LAX 10:51 · JFK 13:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.