Module: BlsmMpWx

Defined in:
lib/blsm-mp-wx.rb,
lib/blsm-mp-wx/version.rb,
lib/blsm-mp-wx/model/vd_mp_wx.rb,
lib/blsm-mp-wx/model/vd_mp_msg.rb,
lib/blsm-mp-wx/model/active_record.rb

Defined Under Namespace

Classes: BaseRecord, VdMpMsg, VdMpWx

Constant Summary collapse

ERROR_CODES =
{
    404 => {code: 404, msg: '未知的公众号,如有疑问,请联系[email protected]'}
}
MP_MSG_TYPES =

微信公众号消息类型

%w(new_order balance score_change distribute custom split_order order todo)
VERSION =
"0.2.4"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.APP_IDObject

Returns the value of attribute APP_ID.



20
21
22
# File 'lib/blsm-mp-wx.rb', line 20

def APP_ID
  @APP_ID
end

.APP_ID_2Object

Returns the value of attribute APP_ID_2.



21
22
23
# File 'lib/blsm-mp-wx.rb', line 21

def APP_ID_2
  @APP_ID_2
end

Class Method Details

.access_token(app_id = nil) ⇒ Object

根据app_id获取access_token 系统会根据当前的access_token即过期时间,自动更新并返回开发者无需关心这里的access_token怎么更新

Parameters

  • app_id -公众号的appid



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/blsm-mp-wx.rb', line 30

def access_token(app_id=nil)
  app_id ||= self.APP_ID
  app = VdMpWx.where(app_id: app_id).first
  return nil unless app
  return app.access_token unless app.access_token_expired? #没有过期,直接返回

  response = Faraday.new(:url => 'https://api.weixin.qq.com').get do |req|
    req.url '/cgi-bin/token'
    req.params[:appid] = app.app_id
    req.params[:secret] = app.app_secret
    req.params[:grant_type] = 'client_credential'
  end

  json_obj = parse_json(response.body)
  return nil unless json_obj
  return nil unless json_obj.has_key?('access_token')

  access_token = json_obj['access_token']
  app.save_access_token(access_token, json_obj['expires_in'])

  access_token
end

.batchget_material(app_id, type, offset, count = 20) ⇒ Object

批量获取公众号的素材列表

Parameters
  • app_id

  • type 素材类型:voice、video、image、news

  • offset

  • count



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/blsm-mp-wx.rb', line 295

def batchget_material(app_id, type, offset, count=20)
  app_id ||= self.APP_ID
  access_token = access_token(app_id)
  return nil unless access_token
  response = Faraday.new(:url => 'https://api.weixin.qq.com').post do |req|
    req.url '/cgi-bin/material/batchget_material'
    req.headers['Content-Type'] = 'application/json'
    data = {
        type: type,
        offset: offset,
        count: count
    }
    req.params[:access_token] = access_token
    req.body = data.to_json
  end

  json_obj = parse_json(response.body)
  return nil unless json_obj
  return nil unless json_obj.has_key?('total_count')
  json_obj.inject({}) { |memo, (key, v)| memo[key.to_s.to_sym]=v; memo }
end

.create_msg(app_id = nil, openid, content, msg_name) ⇒ Object

创建消息,存储到消息队列中

Parameters

  • app_id - 公众号的唯一标识

  • openid - 发送给用户的openid

  • content - 消息内容

  • msg_name - 消息种类:new_order(新订单通知)、balance(结算通知)、score_change(积分变动通知)、order(订单通知)、todo(待处理)、split_order(分单)、custom(普通消息)

new_order => content: {touser:'openid',order_id:''} 


221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/blsm-mp-wx.rb', line 221

def create_msg(app_id=nil, openid, content, msg_name)
  app_id ||= self.APP_ID
  return nil unless openid
  return nil unless content[:touser]==openid
  return nil unless MP_MSG_TYPES.include?(msg_name)
  VdMpMsg.create({
                     app_id: app_id,
                     openid: openid,
                     content: content.to_json,
                     msg_name: msg_name,
                     template_msg: MP_MSG_TYPES.include?(msg_name),
                     status: 'none'
                 })
end

.create_msg!(app_id = nil, openid, content, msg_name) ⇒ Object



237
238
239
240
241
242
243
244
245
246
247
# File 'lib/blsm-mp-wx.rb', line 237

def create_msg!(app_id=nil, openid, content, msg_name)
  app_id ||= self.APP_ID
  VdMpMsg.create!({
                      app_id: app_id,
                      openid: openid,
                      content: content.to_json,
                      msg_name: msg_name,
                      template_msg: MP_MSG_TYPES.include?(msg_name),
                      status: 'none'
                  })
end

.gen_forever_qr_ticket(app_id = nil, scene_id) ⇒ Object

生成永久二维码ticket



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/blsm-mp-wx.rb', line 170

def gen_forever_qr_ticket(app_id=nil, scene_id)
  app_id ||= self.APP_ID
  access_token = access_token(app_id)
  return nil unless access_token

  response = Faraday.new(:url => 'https://api.weixin.qq.com').post do |req|
    req.url '/cgi-bin/qrcode/create'
    req.params[:access_token] = access_token
    req.body="{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": #{scene_id}}}}"
  end

  json_obj = parse_json(response.body)
  return nil unless json_obj
  return nil unless json_obj.has_key?('ticket')

  json_obj['ticket']
end

.gen_short_url(app_id = nil, long_url) ⇒ Object

长链接转短连接



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/blsm-mp-wx.rb', line 189

