weixin_pam 0.0.1

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.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +165 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/javascripts/jquery-sortable.js +699 -0
  6. data/app/assets/javascripts/weixin_pam/application.js +30 -0
  7. data/app/assets/javascripts/weixin_pam/diymenus.js +90 -0
  8. data/app/assets/javascripts/weixin_pam/public_accounts.js +2 -0
  9. data/app/assets/javascripts/weixin_pam/user_accounts.js +23 -0
  10. data/app/assets/stylesheets/weixin_pam/application.scss +31 -0
  11. data/app/assets/stylesheets/weixin_pam/diymenus.scss +52 -0
  12. data/app/assets/stylesheets/weixin_pam/jquery-dragable.scss +26 -0
  13. data/app/assets/stylesheets/weixin_pam/public_accounts.css +4 -0
  14. data/app/assets/stylesheets/weixin_pam/user_accounts.css +4 -0
  15. data/app/controllers/weixin_pam/application_controller.rb +4 -0
  16. data/app/controllers/weixin_pam/diymenus_controller.rb +100 -0
  17. data/app/controllers/weixin_pam/public_accounts_controller.rb +62 -0
  18. data/app/controllers/weixin_pam/user_accounts_controller.rb +76 -0
  19. data/app/decorators/controllers/weixin_rails_middleware/weixin_controller_decorator.rb +31 -0
  20. data/app/helpers/weixin_pam/application_helper.rb +18 -0
  21. data/app/helpers/weixin_pam/diymenus_helper.rb +4 -0
  22. data/app/helpers/weixin_pam/public_accounts_helper.rb +4 -0
  23. data/app/helpers/weixin_pam/user_accounts_helper.rb +4 -0
  24. data/app/models/weixin_pam/diymenu.rb +58 -0
  25. data/app/models/weixin_pam/public_account.rb +87 -0
  26. data/app/models/weixin_pam/user_account.rb +67 -0
  27. data/app/views/layouts/weixin_pam/_nav_bar.html.erb +37 -0
  28. data/app/views/layouts/weixin_pam/application.html.erb +26 -0
  29. data/app/views/weixin_pam/diymenus/_form.html.erb +18 -0
  30. data/app/views/weixin_pam/diymenus/edit.html.erb +3 -0
  31. data/app/views/weixin_pam/diymenus/index.html.slim +32 -0
  32. data/app/views/weixin_pam/diymenus/new.html.erb +3 -0
  33. data/app/views/weixin_pam/public_accounts/_form.html.erb +12 -0
  34. data/app/views/weixin_pam/public_accounts/edit.html.erb +3 -0
  35. data/app/views/weixin_pam/public_accounts/index.html.erb +30 -0
  36. data/app/views/weixin_pam/public_accounts/new.html.erb +3 -0
  37. data/app/views/weixin_pam/public_accounts/show.html.erb +17 -0
  38. data/app/views/weixin_pam/user_accounts/_form.html.erb +37 -0
  39. data/app/views/weixin_pam/user_accounts/edit.html.erb +6 -0
  40. data/app/views/weixin_pam/user_accounts/index.html.slim +25 -0
  41. data/app/views/weixin_pam/user_accounts/new.html.erb +5 -0
  42. data/app/views/weixin_pam/user_accounts/show.html.erb +29 -0
  43. data/config/initializers/simple_form.rb +165 -0
  44. data/config/initializers/simple_form_bootstrap.rb +149 -0
  45. data/config/initializers/weixin_rails_middleware.rb +27 -0
  46. data/config/locales/diymenu.zh-CN.yml +9 -0
  47. data/config/locales/public_account.zh-CN.yml +16 -0
  48. data/config/locales/simple_form.en.yml +31 -0
  49. data/config/locales/user_account.zh-CN.yml +13 -0
  50. data/config/routes.rb +17 -0
  51. data/db/migrate/20151211153307_create_weixin_pam_public_accounts.rb +14 -0
  52. data/db/migrate/20151211153353_create_weixin_pam_user_accounts.rb +19 -0
  53. data/db/migrate/20151212152624_create_weixin_pam_diymenus.rb +18 -0
  54. data/db/migrate/20151215140830_add_weixin_secret_key_and_weixin_token_to_public_accounts.rb +13 -0
  55. data/db/migrate/20151218053505_add_host_to_weixin_pam_public_account.rb +6 -0
  56. data/lib/tasks/weixin_pam_tasks.rake +4 -0
  57. data/lib/templates/erb/scaffold/_form.html.erb +13 -0
  58. data/lib/weixin_pam.rb +3 -0
  59. data/lib/weixin_pam/api_error.rb +3 -0
  60. data/lib/weixin_pam/api_error/failed_result.rb +11 -0
  61. data/lib/weixin_pam/engine.rb +24 -0
  62. data/lib/weixin_pam/public_account_reply.rb +222 -0
  63. data/lib/weixin_pam/version.rb +3 -0
  64. data/test/controllers/weixin_pam/diymenus_controller_test.rb +52 -0
  65. data/test/controllers/weixin_pam/public_accounts_controller_test.rb +52 -0
  66. data/test/controllers/weixin_pam/user_accounts_controller_test.rb +52 -0
  67. data/test/dummy/README.rdoc +28 -0
  68. data/test/dummy/Rakefile +6 -0
  69. data/test/dummy/app/assets/javascripts/application.js +13 -0
  70. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  71. data/test/dummy/app/controllers/application_controller.rb +5 -0
  72. data/test/dummy/app/helpers/application_helper.rb +2 -0
  73. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  74. data/test/dummy/bin/bundle +3 -0
  75. data/test/dummy/bin/rails +4 -0
  76. data/test/dummy/bin/rake +4 -0
  77. data/test/dummy/bin/setup +29 -0
  78. data/test/dummy/config.ru +4 -0
  79. data/test/dummy/config/application.rb +26 -0
  80. data/test/dummy/config/boot.rb +5 -0
  81. data/test/dummy/config/database.yml +25 -0
  82. data/test/dummy/config/environment.rb +5 -0
  83. data/test/dummy/config/environments/development.rb +41 -0
  84. data/test/dummy/config/environments/production.rb +79 -0
  85. data/test/dummy/config/environments/test.rb +42 -0
  86. data/test/dummy/config/initializers/assets.rb +11 -0
  87. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  88. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  89. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  90. data/test/dummy/config/initializers/inflections.rb +16 -0
  91. data/test/dummy/config/initializers/mime_types.rb +4 -0
  92. data/test/dummy/config/initializers/session_store.rb +3 -0
  93. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  94. data/test/dummy/config/locales/en.yml +23 -0
  95. data/test/dummy/config/routes.rb +4 -0
  96. data/test/dummy/config/secrets.yml +22 -0
  97. data/test/dummy/db/development.sqlite3 +0 -0
  98. data/test/dummy/db/schema.rb +60 -0
  99. data/test/dummy/db/test.sqlite3 +0 -0
  100. data/test/dummy/log/development.log +594 -0
  101. data/test/dummy/public/404.html +67 -0
  102. data/test/dummy/public/422.html +67 -0
  103. data/test/dummy/public/500.html +66 -0
  104. data/test/dummy/public/favicon.ico +0 -0
  105. data/test/fixtures/weixin_pam/diymenus.yml +19 -0
  106. data/test/fixtures/weixin_pam/public_accounts.yml +17 -0
  107. data/test/fixtures/weixin_pam/user_accounts.yml +15 -0
  108. data/test/integration/navigation_test.rb +8 -0
  109. data/test/models/weixin_pam/diymenu_test.rb +9 -0
  110. data/test/models/weixin_pam/public_account_test.rb +9 -0
  111. data/test/models/weixin_pam/user_account_test.rb +9 -0
  112. data/test/test_helper.rb +21 -0
  113. data/test/weixin_pam_test.rb +7 -0
  114. metadata +374 -0
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ # Use this hook to configure WeixinRailsMiddleware bahaviors.
3
+ WeixinRailsMiddleware.configure do |config|
4
+
5
+ ## NOTE:
6
+ ## If you config all them, it will use `weixin_token_string` default
7
+
8
+ ## Config public_account_class if you SAVE public_account into database ##
9
+ # Th first configure is fit for your weixin public_account is saved in database.
10
+ # +public_account_class+ The class name that to save your public_account
11
+ config.public_account_class = 'WeixinPam::PublicAccount'
12
+
13
+ ## Here configure is for you DON'T WANT TO SAVE your public account into database ##
14
+ # Or the other configure is fit for only one weixin public_account
15
+ # If you config `weixin_token_string`, so it will directly use it
16
+ # config.weixin_token_string = '3678286d368459d597aeb2a8'
17
+ # using to weixin server url to validate the token can be trusted.
18
+ # config.weixin_secret_string = '9pUe_kQByC4Ot4A1DZe0pXMEh3zU8o6E'
19
+ # 加密配置,如果需要加密,配置以下参数
20
+ # config.encoding_aes_key = 'c1344f20197c7e38fd74b2afbac10ab4991180d8bf8'
21
+ # config.app_id = "your app id"
22
+
23
+ ## You can custom your adapter to validate your weixin account ##
24
+ # Wiki https://github.com/lanrion/weixin_rails_middleware/wiki/Custom-Adapter
25
+ # config.custom_adapter = "MyCustomAdapter"
26
+
27
+ end
@@ -0,0 +1,9 @@
1
+ 'zh-CN':
2
+ activerecord:
3
+ models:
4
+ weixin_pam/diymenu: 微信菜单
5
+ attributes:
6
+ weixin_pam/diymenu:
7
+ name: 菜单名
8
+ key: KEY(click:点击推事件)
9
+ url: URL(view:跳转URL)
@@ -0,0 +1,16 @@
1
+ 'zh-CN':
2
+ activerecord:
3
+ models:
4
+ weixin_pam/public_account: 公众号
5
+ attributes:
6
+ weixin_pam/public_account:
7
+ name: 公众号名称
8
+ app_id: AppID(应用ID)
9
+ app_secret: AppSecret(应用密钥)
10
+ api_url: URL(原始服务器地址)
11
+ api_token: Token(原始令牌)
12
+ weixin_secret_key: URL(新服务器地址)
13
+ weixin_token: Token(新令牌)
14
+ host: 网页授权的主机名
15
+ reply_class: 微信服务器事件推送的响应Class
16
+ enabled: 启用
@@ -0,0 +1,31 @@
1
+ en:
2
+ simple_form:
3
+ "yes": 'Yes'
4
+ "no": 'No'
5
+ required:
6
+ text: 'required'
7
+ mark: '*'
8
+ # You can uncomment the line below if you need to overwrite the whole required html.
9
+ # When using html, text and mark won't be used.
10
+ # html: '<abbr title="required">*</abbr>'
11
+ error_notification:
12
+ default_message: "Please review the problems below:"
13
+ # Examples
14
+ # labels:
15
+ # defaults:
16
+ # password: 'Password'
17
+ # user:
18
+ # new:
19
+ # email: 'E-mail to sign in.'
20
+ # edit:
21
+ # email: 'E-mail.'
22
+ # hints:
23
+ # defaults:
24
+ # username: 'User name to sign in.'
25
+ # password: 'No special characters, please.'
26
+ # include_blanks:
27
+ # defaults:
28
+ # age: 'Rather not say'
29
+ # prompts:
30
+ # defaults:
31
+ # age: 'Select your age'
@@ -0,0 +1,13 @@
1
+ 'zh-CN':
2
+ activerecord:
3
+ models:
4
+ weixin_pam/user_account: 微信用户
5
+ attributes:
6
+ weixin_pam/user_account:
7
+ nickname: 昵称
8
+ sex: 性别
9
+ province: 省份
10
+ city: 城市
11
+ country: 国家
12
+ headimgurl: 头像
13
+ subscribed: 关注
@@ -0,0 +1,17 @@
1
+ WeixinPam::Engine.routes.draw do
2
+ resources :public_accounts do
3
+ resources :diymenus, except: :show do
4
+ collection do
5
+ post :sort
6
+ post :upload
7
+ post :download
8
+ end
9
+ end
10
+ resources :user_accounts, only: [:index] do
11
+ collection do
12
+ post :sync
13
+ end
14
+ end
15
+ end
16
+ mount WeixinRailsMiddleware::Engine, at: "/"
17
+ end
@@ -0,0 +1,14 @@
1
+ class CreateWeixinPamPublicAccounts < ActiveRecord::Migration
2
+ def change
3
+ create_table :weixin_pam_public_accounts do |t|
4
+ t.string :name
5
+ t.string :app_id
6
+ t.string :app_secret
7
+ t.string :api_url
8
+ t.string :api_token
9
+ t.boolean :enabled
10
+
11
+ t.timestamps null: false
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ class CreateWeixinPamUserAccounts < ActiveRecord::Migration
2
+ def change
3
+ create_table :weixin_pam_user_accounts do |t|
4
+ t.references :public_account, index: true
5
+ t.string :uid
6
+ t.string :nickname
7
+ t.string :sex
8
+ t.string :province
9
+ t.string :city
10
+ t.string :country
11
+ t.string :headimgurl
12
+ t.boolean :subscribed, default: false, null: false
13
+ t.string :headimg_fingerprint, limit: 32
14
+
15
+ t.timestamps null: false
16
+ end
17
+ add_index :weixin_pam_user_accounts, [:public_account_id, :uid], unique: true
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ class CreateWeixinPamDiymenus < ActiveRecord::Migration
2
+ def change
3
+ create_table :weixin_pam_diymenus do |t|
4
+ t.references :public_account, index: true
5
+ t.references :parent
6
+ t.integer :button_type
7
+ t.string :name, null: false
8
+ t.string :key
9
+ t.string :url, limit: 128
10
+ t.boolean :is_show, default: false, null: false
11
+ t.integer :sort, default: 1, null: false
12
+
13
+ t.timestamps null: false
14
+ end
15
+ add_index :weixin_pam_diymenus, [:public_account_id, :parent_id]
16
+ add_index :weixin_pam_diymenus, [:public_account_id, :key]
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ class AddWeixinSecretKeyAndWeixinTokenToPublicAccounts < ActiveRecord::Migration
2
+ def up
3
+ add_column :weixin_pam_public_accounts, :weixin_secret_key, :string
4
+ add_column :weixin_pam_public_accounts, :weixin_token, :string
5
+ add_column :weixin_pam_public_accounts, :reply_class, :string
6
+ add_index :weixin_pam_public_accounts, :weixin_secret_key
7
+ add_index :weixin_pam_public_accounts, :weixin_token
8
+ end
9
+
10
+ def down
11
+ raise ActiveRecord::IrreversibleMigration
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ class AddHostToWeixinPamPublicAccount < ActiveRecord::Migration
2
+ def change
3
+ add_column :weixin_pam_public_accounts, :host, :string
4
+ add_index :weixin_pam_public_accounts, :host
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :weixin_pam do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,13 @@
1
+ <%%= simple_form_for(@<%= singular_table_name %>) do |f| %>
2
+ <%%= f.error_notification %>
3
+
4
+ <div class="form-inputs">
5
+ <%- attributes.each do |attribute| -%>
6
+ <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %>
7
+ <%- end -%>
8
+ </div>
9
+
10
+ <div class="form-actions">
11
+ <%%= f.button :submit %>
12
+ </div>
13
+ <%% end %>
@@ -0,0 +1,3 @@
1
+ require "weixin_pam/engine"
2
+ module WeixinPam
3
+ end
@@ -0,0 +1,3 @@
1
+ Dir.glob(File.join(File.dirname(__FILE__), 'api_error', '*.rb')) do |file|
2
+ require file
3
+ end
@@ -0,0 +1,11 @@
1
+ module WeixinPam
2
+ module ApiError
3
+ class FailedResult < StandardError
4
+ attr_reader :result
5
+ def initialize(result, message)
6
+ @result = result
7
+ super(message)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,24 @@
1
+ module WeixinPam
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace WeixinPam
4
+
5
+ require_relative 'public_account_reply'
6
+ require_relative 'api_error'
7
+
8
+ require 'bootstrap-sass'
9
+ require 'sass-rails'
10
+ require 'simple_form'
11
+ require 'jquery-turbolinks'
12
+ require 'weixin_authorize'
13
+ require 'font-awesome-rails'
14
+ require 'rails-i18n'
15
+ require 'weixin_rails_middleware'
16
+
17
+ config.to_prepare do
18
+ # Load application's model / class decorators
19
+ Dir.glob(File.join(File.dirname(__FILE__), "../../app/**/*_decorator*.rb")) do |c|
20
+ Rails.configuration.cache_classes ? require(c) : load(c)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,222 @@
1
+ require 'weixin_rails_middleware/helpers/reply_weixin_message_helper'
2
+ module WeixinPam
3
+ class PublicAccountReply
4
+
5
+ class KeyEventCallback
6
+ attr_accessor :key, :callback, :description
7
+ def execute(service)
8
+ callback.call(service)
9
+ end
10
+ end
11
+
12
+ module KeyEventMethods
13
+ extend ActiveSupport::Concern
14
+
15
+ def find_key_event(key)
16
+ key = key.to_s.intern
17
+ self.class.key_event_callbacks.find { |ke| ke.key == key }
18
+ end
19
+
20
+ class_methods do
21
+ def key_event_callbacks
22
+ @key_event_callbacks ||= []
23
+ end
24
+
25
+ def key_event_desc(desc)
26
+ @current_key_event = KeyEventCallback.new
27
+ @current_key_event.description = desc
28
+ end
29
+
30
+ def define_key_event(key, &block)
31
+ @current_key_event ||= KeyEventCallback.new
32
+ @current_key_event.key = key.intern
33
+ @current_key_event.callback = block
34
+ key_event_callbacks.push(@current_key_event)
35
+ @current_key_event = nil
36
+ end
37
+ end
38
+ end
39
+
40
+ include KeyEventMethods
41
+
42
+ include WeixinRailsMiddleware::ReplyWeixinMessageHelper
43
+ attr_reader :weixin_public_account, :weixin_message, :keyword, :weixin_user_account
44
+
45
+ NO_CONTENT = :no_content
46
+
47
+ def initialize(public_account, message, keyword)
48
+ @weixin_public_account = public_account
49
+ @weixin_user_account = public_account.user_accounts.find_or_create_by!(uid: message.FromUserName)
50
+ @weixin_message = message
51
+ @keyword = keyword
52
+ end
53
+
54
+ def reply
55
+ send("response_#{@weixin_message.MsgType}_message")
56
+ end
57
+
58
+ def response_text_message
59
+ reply_with_dev_message(reply_text_message("Your Message: #{@keyword}"))
60
+ end
61
+
62
+ # <Location_X>23.134521</Location_X>
63
+ # <Location_Y>113.358803</Location_Y>
64
+ # <Scale>20</Scale>
65
+ # <Label><![CDATA[位置信息]]></Label>
66
+ def response_location_message
67
+ @lx = @weixin_message.Location_X
68
+ @ly = @weixin_message.Location_Y
69
+ @scale = @weixin_message.Scale
70
+ @label = @weixin_message.Label
71
+ reply_with_dev_message(reply_text_message("Your Location: #{@lx}, #{@ly}, #{@scale}, #{@label}"))
72
+ end
73
+
74
+ # <PicUrl><![CDATA[this is a url]]></PicUrl>
75
+ # <MediaId><![CDATA[media_id]]></MediaId>
76
+ def response_image_message
77
+ @media_id = @weixin_message.MediaId # 可以调用多媒体文件下载接口拉取数据。
78
+ @pic_url = @weixin_message.PicUrl # 也可以直接通过此链接下载图片, 建议使用carrierwave.
79
+ reply_with_dev_message(generate_image(@media_id))
80
+ end
81
+
82
+ # <Title><![CDATA[公众平台官网链接]]></Title>
83
+ # <Description><![CDATA[公众平台官网链接]]></Description>
84
+ # <Url><![CDATA[url]]></Url>
85
+ def response_link_message
86
+ @title = @weixin_message.Title
87
+ @desc = @weixin_message.Description
88
+ @url = @weixin_message.Url
89
+ reply_with_dev_message(reply_text_message("回复链接信息"))
90
+ end
91
+
92
+ # <MediaId><![CDATA[media_id]]></MediaId>
93
+ # <Format><![CDATA[Format]]></Format>
94
+ def response_voice_message
95
+ @media_id = @weixin_message.MediaId # 可以调用多媒体文件下载接口拉取数据。
96
+ @format = @weixin_message.Format
97
+ # 如果开启了语音翻译功能,@keyword则为翻译的结果
98
+ # reply_text_message("回复语音信息: #{@keyword}")
99
+ reply_with_dev_message(generate_voice(@media_id))
100
+ end
101
+
102
+ # <MediaId><![CDATA[media_id]]></MediaId>
103
+ # <ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
104
+ def response_video_message
105
+ @media_id = @weixin_message.MediaId # 可以调用多媒体文件下载接口拉取数据。
106
+ # 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
107
+ @thumb_media_id = @weixin_message.ThumbMediaId
108
+ reply_with_dev_message(reply_text_message("回复视频信息"))
109
+ end
110
+
111
+ # <MediaId><![CDATA[media_id]]></MediaId>
112
+ # <ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId>
113
+ def response_shortvideo_message
114
+ @media_id = @weixin_message.MediaId # 可以调用多媒体文件下载接口拉取数据。
115
+ # 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
116
+ @thumb_media_id = @weixin_message.ThumbMediaId
117
+ reply_with_dev_message(reply_text_message("回复短视频信息"))
118
+ end
119
+
120
+ def response_event_message
121
+ event_type = @weixin_message.Event
122
+ case event_type.downcase
123
+ when 'unsubscribe'
124
+ @weixin_public_account.user_accounts.where(uid: @weixin_message.FromUserName).limit(1).update_all(subscribed: false)
125
+ when 'subscribe'
126
+ @weixin_public_account.user_accounts.where(uid: @weixin_message.FromUserName).limit(1).update_all(subscribed: true)
127
+ end
128
+ send("handle_#{event_type.downcase}_event")
129
+ end
130
+
131
+ # 关注公众账号
132
+ def handle_subscribe_event
133
+ if @keyword.present?
134
+ # 扫描带参数二维码事件: 1. 用户未关注时,进行关注后的事件推送
135
+ return reply_with_dev_message(reply_text_message("扫描带参数二维码事件: 1. 用户未关注时,进行关注后的事件推送, keyword: #{@keyword}"))
136
+ end
137
+ reply_with_dev_message(reply_text_message("关注公众账号"))
138
+ end
139
+
140
+ # 取消关注
141
+ def handle_unsubscribe_event
142
+ Rails.logger.info("取消关注")
143
+ NO_CONTENT
144
+ end
145
+
146
+ # 扫描带参数二维码事件: 2. 用户已关注时的事件推送
147
+ def handle_scan_event
148
+ reply_with_dev_message(reply_text_message("扫描带参数二维码事件: 2. 用户已关注时的事件推送, keyword: #{@keyword}"))
149
+ end
150
+
151
+ def handle_location_event # 上报地理位置事件
152
+ @lat = @weixin_message.Latitude
153
+ @lgt = @weixin_message.Longitude
154
+ @precision = @weixin_message.Precision
155
+ reply_with_dev_message(reply_text_message("Your Location: #{@lat}, #{@lgt}, #{@precision}"))
156
+ end
157
+
158
+ # 点击菜单拉取消息时的事件推送
159
+ def handle_click_event
160
+ key_event = find_key_event(@keyword)
161
+ if key_event
162
+ key_event.execute(self)
163
+ else
164
+ reply_with_dev_message(reply_text_message("你点击了: #{@keyword}"))
165
+ end
166
+ end
167
+
168
+ # 点击菜单跳转链接时的事件推送
169
+ def handle_view_event
170
+ Rails.logger.info("你点击了: #{@keyword}")
171
+ NO_CONTENT
172
+ end
173
+
174
+ # 弹出系统拍照发图
175
+ def handle_pic_sysphoto_event
176
+ NO_CONTENT
177
+ end
178
+
179
+ # 弹出拍照或者相册发图的事件推送
180
+ def handle_pic_photo_or_album_event
181
+ NO_CONTENT
182
+ end
183
+
184
+ # 扫码事件
185
+ def handle_scancode_push_event
186
+ NO_CONTENT
187
+ end
188
+
189
+ # 帮助文档: https://github.com/lanrion/weixin_authorize/issues/22
190
+
191
+ # 由于群发任务提交后,群发任务可能在一定时间后才完成,因此,群发接口调用时,仅会给出群发任务是否提交成功的提示,若群发任务提交成功,则在群发任务结束时,会向开发者在公众平台填写的开发者URL(callback URL)推送事件。
192
+
193
+ # 推送的XML结构如下(发送成功时):
194
+
195
+ # <xml>
196
+ # <ToUserName><![CDATA[gh_3e8adccde292]]></ToUserName>
197
+ # <FromUserName><![CDATA[oR5Gjjl_eiZoUpGozMo7dbBJ362A]]></FromUserName>
198
+ # <CreateTime>1394524295</CreateTime>
199
+ # <MsgType><![CDATA[event]]></MsgType>
200
+ # <Event><![CDATA[MASSSENDJOBFINISH]]></Event>
201
+ # <MsgID>1988</MsgID>
202
+ # <Status><![CDATA[sendsuccess]]></Status>
203
+ # <TotalCount>100</TotalCount>
204
+ # <FilterCount>80</FilterCount>
205
+ # <SentCount>75</SentCount>
206
+ # <ErrorCount>5</ErrorCount>
207
+ # </xml>
208
+ def handle_masssendjobfinish_event
209
+ Rails.logger.info("回调事件处理")
210
+ NO_CONTENT
211
+ end
212
+
213
+ def handle_templatesendjobfinish_event
214
+ Rails.logger.info("回调模板任务")
215
+ NO_CONTENT
216
+ end
217
+
218
+ def reply_with_dev_message(msg)
219
+ Rails.env.development? ? msg : NO_CONTENT
220
+ end
221
+ end
222
+ end