Author: root

  • 微信订阅号的开发

    最近看了一下微信订阅号的开发。

    我要做一个个人订阅号,用户订阅之后,可以通过输入命令获得交互,得到英文单词的解释,大概就是这样。

    微信开发权限获得就不讲了,需要帮助的同学可以去访问相应的站点。

    首先,我开了一个域名(http://weixin.rsywx.com) 作为和微信通讯的接口。

    按照微信的说法,用户输入命令后,该接口将“被动”地回复信息。而这也是我这个订阅号和用户交互的主要渠道。

    在weixin.rsywx.com中,我用Silex框架构建了我的应用。这是因为我需要在这个框架中进行一些控制。当然你也可以用一个plain PHP文件来完成这个接口的工作。 该应用的入口文件很简单:

    require_once __DIR__ . '/../vendor/autoload.php';
    require_once __DIR__ . '/./WechatCallbackAPI.php';
    $app = new Silex\Application();
    $app['debug'] = true;
    // Twig registration
    $app->register(new Silex\Provider\TwigServiceProvider(), ['twig.path' => __DIR__ . '/../views']);
    $app->post('/', function () use ($app)
    {
        $obj=new WechatCallbackAPI();
        echo $res=$obj->response($app);
    });
    $app->run();

    其中的Twig注册不是必要的,因为微信要求的回应是一个XML字符串。不过放进去也没有关系。 对于“/”这个路径,我们在响应微信的请求时必须使用POST方式。同时我们创建了一个对象,并调用response方法来返回消息。 在WechatCallbackAPI中,我们抄袭微信的实例代码并作一些改进:

    public function response($app)
        {
            $post=$GLOBALS['HTTP_RAW_POST_DATA'];
            //$post=file_get_contents('php://input');
            if(!empty($post))
            {
                libxml_disable_entity_loader(true);
                $obj=simplexml_load_string($post, 'SimpleXMLElement', LIBXML_NOCDATA);
                $from=$obj->FromUserName;
                $to=$obj->ToUserName;
                $key=strtolower(trim($obj->Content));
                if($key==?||$key==?||$key=='help')
                {
                    $wpme=new WPME($from, $to);
                    $res=$wpme->help();
            return $res;
                }
                else if (substr($key, 0,4)=='wpme')
                {
                    $wpme=new WPME($from, $to);
                    $wpme->setKey($key);
                    $res=$wpme->invoke();
                    return $res;
                }
                else if(substr($key, 0,4)=='wotd')
                {
                }
                else
                {
                    $wpme=new WPME($from, $to);
                    $res=$wpme->unknown();
                    return $res;
                }
            }

    注意,这里还用到了一个在PHP 5.6中被标记为deprecated,而在PHP 7将是obsolete的功能:

    $post=$GLOBALS['HTTP_RAW_POST_DATA'];

    PHP手册中建议用

    <pre lang="php">$post=file_get_contents('php://input');

    但是经过测试似乎不行。微信就是这么任性。

    在该response函数中,我们根据不同的用户输入来调用不同的功能。上述代码中列出了WPME(Word Power Made Easy)模块中的判断。WPME模块中最重要的方法是invoke,它将根据不同的命令($key)去进一步调用不同的资源并构造返回值。而另外一些命令在WPME中直接处理,比如最简单的help方法:

    public function help()
        {
            $content = Available commands:\nwpme1: Latest WPME\nwpme7: Last 7 WPMEs\nwpme????: Search WPME for ????;
            $res = sprintf(WPME::$txtTemplate, $this->from, $this->to, time(), $content);
            return $res;
        }

    help将列出可以使用的命令,比如wpme1,然后渲染一个静态文本模板并返回。文本模块的格式可以参考微信文档。

    而invoke方法如下:

    public function invoke()
        {
            $uri = https://rsywx.net/wechat/ . htmlentities($this->key);
            $content = file_get_contents($uri);
            preg_match_all('/(.*?)<\/title>/i', $content, $matches);
            $res = sprintf(WPME::$newsTemplate, $this->from, $this->to, time(), $matches[1][0], date('Y-m-d'), $uri);
            return $res;
        }

    我们可以看到,我们的一般命令将返回图文信息。而图文信息的模板格式也请参考微信文档。这里我们并不进行任何实质性的处理,真正的内容渲染我们在另外一个站点:https://rsywx.net 中进行。

    rsywx.net是一个之前我单独开发的站点,考虑到微信使用的一些功能可以在该站点中复用,所以我将微信需要的返回信息的功能(控制、数据、呈现)放在这里实现。这个站点用Symfony完成。其实,我这个微信号最本质的内容呈现逻辑都是在rsywx.net中完成的。

    我们看一个indexAction方法。这个方法接受来自weixin.rsywx.com的调用,并根据不同的关键字进行处理:

    public function indexAction($key)
        {
            $entity = substr($key, 0, 4);
            if ($entity == 'wpme')
            {
                if ($key == 'wpme1' || $key == 'wpme7')
                {
                    $uri = http://api/$entity/$key;
                    $res = json_decode(file_get_contents($uri))->out;
                    $theme = $this->container->getParameter('theme');
                    return $this->render(AppBundle:$theme/wechat:$key.html.twig, ['res' => $res->res]);
                }
                else //The key is like wpme????, where ???? is the search term
                {
                    $search = substr($key, 4);
                    $uri = http://api/$entity/s/$search;
                    $res = json_decode(file_get_contents($uri))->out;
                    $theme = $this->container->getParameter('theme');
                    return $this->render(AppBundle:$theme/wechat:wpme7.html.twig, ['res' => $res->res]);
                }
            }
        }

    如果从weixin传来的命令是wpme1(列出最新的单词)或者wpme7(列出7个最新的单词),那么rsywx.net将进一步调用http://api.rsywx.com 中相应的RESTful API接口获得数据并渲染;如果是类似wpme????这样的命令,那么将进行搜索,并将结果返回。

    最后我们来看http://api.rsywx.com ,如果我们直接访问这个站点,将会呈现该站点所提供的所有接口的API文档:

    Ashampoo_Snap_2016.02.01_20h46m03s_002_Chrome

    而在这个站点中,我同样用Silex框架实现了对应的方法来返回数据(实际上,rsywx.net的所有数据也都是由该站点提供的)。

    好了,如果你现在在公众号中输入这样的一个命令:wpme1,你将看到如下的界面:

    Screenshot_20160201-205011

    Screenshot_20160201-205018

    怎么样?是不是很酷?

    本文收录于[go4pro.org]

  • 对独裁的抗争

    《The Death Of Caesar》是一本讲述历史上最著名的一次刺杀的书。

    ==========

    我们所学的历史基本只讲谁是凯撒,谁又在何时何地刺杀了他,然后安东尼和屋大维为凯撒复仇,最后屋大维又战胜了安东尼,成为新一代的凯撒。

    (more…)

  • 我关闭了微信朋友圈

    昨天决定关闭微信朋友圈。

    有这么几个原因。

    1. 关闭朋友圈不会影响我收发红包。
    2. 朋友圈的设计不是用来扩展朋友圈,而是限制朋友圈。
    3. 转发机制很不友好。
    4. 最近微信朋友圈推广的一些活动让我很不耻。

    不过我还是会维护微信订阅号。

  • 以法律和道德的名义

    自从这次著名的快播庭审之后,百度也持续地被黑(我是坚定的百度黑)。

    中国的互联网存在着一个特别之处:一方面是坚定不移地标榜着开放,并诞生了不少巨无霸的公司;另一方面又是坚定不移地封杀、屏蔽,并由此诞生了不少巨无霸公司。

    (more…)

  • 新年登高

    苏州人向来有新年登高之风俗。

    1月1日,和多年好友一家开车前往藏书。这也是我们两家保持了好几年的好习惯。我记得,13年是藏书吃羊肉加天平山,14年虽然没有去藏书但是去了东山宾馆,然后爬了东山。15年没有碰头,因为彼得去参加了击剑总决赛,所以16年我们再次相约。

    (more…)

  • 2015个人小结

    2015年即将过去,按照惯例,做个小结。

    (more…)

  • 我们的创新和无知

    我们是在一个创新的年代吗?似乎是的。

    至少,如果我们对财富的创造没有什么创新的话,对财富的再分配有了不少创新。

    最近有不少P2P理财的坏消息。我倒是一点都不意外:

    一个将资金投放到一个自己也不知道能不能创造财富的领域的理财产品,失败不是再正常不过的事情了吗?

    (more…)

  • 诚品小记

    昨天算是一个错位休息日。第一,我周五就开始休假;第二,老彼得学校因为要准备高考场地而进行电力改造所以周六上学,周一调休;第三,肾后带着老丈人和东北老舅一家跑去无锡小小地玩了一圈。

    而我呢,中午就跑去诚品觅食。

    IMG_20151212_122315

    到了书店,第一件事情是去找我的书——《缠绕的意念》,令我欣喜的是,诚品有卖!令我诅丧的是,我在“心理学”书架那里左右上下找了三圈愣是没有找到!

    (more…)

  • 啊哈!你这也能叫出书?

    前几天在诚品买的一本书《啊哈,灵机一动》其本身的内容还是很不错的,但是——我为什么又要说但是了呢——这本书的编辑实在是应该被拉出去枪毙20分钟!

    01830_啊哈,灵机一动_伽德纳_300

    (more…)

  • Becoming Steve Jobs

    这本书《Becoming Steve Jobs》比Isaacson的那本《史蒂夫·乔布斯传》要好看一些。主要原因是作者之一的Schlender采访乔布斯多年,手上累积了大量一手的资料,所以在选取时游刃有余,同时也因为他和其它与乔布斯同时代的IT巨擘有着良好的采访/被采访关系和/或私人关系,所以能从更多的角度、更多的来源对乔布斯进行描述。

    [01826_Becoming

    (more…)