qqbot 0.0.1 → 0.0.2
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 +4 -4
- data/.gitignore +15 -13
- data/Gemfile +4 -4
- data/README.md +63 -40
- data/lib/qqbot.rb +23 -17
- data/lib/qqbot/api.rb +149 -42
- data/lib/qqbot/auth.rb +180 -180
- data/lib/qqbot/bot.rb +172 -41
- data/lib/qqbot/client.rb +67 -67
- data/lib/qqbot/cookie.rb +28 -28
- data/lib/qqbot/model.rb +25 -0
- data/lib/qqbot/version.rb +3 -3
- data/qqbot.gemspec +33 -33
- metadata +5 -4
data/lib/qqbot/bot.rb
CHANGED
@@ -1,41 +1,172 @@
|
|
1
|
-
module QQBot
|
2
|
-
class Bot
|
3
|
-
def initialize
|
4
|
-
@client = QQBot::Client.new
|
5
|
-
@auth = QQBot::Auth.new @client
|
6
|
-
end
|
7
|
-
|
8
|
-
def login
|
9
|
-
@auth.get_qrcode
|
10
|
-
|
11
|
-
url = ''
|
12
|
-
|
13
|
-
until url.start_with? 'http' do
|
14
|
-
sleep 5
|
15
|
-
url = @auth.verify_qrcode
|
16
|
-
@auth.get_qrcode if url == '-1'
|
17
|
-
end
|
18
|
-
|
19
|
-
@auth.get_ptwebqq url
|
20
|
-
|
21
|
-
@auth.get_vfwebqq
|
22
|
-
|
23
|
-
@auth.get_psessionid_and_uin
|
24
|
-
|
25
|
-
auth_options = @auth.options
|
26
|
-
|
27
|
-
@api = QQBot::Api.new(@client, auth_options)
|
28
|
-
end
|
29
|
-
|
30
|
-
def poll
|
31
|
-
return if @api.nil?
|
32
|
-
|
33
|
-
loop do
|
34
|
-
@api.poll
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
1
|
+
module QQBot
|
2
|
+
class Bot
|
3
|
+
def initialize
|
4
|
+
@client = QQBot::Client.new
|
5
|
+
@auth = QQBot::Auth.new @client
|
6
|
+
end
|
7
|
+
|
8
|
+
def login
|
9
|
+
@auth.get_qrcode
|
10
|
+
|
11
|
+
url = ''
|
12
|
+
|
13
|
+
until url.start_with? 'http' do
|
14
|
+
sleep 5
|
15
|
+
url = @auth.verify_qrcode
|
16
|
+
@auth.get_qrcode if url == '-1'
|
17
|
+
end
|
18
|
+
|
19
|
+
@auth.get_ptwebqq url
|
20
|
+
|
21
|
+
@auth.get_vfwebqq
|
22
|
+
|
23
|
+
@auth.get_psessionid_and_uin
|
24
|
+
|
25
|
+
auth_options = @auth.options
|
26
|
+
|
27
|
+
@api = QQBot::Api.new(@client, auth_options)
|
28
|
+
end
|
29
|
+
|
30
|
+
def poll &block
|
31
|
+
return if @api.nil?
|
32
|
+
|
33
|
+
loop do
|
34
|
+
json = @api.poll
|
35
|
+
unless json.nil?
|
36
|
+
json.each do |item|
|
37
|
+
message = QQBot::Message.new
|
38
|
+
value = item['value']
|
39
|
+
case item['poll_type']
|
40
|
+
when 'message' then
|
41
|
+
message.type = 0
|
42
|
+
message.from_id = value['from_uin']
|
43
|
+
message.send_id = value['from_uin']
|
44
|
+
when 'group_message' then
|
45
|
+
message.type = 1
|
46
|
+
message.from_id = value['from_uin']
|
47
|
+
message.send_id = value['send_uin']
|
48
|
+
when 'discu_message' then
|
49
|
+
message.type = 2
|
50
|
+
message.from_id = value['from_uin']
|
51
|
+
message.send_id = value['send_uin']
|
52
|
+
else
|
53
|
+
message.type = 3
|
54
|
+
end
|
55
|
+
message.time = value['time']
|
56
|
+
message.content = value['content'][1]
|
57
|
+
|
58
|
+
font = QQBot::Font.new
|
59
|
+
font_json = value['content'][0][1]
|
60
|
+
font.color = font_json['color']
|
61
|
+
font.name = font_json['name']
|
62
|
+
font.size = font_json['size']
|
63
|
+
font.style = font_json['style']
|
64
|
+
message.font = font
|
65
|
+
|
66
|
+
block.call message
|
67
|
+
end
|
68
|
+
end
|
69
|
+
sleep 1
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def get_group_list
|
74
|
+
json = @api.nil? ? nil : @api.get_group_list
|
75
|
+
|
76
|
+
unless json.nil?
|
77
|
+
group_map = {}
|
78
|
+
|
79
|
+
gnamelist = json['gnamelist']
|
80
|
+
gnamelist.each do |item|
|
81
|
+
group = QQBot::Group.new
|
82
|
+
group.name = item['name']
|
83
|
+
group.id = item['gid']
|
84
|
+
group.code = item['code']
|
85
|
+
group_map[group.id] = group
|
86
|
+
end
|
87
|
+
|
88
|
+
gmarklist = json['gmarklist']
|
89
|
+
gmarklist.each do |item|
|
90
|
+
group_map[item['uin']].markname = item['markname']
|
91
|
+
end
|
92
|
+
|
93
|
+
return group_map.values
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def get_friend_list
|
98
|
+
json = @api.nil? ? nil : @api.get_friend_list
|
99
|
+
|
100
|
+
unless json.nil?
|
101
|
+
friend_map = {}
|
102
|
+
category_list = []
|
103
|
+
|
104
|
+
friends = json['friends']
|
105
|
+
friends.each do |item|
|
106
|
+
friend = QQBot::Friend.new
|
107
|
+
friend.id = item['uin']
|
108
|
+
friend.category_id = item['categories']
|
109
|
+
friend_map[friend.id] = friend
|
110
|
+
end
|
111
|
+
|
112
|
+
marknames = json['marknames']
|
113
|
+
marknames.each do |item|
|
114
|
+
friend_map[item['uin']].markname = item['markname']
|
115
|
+
end
|
116
|
+
|
117
|
+
vipinfo = json['vipinfo']
|
118
|
+
vipinfo.each do |item|
|
119
|
+
friend = friend_map[item['u']]
|
120
|
+
friend.is_vip = item['is_vip']
|
121
|
+
friend.vip_level = item['vip_level']
|
122
|
+
end
|
123
|
+
|
124
|
+
info = json['info']
|
125
|
+
info.each do |item|
|
126
|
+
friend_map[item['uin']].nickname = item['nick']
|
127
|
+
end
|
128
|
+
|
129
|
+
categories = json['categories']
|
130
|
+
has_default_category = false
|
131
|
+
categories.each do |item|
|
132
|
+
category = QQBot::Category.new
|
133
|
+
category.name = item['name']
|
134
|
+
category.sort = item['sort']
|
135
|
+
category.id = item['index']
|
136
|
+
category.friends = friend_map.values.select { |friend| friend.category_id == category.id }
|
137
|
+
category_list << category
|
138
|
+
has_default_category ||= (category.id == 0)
|
139
|
+
end
|
140
|
+
|
141
|
+
unless has_default_category
|
142
|
+
category = QQBot::Category.new
|
143
|
+
category.name = '我的好友(默认)'
|
144
|
+
category.sort = 1
|
145
|
+
category.id = 0
|
146
|
+
category.friends = friend_map.values.select { |friend| friend.category_id == category.id }
|
147
|
+
category_list << category
|
148
|
+
end
|
149
|
+
|
150
|
+
return category_list
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def get_discuss_list
|
155
|
+
json = @api.nil? ? nil : @api.get_discuss_list
|
156
|
+
|
157
|
+
unless json.nil?
|
158
|
+
discuss_list = []
|
159
|
+
|
160
|
+
dnamelist = json['dnamelist']
|
161
|
+
dnamelist.each do |item|
|
162
|
+
discuss = QQBot::Discuss.new
|
163
|
+
discuss.name = item['name']
|
164
|
+
discuss.id = item['did']
|
165
|
+
discuss_list << discuss
|
166
|
+
end
|
167
|
+
|
168
|
+
return discuss_list
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
data/lib/qqbot/client.rb
CHANGED
@@ -1,67 +1,67 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'openssl'
|
3
|
-
|
4
|
-
module QQBot
|
5
|
-
class Client
|
6
|
-
|
7
|
-
@@user_agent = 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36';
|
8
|
-
|
9
|
-
def self.origin uri
|
10
|
-
uri.scheme + '://' + uri.host
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize
|
14
|
-
@cookie = QQBot::Cookie.new
|
15
|
-
end
|
16
|
-
|
17
|
-
def get(uri, referer = '')
|
18
|
-
Net::HTTP.start(uri.host, uri.port,
|
19
|
-
use_ssl: uri.scheme == 'https',
|
20
|
-
verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
|
21
|
-
|
22
|
-
req = Net::HTTP::Get.new uri
|
23
|
-
|
24
|
-
req.initialize_http_header(
|
25
|
-
'User-Agent' => @@user_agent,
|
26
|
-
'Cookie' => @cookie.to_s,
|
27
|
-
'Referer' => referer
|
28
|
-
)
|
29
|
-
|
30
|
-
res = http.request req
|
31
|
-
|
32
|
-
@cookie.put res.get_fields('set-cookie')
|
33
|
-
|
34
|
-
return res.code, res.body
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def post(uri, referer = '', form_data = {})
|
39
|
-
Net::HTTP.start(uri.host, uri.port,
|
40
|
-
use_ssl: uri.scheme == 'https',
|
41
|
-
verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
|
42
|
-
|
43
|
-
req = Net::HTTP::Post.new uri
|
44
|
-
|
45
|
-
req.set_form_data(form_data)
|
46
|
-
|
47
|
-
req.initialize_http_header(
|
48
|
-
'User-Agent' => @@user_agent,
|
49
|
-
'Cookie' => @cookie.to_s,
|
50
|
-
'Referer' => referer,
|
51
|
-
'Origin' => self.class.origin(uri)
|
52
|
-
)
|
53
|
-
|
54
|
-
res = http.request req
|
55
|
-
|
56
|
-
@cookie.put res.get_fields('set-cookie')
|
57
|
-
|
58
|
-
return res.code, res.body
|
59
|
-
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def get_cookie key
|
64
|
-
@cookie[key]
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
1
|
+
require 'net/http'
|
2
|
+
require 'openssl'
|
3
|
+
|
4
|
+
module QQBot
|
5
|
+
class Client
|
6
|
+
|
7
|
+
@@user_agent = 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36';
|
8
|
+
|
9
|
+
def self.origin uri
|
10
|
+
uri.scheme + '://' + uri.host
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@cookie = QQBot::Cookie.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def get(uri, referer = '')
|
18
|
+
Net::HTTP.start(uri.host, uri.port,
|
19
|
+
use_ssl: uri.scheme == 'https',
|
20
|
+
verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
|
21
|
+
|
22
|
+
req = Net::HTTP::Get.new uri
|
23
|
+
|
24
|
+
req.initialize_http_header(
|
25
|
+
'User-Agent' => @@user_agent,
|
26
|
+
'Cookie' => @cookie.to_s,
|
27
|
+
'Referer' => referer
|
28
|
+
)
|
29
|
+
|
30
|
+
res = http.request req
|
31
|
+
|
32
|
+
@cookie.put res.get_fields('set-cookie')
|
33
|
+
|
34
|
+
return res.code, res.body
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def post(uri, referer = '', form_data = {})
|
39
|
+
Net::HTTP.start(uri.host, uri.port,
|
40
|
+
use_ssl: uri.scheme == 'https',
|
41
|
+
verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
|
42
|
+
|
43
|
+
req = Net::HTTP::Post.new uri
|
44
|
+
|
45
|
+
req.set_form_data(form_data)
|
46
|
+
|
47
|
+
req.initialize_http_header(
|
48
|
+
'User-Agent' => @@user_agent,
|
49
|
+
'Cookie' => @cookie.to_s,
|
50
|
+
'Referer' => referer,
|
51
|
+
'Origin' => self.class.origin(uri)
|
52
|
+
)
|
53
|
+
|
54
|
+
res = http.request req
|
55
|
+
|
56
|
+
@cookie.put res.get_fields('set-cookie')
|
57
|
+
|
58
|
+
return res.code, res.body
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_cookie key
|
64
|
+
@cookie[key]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/qqbot/cookie.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
|
-
module QQBot
|
2
|
-
class Cookie
|
3
|
-
|
4
|
-
def initialize
|
5
|
-
@cookies = {}
|
6
|
-
end
|
7
|
-
|
8
|
-
def put set_cookie_array
|
9
|
-
return if set_cookie_array
|
10
|
-
|
11
|
-
set_cookie_array.each do |set_cookie|
|
12
|
-
set_cookie.split('; ').each do |cookie|
|
13
|
-
k, v = cookie.split('=')
|
14
|
-
@cookies[k] = v unless v
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def [] key
|
20
|
-
@cookies[key] || ''
|
21
|
-
end
|
22
|
-
|
23
|
-
def to_s
|
24
|
-
@cookies.map{ |k, v| "#{k}=#{v}" }.join('; ')
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|
1
|
+
module QQBot
|
2
|
+
class Cookie
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@cookies = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def put set_cookie_array
|
9
|
+
return if set_cookie_array.nil?
|
10
|
+
|
11
|
+
set_cookie_array.each do |set_cookie|
|
12
|
+
set_cookie.split('; ').each do |cookie|
|
13
|
+
k, v = cookie.split('=')
|
14
|
+
@cookies[k] = v unless v.nil?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def [] key
|
20
|
+
@cookies[key] || ''
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
@cookies.map{ |k, v| "#{k}=#{v}" }.join('; ')
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/lib/qqbot/model.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module QQBot
|
2
|
+
class Group
|
3
|
+
attr_accessor :name, :code, :id, :markname
|
4
|
+
end
|
5
|
+
|
6
|
+
class Friend
|
7
|
+
attr_accessor :nickname, :category_id, :id, :is_vip, :vip_level, :markname
|
8
|
+
end
|
9
|
+
|
10
|
+
class Category
|
11
|
+
attr_accessor :name, :sort, :id, :friends
|
12
|
+
end
|
13
|
+
|
14
|
+
class Discuss
|
15
|
+
attr_accessor :name, :id
|
16
|
+
end
|
17
|
+
|
18
|
+
class Message
|
19
|
+
attr_accessor :type, :from_id, :send_id, :time, :content, :font
|
20
|
+
end
|
21
|
+
|
22
|
+
class Font
|
23
|
+
attr_accessor :color, :name, :size, :style
|
24
|
+
end
|
25
|
+
end
|
data/lib/qqbot/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module QQBot
|
2
|
-
VERSION = "0.0.
|
3
|
-
end
|
1
|
+
module QQBot
|
2
|
+
VERSION = "0.0.2"
|
3
|
+
end
|
data/qqbot.gemspec
CHANGED
@@ -1,33 +1,33 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'qqbot/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = "qqbot"
|
8
|
-
spec.version = QQBot::VERSION
|
9
|
-
spec.authors = ["ScienJus"]
|
10
|
-
spec.email = ["i@scienjus.com"]
|
11
|
-
|
12
|
-
spec.summary = %q{a qq bot based on smart qq(web qq).}
|
13
|
-
spec.description = %q{a qq bot based on smart qq api
|
14
|
-
spec.homepage = "https://github.com/ScienJus/qqbot"
|
15
|
-
spec.license = "MIT"
|
16
|
-
|
17
|
-
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
|
-
# delete this section to allow pushing this gem to any host.
|
19
|
-
if spec.respond_to?(:metadata)
|
20
|
-
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
21
|
-
else
|
22
|
-
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
23
|
-
end
|
24
|
-
|
25
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
|
-
spec.bindir = "exe"
|
27
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
-
spec.require_paths = ["lib"]
|
29
|
-
|
30
|
-
spec.add_development_dependency "bundler", "~> 1.11"
|
31
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
32
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
33
|
-
end
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'qqbot/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "qqbot"
|
8
|
+
spec.version = QQBot::VERSION
|
9
|
+
spec.authors = ["ScienJus"]
|
10
|
+
spec.email = ["i@scienjus.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{a qq bot based on smart qq(web qq).}
|
13
|
+
spec.description = %q{a qq bot based on smart qq api.}
|
14
|
+
spec.homepage = "https://github.com/ScienJus/qqbot"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
|
+
# delete this section to allow pushing this gem to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
21
|
+
else
|
22
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
23
|
+
end
|
24
|
+
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
|
+
spec.bindir = "exe"
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
spec.add_development_dependency "bundler", "~> 1.11"
|
31
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
32
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
33
|
+
end
|