微信公众号教程(11)公众账号接收非文字消息

公众账号接收非文字消息

在微信公众平台上用户都是用使用文字在进行交互的,但是有时候使用图片、语音、视频以及地理位置等可以实现一些非常棒的功能,比如“语音提醒”公众号里的发送语音就可以实现定时的事件提醒功能;比如ZTalk曾经搞过微信拍照晒电脑桌面的活动(响应的人太少,桑心……);比如一些预定本地化服务的公众号里发送当前地理位置就可以查询周边商家。

要实现这些功能首先得学会接收这些消息类型,比文字消息类型肯定要复杂很多了,目前我们能够接收的消息类型只有图片、地理位置以及退订消息,其他的如链接消息、语音消息是需要官方授权的。接收到用户消息以后回复的消息类型可以参考第11章,目前也就那三种。

一、图片消息接收

 

相信拍照是目前智能手机用户用得最多的功能没有之一,在微信里也是一样,看看每天朋友圈里分享的那些照片就知道了,那么如何接收和保存用户照片捏,首先我们得了解用户发送的图片消息结构,如下图:

大家可以看到图片消息除了固定的消息发送用户ID、接收公众号ID、生成时间等固定字段外,多了一个图片链接PicUrl,这个就是用户向公众账号发送图片后,保存到微信的服务器上返回给公众号的链接,该图片链接格式如下:

也就是说我们如果要把图片保存到本地服务器,就要先将图片从微信服务器上抓取下来,当然你也可以直接保存这个链接以后直接访问,这个看具体应用了。今天要讲的是图片保存到本地服务器上,请看下面代码:

由于图片消息是另一种消息类型,因此代码添加位置可以位于文字消息上面或者下面,只要别在文字消息的判断语句内就行。然后我来解释下每个语句的作用:

第20行,判断消息类型是否为图片消息,条件为$form_MsgType==image;

第24行,获取图片消息数据中的图片链接并赋值给$from_PicUrl;

第26行,生成要保存到本地服务器的图片名称,为了避免重复新图片命名使用了发送用户的OPENID+当前时间戳,文件的后缀名我是直接设定为jpg文件。(由于从图片链接上无法获取到图片后缀名,又懒得通过头文件获取图片格式,就直接固定死了JPG格式,貌似没有什么问题,哈哈哈);

第28行,SAE上的内置接口类很多,SaeFetchurl是一个用来抓取远程网页的类,使用这个类就可以很方便的实现抓取其他网站的内容,否则使用PHP的curl或者file_get_contents这些估计还得解释半天,这句代码是新建一个抓取类的对象。

第30行,执行抓取图片链接,其中抓取的函数是fetch(),图片链接是之前赋值的$from_PicUrl,抓取后的结果赋值给$res;

第32行,判断抓取结果,errno()返回的是抓取结束后的错误代码,如果为0则成功,其他的就是不成功。

第35行,图片抓取成功后,新建一个Storage的对象,我们要保存图片了。

第37行,这句代码其实已经在以前出现多次,这次将抓取的内容($res)写入指定的文件($filename),并保存到Storage里,请注意把“weixincourse”替换成自己创建的Storage空间名

第39行到41行,保存成功后给用户提示图片上传成功。

第45行到48行,文件没有抓取到提示用户图片上传失败。

当然我们如果严谨一点,还要判断图片文件是否保存成功,可以把第37行后面改写一下,如下图:

大家可以尝试把Storage的空间名字故意写错,看看会有什么样的提示。如果提示上传成功,我们到SAE的Storage列表里就应该可以看到刚上传的文件了。

二、地理位置消息接收

 

手机上基于地理位置的APP很多,是个应用现在都得跟LBS扯上点关系,SoLoMo里重要的一环就是地理位置,微信里也有很多应用是跟地理位置相关的,比如查个本地天气、附近酒店餐馆啥的。今天举的例子是查本地天气。先了解下地理位置消息的结构,如下图:

地理位置消息多了四项,分别是经纬度的X和Y坐标、地图缩放比例以及地址信息,而实际上由于网络原因我们经常是收不到地址信息的,只有坐标信息,因此地理位置的开发基本围绕着坐标来。先来看本地天气查询代码吧,如下图:

