微信公众号开发过程整理

温馨提示:为保证数据传输安全,提高业务安全性,公众平台将不再支持HTTP方式调用。避免影响正常使用中含有HTTP方式调用的服务,请开发者尽快调整,将现有通过HTTP方式调用的切换成HTTPS调用,平台将于2017年12月30日停止对HTTP方式调用的支持。

一、微信公众开发前期准备

 

  1.   申请公众号-微信公众号:

  2. 外网服务器资源(互联网可以访问到的),也就是说我们的后台应用要在互联网条件下访问到。

            先说下消息交互流程图:(http:80端口,https443端口)

                

         可以使用百度的BAE:免费申请而且不用维护,但是这样就不利于的本地调试。腾讯云:学生便宜

        其实我们只需要把我们的内网应用通过一个域名映射到公网即可,这里使用花生壳的域名工具,免费给你一个域名,通过添加映射的方式就可以了,具体操作如下图:

      

这样端口也是80的,应用名称不用去管,就把192.168.0.10:9088映射到了178b647i13.iask.in,可以自行测试一下。

 

  1.    配置微信平台的接口配置服务:

 

1)测试号的服务器配置:

       

  •         URL: 以上是测试号的配置,其中URL是开发者用来接收微信消息和事件的接口URL,http的端口号固定使用80,不可填写其他,https(443);

  •         Token:自主设置,这个token与公众平台wiki中常提的access_token不是一回事。这个token只用于验证开发者服务器

 

 

2)真实公众号配置服务器:

 

!说明:启用该配置后,原来设置的自动回复消息以及点击时间会被转发到这里了!只验证一次

 

在填写了该配置提交的时候:微信会立马就行该服务器安全性有效性的验证,具体验证流程如下图:

1)将token、timestamp、nonce三个参数进行字典序排序

2)将三个参数字符串拼接成一个字符串进行sha1加密

3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

二、消息推送和消息回复

  1. 消息推送:粉丝给公众号发消息,当普通用户向公众帐号发消息时,微信服务器将POST该消息(xml)到填写的URL上;(消息类封装暂时没用)

微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。

 

19:14:23,056 DEBUG Finalizer conn.DefaultClientConnection:169 - Connection 0.0.0.0:63825<->101.226.212.27:443 closed

19:14:23,104 DEBUG Finalizer conn.DefaultClientConnection:169 - Connection 0.0.0.0:64259<->58.246.220.31:443 closed

19:14:23,249  INFO http-bio-8081-exec-4 service.MessageService:42 - {MsgId=6482660711707982028, FromUserName=oyYFvw5agVtD6IQE9lA9Hu4HdkNY, CreateTime=1509362066, Content=公共, ToUserName=gh_eaf29fa02b4a, MsgType=text}

19:14:28,549  INFO http-bio-8081-exec-3 service.MessageService:42 - {MsgId=6482660711707982028, FromUserName=oyYFvw5agVtD6IQE9lA9Hu4HdkNY, CreateTime=1509362066, Content=公共, ToUserName=gh_eaf29fa02b4a, MsgType=text}

19:14:33,192  INFO http-bio-8081-exec-10 service.MessageService:42 - {MsgId=6482660711707982028, FromUserName=oyYFvw5agVtD6IQE9lA9Hu4HdkNY, CreateTime=1509362066, Content=公共, ToUserName=gh_eaf29fa02b4a, MsgType=text}

 

  • 文本消息示例:xml数据包 , 涉及技术xml解析:示例dom4j 源码示例。

 

 

 

<xml>

 <ToUserName><![CDATA[toUser]]></ToUserName>

 <FromUserName><![CDATA[fromUser]]></FromUserName>

 <CreateTime>1348831860</CreateTime>

 <MsgType><![CDATA[text]]></MsgType>

 <Content><![CDATA[this is a test]]></Content>

 <MsgId>1234567890123456</MsgId>

 </xml>

 

 

ToUserName

开发者微信号

FromUserName

发送方帐号(一个OpenID)

CreateTime

消息创建时间 (整型)

MsgType

text

Content

文本消息内容

MsgId

消息id,64位整型

 

 

OpenID :为了识别用户,每个用户针对每个公众号会产生一个安全的OpenID

 

  •   图片消息

<xml>

<ToUserName><![CDATA[toUser]]></ToUserName>

<FromUserName><![CDATA[fromUser]]></FromUserName>

<CreateTime>1348831860</CreateTime>

<MsgType><![CDATA[image]]></MsgType>

<PicUrl><![CDATA[this is a url]]></PicUrl>

<MediaId><![CDATA[media_id]]></MediaId>

<MsgId>1234567890123456</MsgId>

</xml>

 

 

ToUserName

开发者微信号

FromUserName

发送方帐号(一个OpenID)

CreateTime

消息创建时间 (整型)

MsgType

image

PicUrl

图片链接(由系统生成)

MediaId

图片消息媒体id,可以调用多媒体文件下载接口拉取数据。

MsgId

消息id,64位整型

 

   

 

