分享 微信开发简介

jesktop · 2015年01月19日 · 最后由 rails_taotao 回复于 2017年02月21日 · 12244 次阅读

推荐使用 GEM

在开始前,推荐 @ruby_sky 同学无私贡献的两个 gem:(这里要特别感谢我们社区的 @ruby_sky 同学) gem 'weixin_rails_middleware' gem 'weixin_authorize' 具体可以查看 gem 的文档,使用后可以很方便的处理一些问题,例如签名,加密和接口参数拼接等。

基础接口

如果只使用基础接口,只需要使用weixin_rails_middleware这个 gem 就可以了。基础接口指的是一般用户主动发出的请求,例如:发送文本或图片等消息到公众帐号时,公众帐号发出的回应消息。而相比于高级接口来说,基础接口要简单很多。

验证微信请求

在开始时,微信需要先验证你的接口,根据官方文档的验证方式大概是:
在微信后台填入服务器地址(URL)、Token 和 EncodingAESKey,然后微信通过提供的参数和一个随机数(echostr)进行字典序排序后,进行 sha1 加密,然后发送至服务器端,服务器端只要对其验证并且返回随机数(echostr),即表示验证成功。(具体内容参考微信文档)
而使用 gem 后,整个验证流程基本不需要自己操心,只需要添加正确的 secret_key 和 token,验证就通过了。

业务逻辑实现

使用weixin_rails_middleware后,执行 rails generate weixin_rails_middleware:install,就生成了整个业务逻辑的简单实现了,包括发送来的是图片,文本或者是关注之类的操作。只要是用户主动发起的操作和请求,基本都实现了简单的回复,所以如果不是特别复杂的操作,基础接口中业务逻辑的实现还是相当方便的。

高级接口

这里主要想说一下高级接口,因为在第一次开发微信公众号时,还是走了不少弯路。

简介

在使用高级接口时,我们使用gem 'weixin_authorize'。高级接口和基础接口有什么不一样呢?我觉得最大的区别在于高级接口基本上都是服务器端主动发起的请求,因为是服务器端主动发起的请求,所以每次需要带上access_token来提供微信验证此信息是否是服务器端发送的。所以我们先来看看access_token是如何获得的。

获取 access_token

access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

因为access_token是会失效的,所以gem 'weixin_authorize'中使用 Redis 来存储access_token是一个不错的方式,根据文档配置,然后通过:

$client ||= WeixinAuthorize::Client.new(ENV["APPID"], ENV["APPSECRET"])

即可获得对应公众号的access_token(公众号可以使用 AppID 和 AppSecret 调用接口来获取 access_token)。
现在咱们手持access_token自然如有神助,可以大显身手了。

自定义菜单

因为使用了开发者模式,所以就算是希望完成自定义菜单这样的事情也变得困难起来。那我们应该如何自定义菜单呢?
建议参考:自定义菜单的实现
文档中讲的很详细,表的结构可以参考文档。这里主要说一下,如何把定义好的菜单结构发送给微信,并且生成对应的菜单。
参考:

def generate_menu
  weixin_client = WeixinAuthorize::Client.new(@current_public_account.app_key, @current_public_account.app_secret)
  menu   = @current_public_account.build_menu
  result = weixin_client.create_menu(menu)
  set_error_message(result["errmsg"]) if result["errcode"] != 0
  redirect_to public_account_diymenus_path(@current_public_account)
end

其实就是带着access_token,把微信需要的菜单 JSON 结构拼装好,发送到微信对应的接口,然后微信就会生成菜单了。因为gem 'weixin_authorize'把事情都处理好了,所以自定义菜单对于我们来说,就变得非常的简单了。

关联用户和微信帐号

大家如果使用过银行的一些公众帐号,一定会用过这样的功能,就是把微信帐号和银行卡关联起来,然后银行卡发生交易时,微信都会收到相应的提示。那么它们是如何关联起来的呢?
我这里介绍一个关联方式,就是用户通过公众帐号的菜单,点击“登录”,然后进行关联。那么公众帐号菜单的登录和直接用网页登录究竟有什么不一样呢?

请求授权页面

在微信菜单中的“登录”按钮跳到的页面也是一个网站的登录页面,但是他们不一样的地方是,这里需要微信做一个授权,也就是菜单中的“登录”按钮指向的链接是这样的:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