代码添加位置同图片消息,另起一个消息类型判断语句,可以放在图片消息前面或者后面。前面说了我们主要使用的是经纬度,经纬度是可以通过一些地图api接口来获取实际地址、周边商家等信息的,天气代码这里我用的是百度地图API接口,主要是因为它有URL接口,代码解释开始:

第21行,消息类型判断语句,消息类型为location;

第24行到27行,将用户推送地理消息的经纬度、地图比例、地址信息分别赋值。经纬度分别为Location_X和Location_Y,相当于用经线和纬线的交叉点来标注地理位置。Scale是用户发送地理位置时地图的缩放比例。Label是地址信息(经常是获取不到的,获取了也没啥用,因为都是连在一起的,无法提取地市县信息)。

第29行,定义百度地图API接口的反向地址解析URL,反向地址解析是指通过经纬度获取当前位置的地址信息。

第31行,由于各家地图不一样因此传输过来的经纬度也会有所偏差,这里我选的是wgs84即手机GPS的坐标。

第33行,又要抓页面了,先建个抓取类的对象。

第35行,百度地图API接口的反向地址解析规则是URL+坐标类型+坐标值,其中$map_api_url.$map_coord_type两个变量拼接就是URL+坐标类型,然后再加上经纬度参数,用location=经度,纬度来赋值。

这里说下URL的规则,URL就是大家常看到的网页链接,一般由HTTP://后面加网址加参数组成,主要说下参数,参数一般是“参数名=赋值”组成,普通的URL参数格式是跟在网址后面第一个参数前用“?”号分隔,第二个参数开始用“&”分隔,参数在程序里是可以获取到的,我们上面获取坐标解析的实际地址形式为:


接收的实际地址为http://api.map.baidu.com/geocoder,获取到的参数是coord_type和location,值为相应后面跟着的。

第37行,判断是否抓取成功,如果抓取成功$geocoder的数据实际是如下格式:

这里一大堆信息里只需要提取城市,即CITY这个标签内的数据。

第40行,这是一个正则表达式,比较复杂,作用就是根据规则将$geocoder里的<city>北京市</city>数据提取出来赋予$city这个变量,如果成功这个数据是会是一个多维数组,其中city标签内的数据即北京市是存储在$city[1][0]里的,$city[0][0]的值是“<city>北京市</city>”;

第41行,将$city[1][0]的值即“北京市”提取出来,同时使用str_replace函数将“市”替换掉再重新赋值给$city,str_replace按照字面意思就是字符串替换,用法是:str_replace(要替换的内容,替换成的内容,字符串);其中替换的内容和替换成的内容可以使用数组,也可以使用单个字符串,我这里是用了数组,即将市县区都替换成了空,替换的用处是因为后面查天气预报的接口只支持城市名称,不能有市县区啥的……经过这一步$city的值就是“北京”;

第43行,定义天气API接口的URL;

第45行,做了三件事,第一个使用iconv()函数将$city的字符编码从UTF-8转换成GBK,第二件是使用urlencode将汉字转换成英文编码方便URL传值,第三件是将URL中的“&city=”的参数名拼接了。

关于字符,有时候我们上网的时候会发现网页有乱码,大部分是因为字符编码不对造成的,可以调节浏览器的编码来切换,在程序里也是一样,由于新浪接口接收的字符串是GBK的,而我们程序里使用UTF-8,所以需要转码后才能通讯,否则新浪接口收到的就是乱码。

 

PS:GBK或者GB2312是中文简体编码,属于ANSI编码,但是同个ANSI编码值在不同国家的编码对应是不同的文字,会非常混乱,所以有了Unicode以及UTF-8,这是国际通用的文字编码格式,所有文字都被分配了不同的编码,也就不怕乱码了。

第46行,查询天气日期,0表示当天,1表示明天,以此类推……

第49行,抓取天气内容并赋值给$weather,这里不需要再建立抓取类的对象了,因为之前已经建立了可以直接用。

第51行,判断是否抓到天气,这里我多加了一个

strstr函数是用来检查$weather里是否存在“Weather”这个字符串,&&表示并且,这里的判断就是不仅要抓取成功并且在抓取到的内容里存在“Weather”。这样写的目的是因为新浪天气接口不管有没有查询到天气都会返回数据,而判断数据里是否有天气信息,只有判断返回内容里有木有“Weather”这个字符串。成功抓取到的会是如下内容:

