[![Join the chat][gitter-badge]][gitter] [![Issue Stats][issue-badge]][issuestats] [![PR Stats][pr-badge]][issuestats]
[中文文档 Chinese document](/README-CN.md)
[Wechat](http://www.wechat.com/) is a free messaging and calling app developed by [Tencent](http://tencent.com/en-us/index.shtml), after linked billion people, Wechat become a platform of application
WeChat gem trying to helping Rails developer to integrated [enterprise account](https://qy.weixin.qq.com) / [public account](https://mp.weixin.qq.com/) easily. Below feature is ready and no need writing adapter code talking to wechat server directly.
- [Sending message](http://qydev.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E6%B6%88%E6%81%AF) API(Can access via console or in rails)
- [Receiving message](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)(You must running on rails server to receiving message)
`wechat` command share the same API in console, so you can interactive with wechat server quickly, without starting up web environment/code.
A responder DSL can used in Rails controller, so giving a event based interface to handler message sent by end user from wechat server.
Wechat provide OAuth2.0 as authentication service and possible to intergrated with devise/other authorization gems, [omniauth-wechat-oauth2](https://github.com/skinnyworm/omniauth-wechat-oauth2) is a good start
There is official [weui](https://github.com/weui/weui), which corresponding Rails gems called [weui-rails](https://github.com/Eric-Guo/weui-rails) available, if you prefer following the same UI design as wechat.
## Installation
Using `gem install`
```
gem install "wechat"
```
Or add to your app's `Gemfile`:
```
gem 'wechat'
```
Run the following command to install it:
```console
bundle install
```
Run the generator:
```console
rails generate wechat:install
```
`rails g wechat:install` will generated the initial `wechat.yml` configuration, example wechat controller and corresponding routes.
## Configuration
#### Configure for command line
You can using `wechat` command solely, you need created configure file `~/.wechat.yml` and including below content for public account. the access_token will be write as a file.
```
appid: "my_appid"
secret: "my_secret"
access_token: "/var/tmp/wechat_access_token"
```
For enterprise account, need using `corpid` instead of `appid` as enterprise account support multiply application (Tencent called agent) in one enterprise account. Obtain the `corpsecret` is a little tricky, must created at management mode->privilege setting and create any of management group to obtain. Due to Tencent currently only provide Chinese interface for they management console, it's highly recommend you find a college knowing Mandarin to help you to obtain.
Windows user need store `.wechat.yml` at `C:/Users/[user_name]/` (replace your user name), also be caution the direction of folder separator.
```
corpid: "my_appid"
corpsecret: "my_secret"
agentid: 1 # Integer, which can be obtain from application, settings
Rails configuration files support different environment similar to database.yml, after running `rails generate wechat:install` you can find configuration files at `config/wechat.yml`
Public account congfigure example:
```
default: &default
appid: "app_id"
secret: "app_secret"
token: "app_token"
access_token: "/var/tmp/wechat_access_token"
production:
appid: <%= ENV['WECHAT_APPID'] %>
secret: <%= ENV['WECHAT_APP_SECRET'] %>
token: <%= ENV['WECHAT_TOKEN'] %>
access_token: <%= ENV['WECHAT_ACCESS_TOKEN'] %>
development:
<<:*default
test:
<<:*default
```
Although it's optional for public account, but highly recommend to enable encrypt mode by add below two items to `wechat.yml`
```
default: &default
encrypt_mode: true
encoding_aes_key: "my_encoding_aes_key"
```
Enterprise account must using encrypt mode (`encrypt_mode: true` is default on, no need configure).
The `token` and `encoding_aes_key` can be obtain from management console -> one of the agent application -> Mode selection, select callback mode and get/set.
Running `wechat` command in the root folder of Rails application will using the Rails configuration first (`default` section), if can not find it, will relay on `~\.wechat.yml`, such behavior enable manage more wechat public account and enterprise account without changing your home `~\.wechat.yml` file.
##### Wechat server timeout setting
Stability various even for Tencent wechat server, so setting a long timeout may needed, default is 20 seconds if not set.
##### Skip the SSL verification
SSL Certification can also be corrupted by some reason in China, [it's reported](http://qydev.weixin.qq.com/qa/index.php?qa=11037) and if it's happen to you, can setting `skip_verify_ssl: true`. (not recommend)
#### Configure individual responder with different appid
Rare case, you may want to hosting more than one wechat enterprise/public account in one Rails application, so you can given those configuration info when calling `wechat_responder`
```ruby
class WechatFirstController <ActionController::Base
JS-SDK enable you control wechat behavior in your web page, but need inject a config with signature methods first, you can obtain those signature hash via below
wechat gems won't handle any privilege exception. (except token time out, but it's not important to you as it's auto retry/recovery in gems internally), but Tencent will control a lot of privilege based on your public account type and certification, more info, please reference [official document](http://mp.weixin.qq.com/wiki/7/2d301d4b757dedc333b9a9854b457b47.html).
## Command line mode
The available API is different between public account and enterprise account, so wechat gems provide different set of command.
Feel safe if you can not read Chinese in the comments, it's keep there in order to copy & find in official document more easier.
menu content for a wechat application can be defined as a yaml files, like `menu.yaml`
```
button:
-
name: "Want"
sub_button:
-
type: "scancode_waitmsg"
name: "绑定用餐二维码"
key: "BINDING_QR_CODE"
-
type: "click"
name: "预订午餐"
key: "BOOK_LUNCH"
-
type: "click"
name: "预订晚餐"
key: "BOOK_DINNER"
-
name: "Query"
sub_button:
-
type: "click"
name: "进出记录"
key: "BADGE_IN_OUT"
-
type: "click"
name: "年假余额"
key: "ANNUAL_LEAVE"
-
type: "view"
name: "About"
url: "http://blog.cloud-mes.com/"
```
Caution: make sure you having management privilege for those application below running below command, other will got [60011](http://qydev.weixin.qq.com/wiki/index.php?title=%E5%85%A8%E5%B1%80%E8%BF%94%E5%9B%9E%E7%A0%81%E8%AF%B4%E6%98%8E) error.
```
$ wechat menu_create menu.yaml
```
##### Sent custom news
Sending custom_news should also defined as a yaml file, like `articles.yaml`
# If you need do something after response, you should add after_wechat_response(req, res)
# private
#
# def after_wechat_response(req, res)
# WechatLog.create req: req, res: res
# end
end
```
So the importent statement is only `wechat_responder`, all other is just a DSL:
```
on <message_type> do |message|
message.reply.text "some text"
end
```
The block code will be running to responding user's message.
Below is current supported message_type:
- :text text message, using `:with` to match text content like `on(:text, with:'help'){|message, content| ...}`
- :image image message
- :voice voice message
- :video video message
- :link link message
- :event event message, using `:with` to match particular event
- :click virtual event message, wechat still sent event message,but gems will mapping to menu click event.
- :view virtual view message, wechat still sent event message,but gems will mapping to menu view page event.
- :scan virtual scan message, wechat still sent event message, but gems will mapping on scan event
- :batch_job virtual batch job message
- :location virtual location message
- :fallback default message, when no other responder can handle incoming messsage, will using fallback to handle
### Transfer to customer service
```ruby
class WechatsController <ActionController::Base
# When no other responder can handle incoming message, will transfer to human customer service.
on :fallback do |message|
message.reply.transfer_customer_service
end
end
```
Caution: do not setting default text responder if you want to using [multiply human customer service](http://dkf.qq.com/), other will lead text message can not transfer.
## Known Issue
* Sometime, enterprise account can not receive the menu message due to Tencent server can not resolved the DNS, so using IP as a callback URL more stable, but it's never happen for user sent text message.
* Enterprise batch replace users using a CSV format file, but if you using the download template directly, it's [not working](http://qydev.weixin.qq.com/qa/index.php?qa=13978), must open the CSV file in excel first, then save as CSV format again, seems Tencent only support Excel save as CSV file format.