里面两个必须的参数是 APPID 和 REDIRECT_URI,其中 REDIRECT_URI 是需要跳转的链接地址。为什么需要这样的地址呢?
因为随着微信的 REDIRECT_URI,去到登录页面时会带着一个 code 值,而我们需要用 code 来获取用户的 openid。

code说明 :
code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

openid说明:
普通用户的标识,对当前公众号唯一

有了 code 值,就可以立刻向微信获取用户的 openid 值了:

sns_info = $client.get_oauth_access_token(params[:code])
if sns_info.is_ok?
  user.openid = sns_info.result[:openid]
end

只要这样,当用户通过该页面登录成功后,就可以把 openid 和 user 关联起来,如果往后有消息需要推送给用户的话就相当方便了,调用微信对应的接口加上 openid,就可以发送消息到对应的微信用户上了。

以上就是这些时间里对微信公众帐号开发的一些看法和认识,都是一些比较简单的介绍。下面在介绍大家开发时记得使用微信提供的沙箱进行调试: http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

原文: 微信开发简介

介绍自己的 gem,还是要支持一下。顺便说一下,微信企业号的开发也已经完成: https://github.com/lanrion/qy_wechat https://github.com/lanrion/qy_wechat_api 已有部分公司接入并内测,欢迎使用。

#1 楼 @ruby_sky

https://github.com/lanrion/weixin_rails_middleware_example

麻烦问下:本地启动 ngrok 后,会得到一个 url : http://e0ede89.ngrok.com 但在微信后台,不仅要填写 url, 还要填写一个 Token

readme 怎么一下就跳到 Test Weixin Message,发送 hi 去了,跳得太快了,能麻烦讲一下,Token 是怎么回事吗?

另外,appID 和 appsecret 不需要在 rails 程序里设置好吗?

更新:

找到说明了: https://github.com/lanrion/weixin_rails_middleware/wiki/Getting-Start

  1. 前往 config/initializers/weixin_rails_middleware.rb,最好随机生成下面两个 string

    config.weixin_token_string  = 'c06a2a40256fdeb47ff0c7cc'
    config.weixin_secret_string = 'J92Eba24yRpG-s9LGYOA03FcnULHYFYs'
    
  2. 在微信 sandbox 填入相关信息: http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index URL 是用上面的信息组合起来的:http://e0ede89.ngrok.com/weixin/J92Eba24yRpG-s9LGYOA03FcnULHYFYs Token 就是 c06a2a40256fdeb47ff0c7cc

提交就可以看到 配置成功 的提示。

@JeskTop @ruby_sky

有个疑问,在 sandbox 调试只有 url 和 token 两项,微信 开发者中心服务器配置 却有 EncodingAESKey(消息加解密密钥) 这样一个必选项,我随机生成后,只有选择 兼容模式消息加解密方式 才可以成功收到消息。

https://github.com/lanrion/weixin_rails_middleware/wiki/msg-encryption-decipher 这里的说在 weixin_rails_middleware.rb 加入以下代码:

config.encoding_aes_key = '<%= WeiXinUniqueToken.generate(generator: :hex, size: 22)[1..43] %>'
config.app_id = "your app id"

我对这个配置有疑问,如果这个 encoding_aes_key 在本地也是随机生成的,在哪能看到呢,难道每次都生成不一样的,不用和微信 开发者中心 相同?

另外,加入这两行后,发现这两个方法都没有定义:

undefined method `encoding_aes_key='

#3 楼 @Peter undefined method 'encoding_aes_key=' 可以先贴一下你的 weixin_rails_middleware 的版本,请更新到最新版本: gem 'weixin_rails_middleware', '~> 1.3.0' 微信推出了消息加密方案,weixin_rails_middleware 也紧跟这个实现,所以会有 encoding_aes_key 这个配置。 在

config.encoding_aes_key = '<%= WeiXinUniqueToken.generate(generator: :hex, size: 22)[1..43] %>'
config.app_id = "your app id"

配置中: encoding_aes_key 保持 EncodingAESKey 一样就可以了, app_id 认证后会有一个 appid。 如果使用明文模式、兼容模式,不需要配置这两项

@ruby_sky 恩,当时使用的时候已经看到有了,不过目前还不涉及这方面的开发,需要的时候会第一时间用。 @Peter 应该确实用新版本就好了,目前我也没有遇到过这个问题。

哈哈,我倒是用这两个 gem 写了一个网站http://dev-start.net/ 演示帐号:[email protected] password: 12345678 感谢

#7 楼 @Peter 帮忙改一下,发一个 PR?把这个 weixin_rails_middleware_example 更新一下? 😄

我目前使用的是 gem 'weixin_authorize' 开发了微信服务号高级接口部分。gem 帮了很多忙,但是也是有一些问题,后来我自己添加了些业务相关。总得来说,目前 Ruby 相关的微信 gem,基本上没有什么人跟进维护了。

#9 楼 @hanluner 你可以来维护一下啊,众人拾柴火焰高 #8 楼 @ruby_sky 那个 pry 我装不上,我当时禁用了,回去再折腾一下,可能里面的版本号都有点老了,折腾好了发 PR

#9 楼 @hanluner 微信接口这种一般都是自己手写,用别人的不知道什么时候就出问题了

#10 楼 @Peter 想,但是精力分不开。好多项目压着。

#10 楼 @Peter pry 安装不上,可以使用 pry-byebug .

#11 楼 @messiahxu 我也同意,所以很多我使用的 gem,都是要读一下其源代码,再观察一下这个 gem 的维护情况。起码这两个微信的 gem,我是一直维护的,同时也希望大家能一起维护起来。

微信开发一般用什么 UI 框架?

#16 楼 @yakczh 用 bootstrap 就够了吧

微信开发一般用什么 ui 呢

#8 楼 @ruby_sky PR 已发,麻烦检查一下

非常赞,尝试过,好用^_^

#19 楼 @Peter Thanks,正在测试你的代码。

碰到个错误,

NoMethodError (undefined method `[]' for nil:NilClass):
  weixin_rails_middleware (1.3.0) lib/weixin_rails_middleware/models/message.rb:27:in `factory

代码

def self.factory(xml)
  hash = MultiXml.parse(xml)['xml']
  case hash['MsgType']

rails 4.1.2,

#6 楼 @hfpp2012 网站很酷,前端用 bootstrap 写的吗?

#23 楼 @littlell 是的 前端只是写来玩的

#22 楼 @jun1st 4.1.2,还没在这个版本上测试过,bug 还存在吗?如果存在,可以到 github 上提一下 issue.

#26 楼 @ruby_sky 应该还存在,当时比较紧急,就用别的方法替换了。

我的项目是 3.2.XX 的,看来问题会很多了

使用这个 gem 'weixin_authorize' 后就可以不用后台写 url 和 token?直接写逻辑代码就可以了吗@ruby_sky @peter

#29 楼 @a4652097 weixin_authorize 已经将接口封闭,直接按照 wiki 调相应的方法即可,部分未支持的接口,可以通过: https://github.com/lanrion/weixin_authorize/wiki/diy-your-api 方法自助实现。

#30 楼 @ruby_sky wiki 里怎么没有群发消息的接口?

#32 楼 @ruby_sky 有项目例子吗?第一次接触微信开发很多都不太懂。

#34 楼 @ruby_sky 不是只有 gem 'weixin_rails_middleware' 的例子吗?有 gem 'weixin_authorize' 的例子吗

37 楼 已删除

#38 楼 @ruby_sky def mass_with_group(group_id, media_info, msgtype="mpnews", is_to_all=false) 这个 media_info 是什么?

41 楼 已删除
42 楼 已删除
43 楼 已删除

请问一下我的网站是响应式的,用户在微信内置浏览器通过公众号获取用户信息的方式可以登录网站,在 PC 端可以通过开放平台的扫码登录网站,但是同一用户通过两种手段会生成两个账号,这两个账号怎么合并?

chairy11 谁来个微信开发学习资源大全? 提及了此话题。 07月06日 23:19

请问@current_public_account 如何定义,不是很明白,还有 ENV["APPID"], ENV["APPSECRET"] 这俩个再哪里声明赋值?

如何获取微信的返回的地理位置

需要 登录 后方可回复, 如果你还没有账号请 注册新账号