这又是一个XML,然后用的是一些拼音首字母做了标签,把这个回复给用户估计会疯的,我们要进行一些整理,方法嘛就是用正则表达式来提取我们需要的内容,我这里提取的标签是city(城市)、status2-status1(天气变化)、temperature2-temperature1(温度变化)、direction2-power2(风向风力)、chy_shuoming(穿着建议)、savedate_weather(信息发布时间)

第54行到62行就是提取这些数据的正则表达式,可以发现其实改动的只是标签名和赋值的参数,如果大家还想加写数据的可以参照着提取;

第64行到71行判断天气变化是否相同,比如上面显示的天气1和天气2其实都是阴,如果不做判断就会返回给用户“阴转阴”,非常2,所以这里判断如果两个天气是一致的则将任意一个天气赋值给$w_status变量,否则就按照天气2转天气1赋值给$w_status变量,最后输出时用$w_status这个变量。

第73行到81行新建一个数组,将前面获取到的天气数据添加为数组元素,格式就是$weather_res=array();然后在括号里用逗号分割每个天气数据,最后一个后面不要加逗号,这样做的好处是避免代码行过长,而且很清晰。

第82行,将数组用implode()函数转化成数组,用"\n"这个换行符来分割。

其实73到82行完成的就是将所有数据拼接成一个字符串,使用“.”一个个拼也可以,不过效率低下而且代码也不够清晰。

全部拼接完成就可以输出了,在手机上效果如下:

后面的就不详细说了,都有标注,都是些判断提示语句,大家可以自己学着看,不懂的可以直接在后台问。另外强调一点,一般天气预报是拿中国天气网接口做的会比这个更好,能够显示县区级的天气,但是需要搞个城市代码表,留到以后说吧,新浪的接口可以直接用城市名查就先演示下。

三、退订消息接收

 

不知道还有多少人记得我曾写过一篇《那些离开的朋友们》,是因为微信把退订消息接口开了,每天看到不少人退订心里有点小难过写的,到今天我看了下差不多有2000个退订用户了,估计是我现在写的东西不合他们胃口。

退订消息接口的代码很简单,跟用户订阅一样是一个事件类型的消息,只是事件类型的标示是”unsubscribe“,退订用户最好是配合数据库来记录,我这里给大家的是一个保存成文件的例子,如下图:

代码添加的位置请看仔细了,在事件消息判断里的获取事件类型之后。代码很短,解释如下:

第300行,判断事件类型标示是否为”unsubscribe“,大家可以看下订阅消息是”subscribe“;

第303行,新建一个Storage的对象;

第305行,写入文件,文件名为退订用户的OPENID,文件后缀是.txt,内容我用了退订时间。

当用户退订后在Storage的存储空间里就会有一个文件生成。

微信公众平台开发的基础教程差不多已经讲完,后面还会讲下数据库和云存储平台的使用,然后就会是完整案例,之所以花那么长时间讲那么细,是希望大家能够先熟悉一些基础的编程,有一个循序渐进的过程,所有复杂的程序其实都是这些基础模块组成,如果你觉得看不懂,那可能是没有跟着动手做,后面的教程估计会跟不上,so,有时间就动动手吧!anyway,我会把教程坚持写完,因为很多人有期待。

时间: 2024-10-06 02:15:44

微信公众号教程(11)公众账号接收非文字消息的相关文章

用java开发微信公众号:测试公众号与本地测试环境搭建(一)

俗话说,工欲善其事,必先利其器.要做微信公众号开发,两样东西不可少,那就是要有一个用来测试的公众号,还有一个用来调式代码的开发环境. 测试公众号 微信公众号有订阅号.服务号.企业号,在注册的时候看到这样的信息,只有订阅号可以个人申请,服务号和企业号要有企业资质才可以.这里所说的微信公众号开发指的是订阅号和服务号. 另外,未认证的个人订阅号有一些接口是没有权限的,并且目前个人订阅号已不支持微信认证,也就是说个人订阅号无法调用一些高级的权限接口,下图就是一个未认证的个人订阅号所具备权限列表,像生成二

用公众号获取 任意公众号文章列表 软件还是免费

用公众号获取 任意公众号文章列表 软件还是免费还不快点下载 下载 地址  https://pan.baidu.com/s/1jI44Wjs

微信公众号教程(9)公众账号发送欢迎图文消息

