wechat 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
[](https://travis-ci.org/Eric-Guo/wechat) [](https://codeclimate.com/github/Eric-Guo/wechat) [](https://codeclimate.com/github/Eric-Guo/wechat) [](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
|