def gen_short_url(app_id=nil, long_url)
  app_id ||= self.APP_ID
  access_token = access_token(app_id)
  return nil unless access_token

  response = Faraday.new(:url => 'https://api.weixin.qq.com').post do |req|
    req.url '/cgi-bin/shorturl'
    req.headers['Content-Type'] = 'application/json'
    data = {
        action: 'long2short',
        long_url: long_url
    }
    req.params[:long_url] = long_url
    req.params[:access_token] = access_token
    req.body = data.to_json
  end

  json_obj = parse_json(response.body)
  return nil unless json_obj
  return nil unless json_obj.has_key?('short_url')
  json_obj['short_url']
end

.gen_wx_user_info(app_id = nil, openid) ⇒ Object

获取用户的基本信息(包括UnionID机制)



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/blsm-mp-wx.rb', line 150

def (app_id=nil, openid)
  app_id ||= self.APP_ID
  access_token = access_token(app_id)
  return nil unless access_token

  response = Faraday.new(:url => 'https://api.weixin.qq.com').get do |req|
    req.url '/cgi-bin/user/info'
    req.params[:openid] = openid
    req.params[:access_token] = access_token
  end

  json_obj = parse_json(response.body)
  puts "#{json_obj}"
  return nil unless json_obj
  return json_obj.inject({}) { |memo, (key, v)| memo[key.to_s.to_sym]=v; memo } if json_obj.has_key?('openid')

  nil
end

.get_material(app_id, media_id) ⇒ Object

根据media_id来获取永久素材

Parameters
  • app_id

  • media_id 要获取的素材的media_id



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'lib/blsm-mp-wx.rb', line 273

def get_material(app_id, media_id)
  app_id ||= self.APP_ID
  access_token = access_token(app_id)
  return nil unless access_token
  response = Faraday.new(:url => 'https://api.weixin.qq.com').post do |req|
    req.url '/cgi-bin/material/get_material'
    req.headers['Content-Type'] = 'application/json'
    req.params[:access_token] = access_token
    req.body= {media_id: media_id}.to_json
  end
  body = response.body
  json_obj = parse_json(body)
  return body unless json_obj
  json_obj.inject({}) { |memo, (key, v)| memo[key.to_s.to_sym]=v; memo }
end

.get_material_count(app_id, type) ⇒ Object

批量获取公众号的素材列表

Parameters
  • app_id

  • type 素材类型:voice、video、image、news



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/blsm-mp-wx.rb', line 253

def get_material_count(app_id, type)
  app_id ||= self.APP_ID
  access_token = access_token(app_id)
  return nil unless access_token
  response = Faraday.new(:url => 'https://api.weixin.qq.com').post do |req|
    req.url '/cgi-bin/material/get_materialcount'
    req.headers['Content-Type'] = 'application/json'
    req.params[:access_token] = access_token
  end

  json_obj = parse_json(response.body)
  return nil unless json_obj
  return nil unless json_obj.has_key?("#{type}_count")
  json_obj["#{type}_count"].to_i
end

.js_api_sign_package(app_id = nil, url) ⇒ Object

JSAPI签名package



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/blsm-mp-wx.rb', line 131

def js_api_sign_package(app_id=nil, url)
  app_id ||= self.APP_ID
  ticket = js_api_ticket(app_id)
  timestamp = Time.new.to_i
  nonce_str = Digest::MD5.hexdigest(Time.new.to_i.to_s + Random.rand(99999).to_s)
  string = "jsapi_ticket=#{ticket}&noncestr=#{nonce_str}&timestamp=#{timestamp}&url=#{url}"
  signature = Digest::SHA1.hexdigest(string)
  {
      appId: app_id,
      nonceStr: nonce_str,
      timestamp: timestamp,
      url: url,
      signature: signature,
      rawString: string
  }
end

.js_api_ticket(app_id = nil) ⇒ Object

获取jsapi全局唯一票据



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/blsm-mp-wx.rb', line 54

def js_api_ticket(app_id=nil)
  app_id ||= self.APP_ID
  access_token = access_token(app_id)
  app = VdMpWx.where(app_id: app_id).first

  return nil unless access_token
  return nil unless app
  return app.js_api_ticket unless app.js_api_ticket_expired? #没有过期,直接返回

  response = Faraday.new(:url => 'https://api.weixin.qq.com').get do |req|
    req.url '/cgi-bin/ticket/getticket'
    req.params[:access_token] = access_token
    req.params[:type] = 'jsapi'
  end

  json_obj = parse_json(response.body)
  return nil unless json_obj
  return nil unless json_obj.has_key?('ticket')

  ticket = json_obj['ticket']
  app.save_js_api_ticket(ticket, json_obj['expires_in'])

  ticket
end

.send_msg(app_id = nil, openid, msg) ⇒ Object

发送普通消息文本消息:{

"touser":"OPENID",
"msgtype":"text",
"text":
{
      "content":"Hello World"
}

} 图文消息:{ “touser”:“OPENID”,

  "msgtype":"news",
  "news":
{
  "articles": [
      {
          "title":"Happy Day",
      "description":"Is Really A Happy Day",
      "url":"URL",
      "picurl":"PIC_URL"
      },
      {
       "title":"Happy Day",
      "description":"Is Really A Happy Day",
      "url":"URL",
      "picurl":"PIC_URL"
      }
  ]
}

}



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/blsm-mp-wx.rb', line 111

def send_msg(app_id=nil, openid, msg)
  app_id ||= self.APP_ID
  access_token = access_token(app_id)
  return nil unless access_token
  return nil unless openid
  return nil unless msg[:touser]==openid

  response = Faraday.new(:url => 'https://api.weixin.qq.com').post do |req|
    req.url '/cgi-bin/message/custom/send'
    req.params[:access_token] = access_token
    req.headers['Content-Type'] = 'application/json'
    req.body = msg.to_json
  end

  json_obj = parse_json(response.body)
  return nil unless json_obj
  json_obj['errcode']==0
end