wechat 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +13 -0
- data/LICENSE +21 -0
- data/README.md +405 -0
- data/Rakefile +29 -0
- data/bin/wechat +172 -0
- data/lib/wechat.rb +104 -0
- data/lib/wechat/access_token.rb +41 -0
- data/lib/wechat/api.rb +85 -0
- data/lib/wechat/cipher.rb +72 -0
- data/lib/wechat/client.rb +79 -0
- data/lib/wechat/corp_api.rb +66 -0
- data/lib/wechat/jsapi_ticket.rb +86 -0
- data/lib/wechat/message.rb +176 -0
- data/lib/wechat/responder.rb +177 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e8ac0d453ab3b09ebc953fc377d87e3e4faaa691
|
4
|
+
data.tar.gz: db19e37a02a7361aed18294bc10782f276af4bb3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c7ed1bc6f07ded18760833ecfc8a19f5daba4ccb8ad0d6e1ed0ce484ef58ae08558c097c37aae5b014101400786d3b76c9a572ef2ce21c3cc56a8c9a3cf71224
|
7
|
+
data.tar.gz: 205d9c379adec3226e9fa51600ead4905a259133ff724eb49a56d7dec18b14304232a1e75aa92553e4c7048f83837295b2c1ce65c37b2789c40ca1f4fa5e21e3
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## v0.2.0 (released at 8/27/2015)
|
4
|
+
|
5
|
+
* Add wechat enterprise account support
|
6
|
+
* Make responder execute in action context, by @lazing #15
|
7
|
+
* jsapi_ticket support, by @feitian124 #27
|
8
|
+
* Rename gems to wechat and ambitious to being #1 gems about development wechat. thanks Xiaoning transfer this gem name.
|
9
|
+
* Original gem `wechat-rails` author skinnyworm trasfer to Eric-Guo as maintainer
|
10
|
+
|
11
|
+
## v0.1.1
|
12
|
+
|
13
|
+
* Initial release from [wechat-rails](https://github.com/skinnyworm/wechat-rails).
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 skinnyworm
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,405 @@
|
|
1
|
+
WeChat
|
2
|
+
======
|
3
|
+
|
4
|
+
[![Build Status](https://travis-ci.org/Eric-Guo/wechat.svg)](https://travis-ci.org/Eric-Guo/wechat) [![Code Climate](https://codeclimate.com/github/Eric-Guo/wechat.png)](https://codeclimate.com/github/Eric-Guo/wechat) [![Code Coverage](https://codeclimate.com/github/Eric-Guo/wechat/coverage.png)](https://codeclimate.com/github/Eric-Guo/wechat) [![Gem Version](https://badge.fury.io/rb/wechat.svg)](https://badge.fury.io/for/rb/wechat)
|
5
|
+
|
6
|
+
|
7
|
+
WeChat gem 可以帮助开发者方便地在Rails环境中集成微信[公众平台](https://mp.weixin.qq.com/)和[企业平台](https://qy.weixin.qq.com)提供的服务,包括:
|
8
|
+
|
9
|
+
- 微信公众/企业平台[主动消息](http://qydev.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E6%B6%88%E6%81%AF)API(命令行和Web环境都可以使用)
|
10
|
+
- [回调消息](http://qydev.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E6%B6%88%E6%81%AF%E4%B8%8E%E4%BA%8B%E4%BB%B6)(必须运行Web服务器)
|
11
|
+
- [微信JS-SDK](http://qydev.weixin.qq.com/wiki/index.php?title=%E5%BE%AE%E4%BF%A1JS%E6%8E%A5%E5%8F%A3) config接口注入权限验证
|
12
|
+
- OAuth 2.0认证机制
|
13
|
+
|
14
|
+
命令行工具`wechat`可以调用各种无需web环境的API。同时也提供了Rails Controller的responder DSL, 可以帮助开发者方便地在Rails应用中集成微信的消息处理机制。如果你的App还需要集成微信OAuth2.0, 你可以考虑[omniauth-wechat-oauth2](https://github.com/skinnyworm/omniauth-wechat-oauth2), 以便和devise集成,提供完整的用户认证。
|
15
|
+
|
16
|
+
|
17
|
+
## 安装
|
18
|
+
|
19
|
+
Using `gem install`
|
20
|
+
|
21
|
+
```
|
22
|
+
gem install "wechat"
|
23
|
+
```
|
24
|
+
|
25
|
+
Or add to your app's `Gemfile`:
|
26
|
+
|
27
|
+
```
|
28
|
+
gem 'wechat'
|
29
|
+
```
|
30
|
+
|
31
|
+
|
32
|
+
## 配置
|
33
|
+
|
34
|
+
#### 命令行程序的配置
|
35
|
+
|
36
|
+
要使用命令行程序,需要在home目录中创建一个`~/.wechat.yml`,包含以下内容。其中`access_token`是存放access_token的文件位置。
|
37
|
+
|
38
|
+
```
|
39
|
+
appid: "my_appid"
|
40
|
+
secret: "my_secret"
|
41
|
+
access_token: "/var/tmp/wechat_access_token"
|
42
|
+
```
|
43
|
+
|
44
|
+
Windows或者使用企业号,需要存放在`C:/Users/[user_name]/`下,其中corpid和corpsecret可以从企业号管理界面的设置->权限管理,通过新建任意一个管理组后获取。
|
45
|
+
|
46
|
+
```
|
47
|
+
corpid: "my_appid"
|
48
|
+
corpsecret: "my_secret"
|
49
|
+
agentid: "1" # 企业应用的id,整型。可在应用的设置页面查看
|
50
|
+
access_token: "C:/Users/[user_name]/wechat_access_token"
|
51
|
+
```
|
52
|
+
|
53
|
+
#### Rails 全局配置
|
54
|
+
Rails应用程序中,需要将配置文件放在`config/wechat.yml`,可以为不同environment创建不同的配置。
|
55
|
+
|
56
|
+
公众号配置示例:
|
57
|
+
|
58
|
+
```
|
59
|
+
default: &default
|
60
|
+
appid: "app_id"
|
61
|
+
secret: "app_secret"
|
62
|
+
token: "app_token"
|
63
|
+
access_token: "/var/tmp/wechat_access_token"
|
64
|
+
|
65
|
+
production:
|
66
|
+
appid: <%= ENV['WECHAT_APPID'] %>
|
67
|
+
secret: <%= ENV['WECHAT_APP_SECRET'] %>
|
68
|
+
token: <%= ENV['WECHAT_TOKEN'] %>
|
69
|
+
access_token: <%= ENV['WECHAT_ACCESS_TOKEN'] %>
|
70
|
+
|
71
|
+
development:
|
72
|
+
<<: *default
|
73
|
+
|
74
|
+
test:
|
75
|
+
<<: *default
|
76
|
+
```
|
77
|
+
|
78
|
+
企业号配置下必须使用加密模式,其中token和encoding_aes_key可以从企业号管理界面的应用中心->某个应用->模式选择,选择回调模式后获得。
|
79
|
+
|
80
|
+
```
|
81
|
+
default: &default
|
82
|
+
corpid: "corpid"
|
83
|
+
corpsecret: "corpsecret"
|
84
|
+
agentid: "1"
|
85
|
+
access_token: "C:/Users/[user_name]/wechat_access_token"
|
86
|
+
encrypt_mode: true
|
87
|
+
token: ""
|
88
|
+
encoding_aes_key: ""
|
89
|
+
|
90
|
+
production:
|
91
|
+
corpid: <%= ENV['WECHAT_CORPID'] %>
|
92
|
+
corpsecret: <%= ENV['WECHAT_CORPSECRET'] %>
|
93
|
+
agentid: <%= ENV['WECHAT_AGENTID'] %>
|
94
|
+
access_token: <%= ENV['WECHAT_ACCESS_TOKEN'] %>
|
95
|
+
encrypt_mode: <%= ENV['WECHAT_ENCRYPT_MODE'] %>
|
96
|
+
token: <%= ENV['WECHAT_TOKEN'] %>
|
97
|
+
encoding_aes_key: <%= ENV['WECHAT_ENCODING_AES_KEY'] %>
|
98
|
+
|
99
|
+
development:
|
100
|
+
<<: *default
|
101
|
+
|
102
|
+
test:
|
103
|
+
<<: *default
|
104
|
+
```
|
105
|
+
|
106
|
+
注意在Rails项目根目录下运行`wechat`命令行工具会优先使用`config/wechat.yml`中的`default`配置,如果失败则使用`~\.wechat.yml`中的配置,以便于在生产环境下管理多个微信账号应用。
|
107
|
+
|
108
|
+
#### 为每个Responder配置不同的appid和secret
|
109
|
+
|
110
|
+
在个别情况下,单个Rails应用可能需要处理来自多个账号的消息,此时可以配置多个responder controller。
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
class WechatFirstController < ApplicationController
|
114
|
+
wechat_responder appid: "app1", secret: "secret1", token: "token1", access_token: Rails.root.join("tmp/access_token1")
|
115
|
+
|
116
|
+
on :text, with:"help", respond: "help content"
|
117
|
+
end
|
118
|
+
```
|
119
|
+
|
120
|
+
#### jssdk 支持
|
121
|
+
|
122
|
+
jssdk 使用前需通过config接口注入权限验证配置, 所需参数可以通过 signature 方法获取:
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
WechatsController.wechat.jsapi_ticket.signature(request.original_url)
|
126
|
+
```
|
127
|
+
|
128
|
+
## 关于接口权限
|
129
|
+
|
130
|
+
wechat gems 内部不会检查权限。但因公众号类型不同,和微信服务器端通讯时,可能会被拒绝,详细权限控制可参考[官方文档](http://mp.weixin.qq.com/wiki/7/2d301d4b757dedc333b9a9854b457b47.html)。
|
131
|
+
|
132
|
+
## 使用命令行
|
133
|
+
|
134
|
+
```
|
135
|
+
$ wechat
|
136
|
+
Wechat commands:
|
137
|
+
wechat custom_image [OPENID, IMAGE_PATH] # 发送图片客服消息
|
138
|
+
wechat custom_music [OPENID, THUMBNAIL_PATH, MUSIC_URL] # 发送音乐客服消息
|
139
|
+
wechat custom_news [OPENID, NEWS_YAML_FILE] # 发送图文客服消息
|
140
|
+
wechat custom_text [OPENID, TEXT_MESSAGE] # 发送文字客服消息
|
141
|
+
wechat custom_video [OPENID, VIDEO_PATH] # 发送视频客服消息
|
142
|
+
wechat custom_voice [OPENID, VOICE_PATH] # 发送语音客服消息
|
143
|
+
wechat media [MEDIA_ID, PATH] # 媒体下载
|
144
|
+
wechat media_create [MEDIA_ID, PATH] # 媒体上传
|
145
|
+
wechat menu # 当前菜单
|
146
|
+
wechat menu_create [MENU_YAML] # 创建菜单
|
147
|
+
wechat menu_delete # 删除菜单
|
148
|
+
wechat message_send [OPENID, TEXT_MESSAGE] # 发送文字消息(仅企业号)
|
149
|
+
wechat template_message [OPENID, TEMPLATE_YAML_FILE] # 模板消息接口
|
150
|
+
wechat user [OPEN_ID] # 查找关注者
|
151
|
+
wechat users # 关注者列表
|
152
|
+
```
|
153
|
+
|
154
|
+
### 使用场景
|
155
|
+
以下是几种典型场景的使用方法
|
156
|
+
|
157
|
+
#####获取所有用户的OPENID
|
158
|
+
|
159
|
+
```
|
160
|
+
$ wechat users
|
161
|
+
|
162
|
+
{"total"=>4, "count"=>4, "data"=>{"openid"=>["oCfEht9***********", "oCfEhtwqa***********", "oCfEht9oMCqGo***********", "oCfEht_81H5o2***********"]}, "next_openid"=>"oCfEht_81H5o2***********"}
|
163
|
+
|
164
|
+
```
|
165
|
+
|
166
|
+
#####获取用户的信息
|
167
|
+
|
168
|
+
```
|
169
|
+
$ wechat user "oCfEht9***********"
|
170
|
+
|
171
|
+
{"subscribe"=>1, "openid"=>"oCfEht9***********", "nickname"=>"Nickname", "sex"=>1, "language"=>"zh_CN", "city"=>"徐汇", "province"=>"上海", "country"=>"中国", "headimgurl"=>"http://wx.qlogo.cn/mmopen/ajNVdqHZLLBd0SG8NjV3UpXZuiaGGPDcaKHebTKiaTyof*********/0", "subscribe_time"=>1395715239}
|
172
|
+
|
173
|
+
```
|
174
|
+
|
175
|
+
#####获取用户的信息
|
176
|
+
|
177
|
+
```
|
178
|
+
$ wechat user "oCfEht9***********"
|
179
|
+
|
180
|
+
{"subscribe"=>1, "openid"=>"oCfEht9***********", "nickname"=>"Nickname", "sex"=>1, "language"=>"zh_CN", "city"=>"徐汇", "province"=>"上海", "country"=>"中国", "headimgurl"=>"http://wx.qlogo.cn/mmopen/ajNVdqHZLLBd0SG8NjV3UpXZuiaGGPDcaKHebTKiaTyof*********/0", "subscribe_time"=>1395715239}
|
181
|
+
```
|
182
|
+
|
183
|
+
##### 获取当前菜单
|
184
|
+
```
|
185
|
+
$ wechat menu
|
186
|
+
|
187
|
+
{"menu"=>{"button"=>[{"type"=>"view", "name"=>"保护的", "url"=>"http://***/protected", "sub_button"=>[]}, {"type"=>"view", "name"=>"公开的", "url"=>"http://***", "sub_button"=>[]}]}}
|
188
|
+
|
189
|
+
```
|
190
|
+
|
191
|
+
##### 创建菜单
|
192
|
+
创建菜单需要一个定义菜单内容的yaml文件,比如
|
193
|
+
menu.yaml
|
194
|
+
|
195
|
+
```
|
196
|
+
button:
|
197
|
+
-
|
198
|
+
name: "我要"
|
199
|
+
sub_button:
|
200
|
+
-
|
201
|
+
type: "click"
|
202
|
+
name: "预订午餐"
|
203
|
+
key: "BOOK_LUNCH"
|
204
|
+
sub_button:
|
205
|
+
-
|
206
|
+
-
|
207
|
+
type: "click"
|
208
|
+
name: "预订晚餐"
|
209
|
+
key: "BOOK_DINNER"
|
210
|
+
sub_button:
|
211
|
+
-
|
212
|
+
-
|
213
|
+
type: "click"
|
214
|
+
name: "预订半夜餐"
|
215
|
+
key: "BOOK_NIGHT_SNACK"
|
216
|
+
sub_button:
|
217
|
+
-
|
218
|
+
-
|
219
|
+
name: "查询"
|
220
|
+
sub_button:
|
221
|
+
-
|
222
|
+
type: "click"
|
223
|
+
name: "进出记录"
|
224
|
+
key: "BADGE_IN_OUT"
|
225
|
+
sub_button:
|
226
|
+
-
|
227
|
+
-
|
228
|
+
type: "click"
|
229
|
+
name: "年假余额"
|
230
|
+
key: "ANNUAL_LEAVE"
|
231
|
+
sub_button:
|
232
|
+
-
|
233
|
+
-
|
234
|
+
type: "view"
|
235
|
+
name: "关于"
|
236
|
+
url: "http://blog.cloud-mes.com/"
|
237
|
+
|
238
|
+
```
|
239
|
+
|
240
|
+
然后执行命令行
|
241
|
+
|
242
|
+
```
|
243
|
+
$ wechat menu_create menu.yaml
|
244
|
+
|
245
|
+
```
|
246
|
+
|
247
|
+
##### 发送客服图文消息
|
248
|
+
需定义一个图文消息内容的yaml文件,比如
|
249
|
+
articles.yaml
|
250
|
+
|
251
|
+
```
|
252
|
+
articles:
|
253
|
+
-
|
254
|
+
title: "习近平在布鲁日欧洲学院演讲"
|
255
|
+
description: "新华网比利时布鲁日4月1日电 国家主席习近平1日在比利时布鲁日欧洲学院发表重要演讲"
|
256
|
+
url: "http://news.sina.com.cn/c/2014-04-01/232629843387.shtml"
|
257
|
+
pic_url: "http://i3.sinaimg.cn/dy/c/2014-04-01/1396366518_bYays1.jpg"
|
258
|
+
```
|
259
|
+
|
260
|
+
然后执行命令行
|
261
|
+
|
262
|
+
```
|
263
|
+
$ wechat custom_news oCfEht9oM*********** articles.yml
|
264
|
+
|
265
|
+
```
|
266
|
+
|
267
|
+
##### 发送模板消息
|
268
|
+
需定义一个模板消息内容的yaml文件,比如
|
269
|
+
template.yml
|
270
|
+
|
271
|
+
```
|
272
|
+
template:
|
273
|
+
template_id: "o64KQ62_xxxxxxxxxxxxxxx-Qz-MlNcRKteq8"
|
274
|
+
url: "http://weixin.qq.com/download"
|
275
|
+
topcolor: "#FF0000"
|
276
|
+
data:
|
277
|
+
first:
|
278
|
+
value: "你好,你已报名成功"
|
279
|
+
color: "#0A0A0A"
|
280
|
+
keynote1:
|
281
|
+
value: "XX活动"
|
282
|
+
color: "#CCCCCC"
|
283
|
+
keynote2:
|
284
|
+
value: "2014年9月16日"
|
285
|
+
color: "#CCCCCC"
|
286
|
+
keynote3:
|
287
|
+
value: "上海徐家汇xxx城"
|
288
|
+
color: "#CCCCCC"
|
289
|
+
remark:
|
290
|
+
value: "欢迎再次使用。"
|
291
|
+
color: "#173177"
|
292
|
+
|
293
|
+
```
|
294
|
+
|
295
|
+
然后执行命令行
|
296
|
+
|
297
|
+
```
|
298
|
+
$ wechat template_message oCfEht9oM*********** template.yml
|
299
|
+
|
300
|
+
```
|
301
|
+
|
302
|
+
## Rails Responder Controller DSL
|
303
|
+
|
304
|
+
为了在Rails app中响应用户的消息,开发者需要创建一个wechat responder controller. 首先在router中定义
|
305
|
+
|
306
|
+
```ruby
|
307
|
+
resource :wechat, only:[:show, :create]
|
308
|
+
|
309
|
+
```
|
310
|
+
|
311
|
+
然后创建Controller class, 例如
|
312
|
+
|
313
|
+
```ruby
|
314
|
+
|
315
|
+
class WechatsController < ApplicationController
|
316
|
+
wechat_responder
|
317
|
+
|
318
|
+
# 默认的文字信息responder
|
319
|
+
on :text do |request, content|
|
320
|
+
request.reply.text "echo: #{content}" #Just echo
|
321
|
+
end
|
322
|
+
|
323
|
+
# 当请求的文字信息内容为'help'时, 使用这个responder处理
|
324
|
+
on :text, with:"help" do |request, help|
|
325
|
+
request.reply.text "help content" #回复帮助信息
|
326
|
+
end
|
327
|
+
|
328
|
+
# 当请求的文字信息内容为'<n>条新闻'时, 使用这个responder处理, 并将n作为第二个参数
|
329
|
+
on :text, with: /^(\d+)条新闻$/ do |request, count|
|
330
|
+
articles_range = (0... [count.to_i, 10].min)
|
331
|
+
request.reply.news(articles_range) do |article, i| #回复"articles"
|
332
|
+
article.item title: "标题#{i}", description:"内容描述#{i}", pic_url: "http://www.baidu.com/img/bdlogo.gif", url:"http://www.baidu.com/"
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
# 当收到 EventKey 为 mykey 的事件时
|
337
|
+
on :event, with: "mykey" do |request, key|
|
338
|
+
request.reply.text "收到来自#{request[:FromUserName]} 的EventKey 为 #{key} 的事件"
|
339
|
+
end
|
340
|
+
|
341
|
+
# 处理图片信息
|
342
|
+
on :image do |request|
|
343
|
+
request.reply.image(request[:MediaId]) #直接将图片返回给用户
|
344
|
+
end
|
345
|
+
|
346
|
+
# 处理语音信息
|
347
|
+
on :voice do |request|
|
348
|
+
request.reply.voice(request[:MediaId]) #直接语音音返回给用户
|
349
|
+
end
|
350
|
+
|
351
|
+
# 处理视频信息
|
352
|
+
on :video do |request|
|
353
|
+
nickname = wechat.user(request[:FromUserName])["nickname"] #调用 api 获得发送者的nickname
|
354
|
+
request.reply.video(request[:MediaId], title: "回声", description: "#{nickname}发来的视频请求") #直接视频返回给用户
|
355
|
+
end
|
356
|
+
|
357
|
+
# 处理地理位置信息
|
358
|
+
on :location do |request|
|
359
|
+
request.reply.text("#{request[:Location_X]}, #{request[:Location_Y]}") #回复地理位置
|
360
|
+
end
|
361
|
+
|
362
|
+
# 当用户加关注
|
363
|
+
on :event, with: 'subscribe' do |request, key|
|
364
|
+
request.reply.text "#{request[:FromUserName]} #{key} now"
|
365
|
+
end
|
366
|
+
|
367
|
+
# 当用户取消关注订阅
|
368
|
+
on :event, with: 'unsubscribe' do |request, key|
|
369
|
+
request.reply.text "#{request[:FromUserName]}无法收到这条消息。"
|
370
|
+
end
|
371
|
+
|
372
|
+
# 当无任何responder处理用户信息时,使用这个responder处理
|
373
|
+
on :fallback, respond: "fallback message"
|
374
|
+
end
|
375
|
+
|
376
|
+
```
|
377
|
+
|
378
|
+
在controller中使用`wechat_responder`引入Responder DSL, 之后可以用
|
379
|
+
|
380
|
+
```
|
381
|
+
on <message_type> do |message|
|
382
|
+
message.reply.text "some text"
|
383
|
+
end
|
384
|
+
|
385
|
+
```
|
386
|
+
来响应用户信息。
|
387
|
+
|
388
|
+
目前支持的message_type有如下几种
|
389
|
+
|
390
|
+
- :text 响应文字消息,可以用`:with`参数来匹配文本内容 `on(:text, with:'help'){|message, content| ...}`
|
391
|
+
- :image 响应图片消息
|
392
|
+
- :voice 响应语音消息
|
393
|
+
- :video 响应视频消息
|
394
|
+
- :location 响应地理位置消息
|
395
|
+
- :link 响应链接消息
|
396
|
+
- :event 响应事件消息, 可以用`:with`参数来匹配事件类型
|
397
|
+
- :fallback 默认响应,当收到的消息无法被其他responder响应时,会使用这个responder.
|
398
|
+
|
399
|
+
## Message DSL
|
400
|
+
|
401
|
+
Wechat 的核心是一个Message DSL,帮助开发者构建各种类型的消息,包括主动推送的和被动响应的。
|
402
|
+
....
|
403
|
+
|
404
|
+
|
405
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'Wechat'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
require File.join('bundler', 'gem_tasks')
|
25
|
+
require File.join('rspec', 'core', 'rake_task')
|
26
|
+
RSpec::Core::RakeTask.new(:spec)
|
27
|
+
|
28
|
+
|
29
|
+
task :default => :spec
|