wx_ext 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b41727e13812d26ea3ef4949f2576c899a4de8a3
4
+ data.tar.gz: 11b3b1f0ddd636b43ab554c81848e1ec356c201f
5
+ SHA512:
6
+ metadata.gz: e2620ed495169871657c6577564b3923fc1c62c9e38ea07a908f57a45195d5354b6d22b92bc66539704e756efa0278a47d0defcaaddddc17b7efaf0e3c37bd52
7
+ data.tar.gz: 7bb3b9d0c3ca7c18c2013c5a37f65d7aaeb0d585b6464d6d85f46339db43ce3cfd7986b795880e26f01cbef0d0874877a5948dce5b44a02fe05684a4d64818f4
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in wx_ext.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 flowerwrong
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # WxExt
2
+
3
+ 微信接口之外的扩展gem
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'wx_ext', :git => 'https://github.com/FlowerWrong/wx_ext.git'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ ## Usage
18
+
19
+ TODO: 用户管理接口
20
+
21
+ ## Contributing
22
+
23
+ 1. Fork it ( https://github.com/[my-github-username]/wx_ext/fork )
24
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
25
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
26
+ 4. Push to the branch (`git push origin my-new-feature`)
27
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new('spec')
@@ -0,0 +1,3 @@
1
+ module WxExt
2
+ VERSION = "0.0.1"
3
+ end
data/lib/wx_ext.rb ADDED
@@ -0,0 +1,123 @@
1
+ require "wx_ext/version"
2
+ require 'digest'
3
+ require 'rest_client'
4
+ require 'json'
5
+
6
+ module WxExt
7
+ class WeiXin
8
+ attr_accessor :account, :password, :home_url, :token, :user_name, :ticket_id, :ticket, :cookies, :operation_seq
9
+ def initialize(account, password)
10
+ @account = account
11
+ @password = password
12
+ @home_url = 'https://mp.weixin.qq.com'
13
+ @token = nil
14
+ @ticket = nil
15
+ @user_name = nil
16
+ @ticket_id = nil
17
+ @cookies = {}
18
+ @operation_seq = ''
19
+ end
20
+
21
+ # 使用用户名和密码登陆微信公众平台获取access_token, 过期时间是7200s
22
+ def init
23
+ login_name = @account
24
+ password = Digest::MD5.hexdigest @password
25
+ home_url = @home_url
26
+
27
+ login_headers = {
28
+ referer: 'https://mp.weixin.qq.com/'
29
+ }
30
+ login_params = {
31
+ username: login_name,
32
+ pwd: password,
33
+ imgcode: '',
34
+ f: 'json'
35
+ }
36
+
37
+ login_resource = RestClient::Resource.new(home_url, :headers => login_headers)
38
+ login_res = login_resource['cgi-bin/login'].post login_params, :content_type => 'text/plain'
39
+ login_cookies = login_res.cookies
40
+ login_res_str = login_res.to_s
41
+ # {"base_resp"=>{"ret"=>0, "err_msg"=>"ok"}, "redirect_url"=>"/cgi-bin/home?t=home/index&lang=zh_CN&token=1869497342"}
42
+ # {"base_resp":{"ret":-8,"err_msg":"need verify code"}}
43
+ # https://mp.weixin.qq.com/cgi-bin/verifycode?username=tuodan@thecampus.cc&r=1415774604450
44
+ login_res_hash = JSON.parse login_res_str
45
+ token_reg = /.*token=(\d+)\".*/
46
+ if token_reg =~ login_res_str
47
+ @token = $1
48
+ end
49
+
50
+ msg_send_url = "https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=#{@token}&lang=zh_CN"
51
+ msg_send_page = RestClient.get msg_send_url, {cookies: login_cookies}
52
+ @cookies = login_cookies.merge msg_send_page.cookies
53
+
54
+ ticket_reg = /.*ticket\s*:\s*\"(\w+)\".*user_name\s*:\s*\"(\w+)\".*nick_name\s*:\s*\"(.*)\".*/m
55
+
56
+ operation_seq_reg = /.*operation_seq\s*:\s*\"(\d+)\".*/
57
+ if operation_seq_reg =~ msg_send_page.to_s
58
+ @operation_seq = $1
59
+ end
60
+ if ticket_reg =~ msg_send_page.to_s
61
+ @ticket = $1
62
+ @user_name = @ticket_id= $2
63
+ true
64
+ else
65
+ nil
66
+ end
67
+ end
68
+
69
+ # 上传图片素材到素材中心
70
+ def upload_file(file, file_name, folder = "/cgi-bin/uploads")
71
+ upload_url = "https://mp.weixin.qq.com/cgi-bin/filetransfer?action=upload_material&f=json&writetype=doublewrite&groupid=1&ticket_id=#{@ticket_id}&ticket=#{@ticket}&token=#{@token}&lang=zh_CN"
72
+ response = RestClient.post upload_url, :file => file, \
73
+ :Filename => file_name, \
74
+ :folder => folder
75
+ res_hash = JSON.parse response.to_s
76
+ end
77
+
78
+ # 发送单条图文消息到素材中心
79
+ def upload_single_msg(single_msg_params)
80
+ post_single_msg_uri = "cgi-bin/operate_appmsg?t=ajax-response&sub=create&type=10&token=#{@token}&lang=zh_CN"
81
+ post_single_msg_headers = {
82
+ referer: "https://mp.weixin.qq.com/cgi-bin/appmsg?t=media/appmsg_edit&action=edit&type=10&isMul=0&isNew=1&lang=zh_CN&token=#{@token}"
83
+ }
84
+ post_single_msg_resource = RestClient::Resource.new(@home_url, headers: post_single_msg_headers, cookies: @cookies)
85
+ post_single_msg_res = post_single_msg_resource[post_single_msg_uri].post single_msg_params
86
+ # {"ret":"0", "msg":"OK"}
87
+ res_hash = JSON.parse post_single_msg_res.to_s
88
+ end
89
+
90
+ # 发送多图文到素材中心
91
+ def upload_multi_msg(msg_params)
92
+ post_msg_uri = "cgi-bin/operate_appmsg?t=ajax-response&sub=create&type=10&token=#{@token}&lang=zh_CN"
93
+ post_msg_headers = {
94
+ referer: "https://mp.weixin.qq.com/cgi-bin/appmsg?t=media/appmsg_edit&action=edit&type=10&isMul=1&isNew=1&lang=zh_CN&token=#{@token}"
95
+ }
96
+ post_msg_resource = RestClient::Resource.new(@home_url, headers: post_msg_headers, cookies: @cookies)
97
+ post_msg_res = post_msg_resource[post_msg_uri].post msg_params
98
+ # {"ret":"0", "msg":"OK"}
99
+ res_hash = JSON.parse post_msg_res.to_s
100
+ end
101
+
102
+ # 群发图文消息
103
+ def broadcast_msg(msg_params)
104
+ post_msg_uri = "cgi-bin/masssend?t=ajax-response&token=#{@token}&lang=zh_CN"
105
+ post_msg_headers = {
106
+ referer: "https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=#{token}&lang=zh_CN",
107
+ host: 'mp.weixin.qq.com'
108
+ }
109
+ post_msg_resource = RestClient::Resource.new(@home_url, :headers => post_msg_headers, cookies: @cookies)
110
+ post_msg_res = post_msg_resource[post_msg_uri].post msg_params
111
+ # {"ret":"0", "msg":"OK"}
112
+ puts post_msg_res.to_s
113
+ res_hash = JSON.parse post_msg_res.to_s
114
+ end
115
+
116
+ # 获取所有的图文列表
117
+ def get_app_msg_list(msg_begin = 0, msg_count = 10)
118
+ app_msg_url = "https://mp.weixin.qq.com/cgi-bin/appmsg?type=10&action=list&begin=#{msg_begin}&count=#{msg_count}&f=json&token=#{@token}&lang=zh_CN&token=#{@token}&lang=zh_CN&f=json&ajax=1&random=#{rand}"
119
+ msg_json = RestClient.get app_msg_url, {cookies: @cookies}
120
+ app_msg_hash = JSON.parse msg_json.to_s
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,8 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'wx_ext'
5
+
6
+ RSpec.configure do |config|
7
+ #
8
+ end
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe WxExt::WeiXin do
5
+ before(:all) do
6
+ @weixin = WxExt::WeiXin.new "login_account", "login_pass"
7
+ end
8
+
9
+ it "init method should init all params" do
10
+ flag = @weixin.init
11
+ token = @weixin.token
12
+ puts "token = " + token
13
+ expect(token).to match(/\d+/)
14
+ end
15
+
16
+ it "upload_file method should return a right hash" do
17
+ flag = @weixin.init
18
+ puts @weixin.token
19
+ puts @weixin.ticket_id
20
+ puts @weixin.ticket
21
+ file = File.new("/home/yang/dev/ruby/gem/hack_wx/spec/hack_wx/test_spec.jpg", 'rb')
22
+ file_hash = @weixin.upload_file(file, "test_spec.jpg")
23
+ puts "==" * 20
24
+ puts file_hash
25
+ expect(file_hash["base_resp"]["ret"].to_s).to eql("0")
26
+ end
27
+
28
+ it "upload_single_msg method should upload a msg to sucaizhongxin" do
29
+ flag = @weixin.init
30
+ file = File.new("/home/yang/dev/ruby/gem/hack_wx/spec/hack_wx/test_spec.jpg", 'rb')
31
+ file_hash = @weixin.upload_file(file, "test_spec.jpg")
32
+ file_id = file_hash["content"]
33
+ single_msg_params = {
34
+ AppMsgId: '',
35
+ ajax: 1,
36
+ author0: '作者' + rand.to_s,
37
+ content0: '正文' + rand.to_s,
38
+ count: 1,
39
+ digest0: 'test摘要' + rand.to_s,
40
+ f: 'json',
41
+ fileid0: file_id,
42
+ lang: 'zh_CN',
43
+ random: rand,
44
+ show_cover_pic0: 1,
45
+ sourceurl0: 'http://thecampus.cc/' + rand.to_s,
46
+ title0: 'test标题' + rand.to_s,
47
+ token: @weixin.token,
48
+ vid: ''
49
+ }
50
+ msg_hash = @weixin.upload_single_msg(single_msg_params)
51
+ puts "==" * 20
52
+ puts msg_hash
53
+ expect(msg_hash["ret"].to_s).to eql("0")
54
+ end
55
+
56
+ it "upload_multi_msg method should upload multi msg to sucaizhongxin" do
57
+ flag = @weixin.init
58
+ file = File.new("/home/yang/dev/ruby/gem/hack_wx/spec/hack_wx/test_spec.jpg", 'rb')
59
+ file_hash = @weixin.upload_file(file, "test_spec.jpg")
60
+ file_id = file_hash["content"]
61
+ msg_params = {
62
+ AppMsgId: '',
63
+ ajax: 1,
64
+ author0: 'test多图文上传作者' + rand.to_s,
65
+ author1: 'test多图文上传作者' + rand.to_s,
66
+ content0: 'test多图文上传正文' + rand.to_s,
67
+ content1: 'test多图文上传正文' + rand.to_s,
68
+ count: 2,
69
+ digest0: 'test多图文上传正文' + rand.to_s,
70
+ digest1: 'test多图文上传正文' + rand.to_s,
71
+ f: 'json',
72
+ fileid0: file_id,
73
+ fileid1: file_id,
74
+ lang: 'zh_CN',
75
+ random: rand,
76
+ show_cover_pic0: 1,
77
+ show_cover_pic1: 1,
78
+ sourceurl0: 'http://thecampus.cc/' + rand.to_s,
79
+ sourceurl1: 'http://thecampus.cc/' + rand.to_s,
80
+ title0: 'test多图文上传标题' + rand.to_s,
81
+ title1: 'test多图文上传标题' + rand.to_s,
82
+ token: @weixin.token,
83
+ vid: ''
84
+ }
85
+ msg_hash = @weixin.upload_multi_msg(msg_params)
86
+ puts "==" * 20
87
+ puts msg_hash
88
+ expect(msg_hash["ret"].to_s).to eql("0")
89
+ end
90
+
91
+ it "broadcast msg to all user should return ok" do
92
+ flag = @weixin.init
93
+
94
+ msg_hash = @weixin.get_app_msg_list
95
+ puts "==" * 20
96
+ app_msg_id = msg_hash["app_msg_info"]["item"][0]["app_id"]
97
+
98
+ msg_params = {
99
+ ajax: 1,
100
+ appmsgid: app_msg_id, # 图文appid
101
+ cardlimit: 1, # 发送限制条数
102
+ city: '',
103
+ country: '',
104
+ province: '',
105
+ f: 'json',
106
+ groupid: '-1',
107
+ imgcode: '',
108
+ lang: 'zh_CN',
109
+ operation_seq: @weixin.operation_seq, #
110
+ random: rand,
111
+ sex: 0,
112
+ synctxweibo: 0,
113
+ token: @weixin.token,
114
+ type: 10
115
+ }
116
+ msg_hash = @weixin.broadcast_msg(msg_params)
117
+ puts "==" * 20
118
+ # {"ret"=>"64004", "msg"=>"not have masssend quota today!"}
119
+ puts msg_hash
120
+ expect(msg_hash["ret"].to_s).to eql("0")
121
+ end
122
+
123
+ it "get app msg list return json" do
124
+ flag = @weixin.init
125
+
126
+ msg_hash = @weixin.get_app_msg_list
127
+ puts "==" * 20
128
+ puts msg_hash["app_msg_info"]["item"][0]["app_id"]
129
+ expect(msg_hash["base_resp"]["ret"].to_s).to eql("0")
130
+ end
131
+
132
+ end
data/wx_ext.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'wx_ext/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "wx_ext"
8
+ spec.version = WxExt::VERSION
9
+ spec.authors = ["flowerwrong"]
10
+ spec.email = ["sysuyangkang@gmail.com"]
11
+ spec.summary = %q{a gem to hack mp.weixin.qq.com}
12
+ spec.description = %q{a gem to hack mp.weixin.qq.com}
13
+ spec.homepage = "http://thecampus.cc"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+
24
+ spec.add_development_dependency "rspec"
25
+ spec.add_development_dependency "rest_client"
26
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wx_ext
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - flowerwrong
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rest_client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: a gem to hack mp.weixin.qq.com
70
+ email:
71
+ - sysuyangkang@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - lib/wx_ext.rb
82
+ - lib/wx_ext/version.rb
83
+ - spec/spec_helper.rb
84
+ - spec/wx_ext/weixin_spec.rb
85
+ - wx_ext.gemspec
86
+ homepage: http://thecampus.cc
87
+ licenses:
88
+ - MIT
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.4.2
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: a gem to hack mp.weixin.qq.com
110
+ test_files:
111
+ - spec/spec_helper.rb
112
+ - spec/wx_ext/weixin_spec.rb