第十章 公众账号发送欢迎图文消息 昨天已经讲了如何实现用户订阅公众账号时发送欢迎词,但这个貌似体现不出开发模式的优势啊,我用编辑模式做不是更加简单嘛,那么今天就来个升级版的欢迎词吧.先看最后的效果,如下图: 当用户关注公众账号时自动回复一个多图文消息,每个图文消息可以对应一篇文章或者自己网站的某个网页,用户点击就可以查看,是不是非常棒,特别适合一些企业用来做公司业务介绍.现在就教大家如何实现,顺便就可以把图文消息的回复讲了. 一.使用SAE的分布式存储服务 在编辑模式里做图文消息回复时,直接通过

微信公众号教程(10)公众账号自定义回复功能

公众账号自定义回复功能 微信官方其实并不推荐经常群发消息,更多的是希望用户通过对话来自己获取服务或者进行搜索.今天我们就讲下如何使用开发模式做自定义回复. 目前公众账号可以接收的用户提交消息请求有四种类型,分别是文字.图片.地理位置和链接,而公众账号回复只有三种格式,文字.图文和音乐,也就是说用户互动的模式最多也就是12种,我们今天先讲三种即文字回复文字.文字回复图文.文字回复音乐. 这强调一下,微信的消息接口通讯有效时间是5秒,也就是说网络不稳定等原因很容易造成用户在5秒内接收不到回复消息,然

微信公众号教程(1)微信公众账号注册、设置、登陆

原文:http://www.cnblogs.com/imaker/p/6247323.html 从今天开始微信公众平台教程开写,前面部分会比较浅,已经在玩的朋友可以忽略. 第一章 微信公众账号注册.设置.登陆 一.微信公众平台注册   注册前的准备工作,很重要!   1.一个没有注册过公众账号的邮箱,如果是qq邮箱那么对应的qq号也要没有注册过公众账号.顺便提一下,公众账号用gmail邮箱邮箱是注册不了的,只有国内邮箱才能注册成功!   2.身份证扫描件,每个身份证可以注册5个公众账号   3.

微信公众号教程(8)用微信开发模式做欢迎词

第九章 用微信开发模式做欢迎词 今天的重点是如何将微信开发模式和SAE对接,希望朋友们已经完成了SAE注册,如果还没搞定的话请抓紧,有问题的话请及时提出,接下来的教程都在那上面进行. 在教程开始前建议朋友们可以先注册一个新的公众账号,或者用非主账号当做开发测试账号,因为开发调试过称中可能会经常出现账号无法正常回复用户的情况,影响正常使用,所以在学习期间以及后期开发过程中最好有一个测试公众账号,等开发完成了再切换到主账号上,也是非常方便的. 一.微信公众平台与SAE对接通讯   我们先回到微信公众

微信公众号教程(3)微信公众平台群发消息

微信公众平台最常用到的就是群发消息,这种一对多.几乎百分百到达的传播方式,取代了短信群发,并且具有多媒体形态,还可以直接引导转化.因此编辑一条好的内容,挑选恰当的时候发送,既可以给用户带来有价值的信息,又有机会给公众账号带来新的关注和收益.本期将重点为大家讲解素材管理该怎么玩,群发消息需要注意些什么. 第三章 微信公众平台群发消息 一.微信公众平台后台素材管理   点击公众平台后台导航的"素材管理",或者在群发消息或者与用户聊天页面时,选择发送多媒体内容时快捷进入.这个页面主要是用来管

微信公众号开发(2)---接收订阅事件推送并回复消息

在thinkphp框架内完成的,下面是控制器页面(不涉及其他页面) <?PHP namespace Home\Controller;use Think\Controller; class IndexController extends Controller {    //token验证,微信服务器发送post请求过来    public function index(){      $timestamp = $_GET["timestamp"];//a时间戳      $nonc

教程:如何申请公众号和创建公众号?

在注册微信公众号前首先要准备: 1.一个没有注册过公众账号的邮箱,如果是qq邮箱那么对应的qq号也要没有注册过公众账号. 2.×××扫描件,每个×××可以注册5个公众账号 3.手机,用来接受注册验证码,每个手机也只能验证5个公众账号 4.想好公众账号名称,非常重要,一旦申请成功名称不能修改,并且该名称最好与已获得认证的腾讯微博名称相同,等公众号到500粉丝后可以自助认证. 准备工作做好后可以进入微信公众平台官网,点击立即注册进入注册页面(PS只能在电脑端注册,移动端目前不支持) 选择注册类型 注