特别说明:

 

PicUrl: 这个参数是微信系统把用户发送的图片消息自动转化成url。 这个url可用浏览器打开查看到图片。

      MediaId: 是微信系统产生的id 用于标记该图片,详情可参考wiki 素材管理/获取临时素材

 

 示例:发送图片的参数:

{MsgId=6482681349030657007,

FromUserName=oyU-W0c1DXqbgmL17_X0tMuXpz_0,

CreateTime=1509366871,

MediaId=CK8tkH-kpdVop5pBndX47KpoYDc9zJJdz-UUs5sVCUkeOcBqbeWFMfyKueJsbwQN,

PicUrl=http://mmbiz.qpic.cn/mmbiz_jpg/AcmwDUnD36FYicFicSEsjGr5VA1Tay2ZkQlX7Gyq786hmWdlFUj1CkYFSv7dUwduwIGVvMoBHiam6qVuNiasce0nMA/0,

ToUserName=gh_354d2c1b1485, MsgType=image}

 

  我们可以通过MediaId获取图片素材,存在微信的服务器上的临时素材也可以直接使用该MediaId回复用户同样的图片。

 请求说明:

http请求方式: GET,https调用

https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID

这里用到了ACCESS_TOKEN

ACCESS_TOKENaccess_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token

 

特征:①最大值512个字符;②:有效期:2个小时

获取方式:公众号可以使用AppID和AppSecret调用本接口来获取access_token,

https请求方式: GET:只有在公众号设置了IP白名单的IP才能调用该接口

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

返回说明

正常情况下,微信会返回下述JSON数据包给公众号:

{"access_token":"ACCESS_TOKEN","expires_in":7200}

容易遇到的错误:access_token is  not latest hint(过期)建议公众号开发者使用中控服务器统一获取和刷新Access_token,其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务,在5分钟内老的token是不会失效的(Jedis很容易解决这个问题

 

成功获取access_token后就可以调用素材获取接口开获取用户发送的图片,语音,视频等消息。

   

   2.回复消息 :涉及java对象转换xml  示例:XStream

        一旦遇到以下情况,微信都会在公众号会话中,向用户下发系统提示“该公众号暂时无法提供服务,请稍后再试”:

①、开发者在5秒内未回复任何内容

②、开发者回复了异常数据,比如JSON数据等

 

  •       文本消息:把接受消息的发送方和接受方互换

<xml>

<ToUserName><![CDATA[toUser]]></ToUserName>

<FromUserName><![CDATA[fromUser]]></FromUserName>

<CreateTime>12345678</CreateTime>

<MsgType><![CDATA[text]]></MsgType>

<Content><![CDATA[你好]]></Content>

</xml>

                

 

ToUserName

接收方帐号(收到的OpenID)

FromUserName

开发者微信号

CreateTime

消息创建时间 (整型)

MsgType

text

Content

回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)

 

  • 回复图片消息:需要先通过素材上传接口上传图片得到MediaId,媒体文件在微信后台保存时间为3天,即3天后media_id失效,大小限制参考官方文档(回复图文消息示例)

 

<xml>

<ToUserName><![CDATA[toUser]]></ToUserName>

<FromUserName><![CDATA[fromUser]]></FromUserName>

<CreateTime>12345678</CreateTime>

<MsgType><![CDATA[image]]></MsgType>

<Image>

<MediaId><![CDATA[media_id]]></MediaId>

</Image>

</xml>

 

 

 

ToUserName

接收方帐号(收到的OpenID)

FromUserName

开发者微信号

CreateTime

消息创建时间 (整型)

MsgType

image

MediaId

通过素材管理中的接口上传多媒体文件,得到的id。

 

 

三、自定菜单

 由于本账号无创建菜单的权限,故使用测试账号,测试账号的配置上很简单,在上面就有答案。

特别注意:

 

1、自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。

2、一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。

3、创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。

4.编辑中的菜单不会马上被用户看到,点击发布后,会在24小时后在手机端同步显示。

 

自定义菜单接口可实现常用类型按钮:

 

1、click:点击推事件用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;

2、view:跳转URL用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息。

 

接口调用请求说明

http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN

 

{

"button":[

{

"type":"click",

"name":"今日歌曲",

"key":"V1001_TODAY_MUSIC"

},

{

"name":"菜单",

"sub_button":[

{

"type":"view",

"name":"搜索",

"url":"http://www.soso.com/";

},

{

"type":"miniprogram",

"name":"wxa",

"url":"http://mp.weixin.qq.com";,

"appid":"wx286b93c14bbf93aa",

"pagepath":"pages/lunar/index"

},

{

"type":"click",

"name":"赞一下我们",

"key":"V1001_GOOD"

}]

}]

}

 

 

 

button

一级菜单数组,个数应为1~3个

sub_button

二级菜单数组,个数应为1~5个

type

菜单的响应动作类型,view表示网页类型,click表示点击类型,miniprogram表示小程序类型

name

菜单标题,不超过16个字节,子菜单不超过60个字节

key

click等点击类型必须

菜单KEY值,用于消息接口推送,不超过128字节

url

view、miniprogram类型必须

网页链接,用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。

media_id

media_id类型和view_limited类型必须

调用新增永久素材接口返回的合法media_id

appid

miniprogram类型必须

小程序的appid(仅认证公众号可配置)

pagepath

miniprogram类型必须

小程序的页面路径

 

 

如何封装:上图可知是JSON对象对应到java可以封装成javaPOJO

所有类型都有name属性:父类:(name)

①:定义click类型按钮(type,key

②:定义view类型按钮(type,url

③:定义包含二级菜单的一级菜单 :(BaseButton[] sub_button

④:定义菜单项:Menu(BaseButton[] button)

 

响应菜单事件:(推送XML数据包)

 用户点击自定义菜单后,微信会把点击事件推送给开发者,请注意,点击菜单弹出子菜单,不会产生上报:

 

点击菜单:

 

 

ToUserName

开发者微信号

FromUserName

发送方帐号(一个OpenID)

CreateTime

消息创建时间 (整型)

MsgType

消息类型,event

Event

事件类型,CLICK

EventKey

事件KEY值,与自定义菜单接口中KEY值对应

 

 

跳转菜单:直接跳转我们的设置的链接,当然后台也可以获取此事件,点击事件示例发送图文消息

演示订阅,回复图文消息

 

、利用微信JS-SDK网页开发

   微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包,就是一个js库,通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力!

 如何使用js_sdk:

    步骤 ①绑定js接口安全域名:公众号设置——>功能设置,:只有设置了该域名或路径,且我们在该域名或路径下发起到js-sdk接口的调用才能调用成功。我们可以按照如下图步骤设置,举一个例子:我们设置一个178b647i13.iask.in/static,有两点保证:1.必须是域名,且http支持80端口,https支持443端口(同样使用花生壳)该路径可直接访问到MP......txt,拿到浏览器来测试,2,我们调用js-sdk接口的路径至少与该路径一样,也就是我们的页面至少在static路径下。点击提交的时候微信会自动验证该路径,会提示你验证失败或者成功,但不会提示具体的原因!

     

         

.

    步骤:应用js文件(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js,改js提供了wx对象,如果发现wx is not defined,说明没有引用成功,检查应用方式是否正确,建议直接下载该文件放在本地引用避免各种奇葩愿意引用不到!

    步骤通过config接口注入权限验证配置,所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用)

       

wx.config({

    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。

    appId: '', // 必填,公众号的唯一标识

    timestamp: , // 必填,生成签名的时间戳

    nonceStr: '', // 必填,生成签名的随机串

    signature: '',// 必填,签名,见附录1

    jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2

});

这里面signature是最关键的,也是最容易出错的地方。

获取步骤:

   ①临时票据jsapi_ticket:jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期ye为7200秒,通过access_token来获取,该access_token就是上面我们所说的前参考前面内容 !

      用拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi成功返回如下JSON:

   

{

"errcode":0,

"errmsg":"ok",

"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",

"expires_in":7200

}

 

②:获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名

     

签名算法

签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。

 

注意事项

1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。

2.签名用的url必须是调用JS接口页面的完整URL(不包含#及其后面部分)。

3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。

 

 

 

常见错误:

1.invalid url domain当前页面所在域名与使用的appid没有绑定,请确认正确填写绑定的域名。例如配置的js接口安全路径是178b647i13.iask.in/static ,(因为178b647i13.iask.in这个我们是放不了文件的)但是我们的页面地址是178b647i13.iask.in/#/input,传到后台参与验签的地址是178b647i13.iask.in,这时就会出现这个错误。

2.invalid signature签名错误。建议按如下顺序检查:

     1.确认签名算法正确,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具进行校验,得到的signature与我们自己生成的signature比较如果不一致说明算法有问题。

     2.确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。

     3.确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。

    4.确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。

    5 .确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。https://www.xin-e-jia.com/btbMobile/vx/?from=singlemessage&isappinstalled=0#/RegPre?json=8fAsMYNk9o1s6pEHZhV7zKku%2FFzDan88WSbpu%2FA6%20Hszy3FcEut84gUvi%20zEl%2FpAWi4l%2FflGaKCgGjZkgrHM0A%3D%3D

  步骤④:通过ready接口处理成功验证

 

wx.ready(function(){

    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。

});

 

步骤⑤:通过error接口处理失败验证

 

 

wx.error(function(res){

    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。

});

 

 

所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下常用的通用参数:

1.success:接口调用成功时执行的回调函数。

2.fail:接口调用失败时执行的回调函数。

3.complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。

4.cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。

以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下:

调用成功时:"xxx:ok" ,其中xxx为调用的接口名

用户取消时:"xxx:cancel",其中xxx为调用的接口名

调用失败时:其值为具体错误信息

草图:

 

 

 

 

 

示例:选择照片

业务域名可以用来防止页面被重新排版,认证后才有!

 

 

   

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值