rubirai 0.0.3.pre.a1 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9af7ce359d2d64f6e7f1228870a74558fc3004b6b5f23257b951c13893ca4599
4
- data.tar.gz: 421a1ecaa61dd1049501873197b01b22fe78bbdc7ef8c38766f20582ee598125
3
+ metadata.gz: 5f41f579f9ae1486c4a8f5af2e12e7e98e2aab20b880b9d2b1781eb57f480c3b
4
+ data.tar.gz: 2044c0aabd41caba57890b30b1951e0440046201e1b4eaa1f91fc766ae404e1a
5
5
  SHA512:
6
- metadata.gz: ae1ada8f42c7d9c8df3422262782b2c2a5ee16a8611d104ccd53d78c156430d8e88e9d8bff1283b05bca3c7faf530ab8af71e3ea1cdf81dbfab9b296838bbbc5
7
- data.tar.gz: 9621c881cd3812da59a2c1371c5ed56d87bd8971c6c472c056ce05b1159a37333f1d3701a0b3fe287278fe9e33b5de357baa7f8df4c7bbea554ab93a4c035224
6
+ metadata.gz: c34f19d099e6f2d85e403e93d9c03b82b5ad9325f26f7de0714e517b73d0ec041de372bf534bbffa34aef342394411012dd1cbf78da2a3afac87409006a547b7
7
+ data.tar.gz: 8392b2ea57dc0eb3df290a4e2b357bc184102879904fb38bbd5e9ce60bd7071b9be686fad559aff5b9ef4b8711e93bf205949fc9605991c661429425d3b31ebb
@@ -5,7 +5,7 @@ on:
5
5
  branches: [ master ]
6
6
 
7
7
  jobs:
8
- test:
8
+ gendoc:
9
9
  runs-on: ubuntu-latest
10
10
  strategy:
11
11
  matrix:
@@ -7,7 +7,6 @@ on:
7
7
 
8
8
  jobs:
9
9
  publish:
10
- if: github.event.base_ref == 'refs/heads/master'
11
10
  runs-on: ubuntu-latest
12
11
  steps:
13
12
  - uses: actions/checkout@v2
@@ -9,7 +9,9 @@ name: Pull Request
9
9
 
10
10
  on:
11
11
  pull_request:
12
- branches: [ master ]
12
+ branches:
13
+ - master
14
+ - dev
13
15
 
14
16
  jobs:
15
17
  test:
data/README.md CHANGED
@@ -11,6 +11,28 @@ A light-weight Mirai QQ bot http interface lib for Ruby.
11
11
 
12
12
  [中文][wiki] | [Rubydocs][rubydocs]
13
13
 
14
+ ## Description
15
+
16
+ This library is designed specifically for integration with [mirai-api-http].
17
+ [Mirai][mirai] is a QQ bot framework. The relationship is like this:
18
+
19
+ ```
20
+ mirai <-jvm-> mirai-console <-plugin-> mirai-api-http <-http-> rubirai
21
+ ```
22
+
23
+ [mirai-api-http]: https://github.com/project-mirai/mirai-api-http
24
+ [mirai]: https://github.com/mamoe/mirai
25
+
26
+ ## Prerequisite
27
+
28
+ Install [mirai-api-http] and configure its `setting.yml` file.
29
+
30
+ Now its easier to enable `singleMode` if you have only one account
31
+ in the mirai console.
32
+
33
+ Note that you **must** enable Http Adapter with configuration of
34
+ `http` under `adapterSettings`. More mode support to come.
35
+
14
36
  ## Usage
15
37
 
16
38
  First, download the package using `gem`. In your `Gemfile`, add
@@ -26,7 +48,7 @@ require 'rubirai'
26
48
  # assuming your mirai http api address and port
27
49
  # are 127.0.0.1 and 8080
28
50
  bot = Rubirai::Bot.new('127.0.0.1', '8080')
29
- # qq and auth key
51
+ # qq and verify key
30
52
  bot.login 1145141919, 'ikisugi_key'
31
53
 
32
54
  # Add a listener function
@@ -53,10 +75,13 @@ gem install rubirai
53
75
  - [中文 Wiki][wiki]
54
76
  - [Docs][rubydocs]
55
77
 
56
-
57
78
  ## License
79
+
80
+ [AGPL-3.0 License][license]
81
+
58
82
  [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FShimogawa%2Frubirai.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FShimogawa%2Frubirai?ref=badge_large)
59
83
 
60
84
 
61
85
  [wiki]: https://github.com/Shimogawa/rubirai/wiki
62
86
  [rubydocs]: https://www.rebuild.moe/rubirai/
87
+ [license]: LICENSE
data/lib/rubirai/auth.rb CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  module Rubirai
4
4
  class Bot
5
- # Start authentication. Will store the session.
6
- # @param auth_key [String] the auth key defined in config file
5
+ # Start verification. Will store the session.
6
+ # @param verify_key [String] the auth key defined in config file
7
7
  # @return [String] the session key which will also be stored in the bot
8
- def auth(auth_key)
9
- v = call :post, '/auth', json: { "authKey": auth_key }
8
+ def verify(verify_key)
9
+ v = call :post, '/verify', json: { "verifyKey": verify_key }
10
10
  @session = v['session']
11
11
  end
12
12
 
@@ -14,11 +14,11 @@ module Rubirai
14
14
  # @param qq [String, Integer] qq id
15
15
  # @param session [String, nil] the session key. Set to `nil` will use the saved credentials.
16
16
  # @return [void]
17
- def verify(qq, session = nil)
17
+ def bind(qq, session = nil)
18
18
  check qq, session
19
19
 
20
- call :post, '/verify', json: { "sessionKey": @session || session, "qq": qq.to_i }
21
- @session = session if session
20
+ call :post, '/bind', json: { "sessionKey": @session || session, "qq": qq.to_i }
21
+ @session ||= session
22
22
  @qq = qq
23
23
  nil
24
24
  end
@@ -42,13 +42,16 @@ module Rubirai
42
42
  # Log you in.
43
43
  #
44
44
  # @param qq [String, Integer] qq id
45
- # @param auth_key [String] the auth key set in the settings file for mirai-api-http.
45
+ # @param verify_key [String] the auth key set in the settings file for mirai-api-http.
46
+ # @param single_mode [Boolean] if to skip binding (need to enable `singeMode` for
47
+ # mirai-http-api)
46
48
  # @return [void]
47
- # @see #auth
49
+ # @see #bind
48
50
  # @see #verify
49
- def login(qq, auth_key)
50
- auth auth_key
51
- verify qq
51
+ def login(qq, verify_key, single_mode: false)
52
+ verify verify_key
53
+ single_mode or bind(qq)
54
+ nil
52
55
  end
53
56
 
54
57
  alias connect login
@@ -58,22 +58,7 @@ module Rubirai
58
58
  attr_keys.each do |k|
59
59
  k2 = k.to_s.snake_to_camel(lower: true)
60
60
  val = hash[k2]
61
- val = case k2
62
- when 'group'
63
- Group.new val, bot
64
- when 'operator', 'member'
65
- GroupUser.new val, bot
66
- when 'sender'
67
- if val.key? 'group'
68
- GroupUser.new val, bot
69
- else
70
- User.new val, bot
71
- end
72
- when 'messageChain'
73
- MessageChain.new bot, val
74
- else
75
- val
76
- end
61
+ val = parse_val_from_key k2, val, bot
77
62
  instance_variable_set("@#{k}", val)
78
63
  end
79
64
  end
@@ -107,6 +92,27 @@ module Rubirai
107
92
  @raw = hash
108
93
  @bot = bot
109
94
  end
95
+
96
+ protected
97
+
98
+ def parse_val_from_key(key, val, bot)
99
+ case key
100
+ when 'group'
101
+ Group.new val, bot
102
+ when 'operator', 'member'
103
+ GroupUser.new val, bot
104
+ when 'sender'
105
+ if val.key? 'group'
106
+ GroupUser.new val, bot
107
+ else
108
+ User.new val, bot
109
+ end
110
+ when 'messageChain'
111
+ MessageChain.new bot, val
112
+ else
113
+ val
114
+ end
115
+ end
110
116
  end
111
117
  end
112
118
 
@@ -15,7 +15,7 @@ module Rubirai
15
15
 
16
16
  # Friend message event
17
17
  class FriendMessageEvent < MessageEvent
18
- # @!method initialize(hash, bot = nil)
18
+ # @!method initialize(hash, boxt = nil)
19
19
  # @param hash [Hash]
20
20
  # @param bot [Rubirai::Bot]
21
21
  # @!attribute [r] sender
@@ -7,7 +7,7 @@ module Rubirai
7
7
  class Bot
8
8
  # Start to listen for events
9
9
  #
10
- # @param interval [Numeric] the interval to fetch events in seconds.
10
+ # @param interval [Integer, Float] the interval to fetch events in seconds.
11
11
  # @param is_blocking [Boolean] if the listen thread should block the current thread
12
12
  # @param ignore_error [Boolean] if errors should generate error events (see {RubiraiErrorEvent})
13
13
  # @return [void]
@@ -11,7 +11,7 @@ module Rubirai
11
11
  resp = call :get, '/friendList', params: {
12
12
  sessionKey: @session
13
13
  }
14
- resp.map { |friend| User.new(friend, self) }
14
+ resp['data'].map { |friend| User.new(friend, self) }
15
15
  end
16
16
 
17
17
  # Get group list of the bot
@@ -20,7 +20,7 @@ module Rubirai
20
20
  resp = call :get, '/groupList', params: {
21
21
  sessionKey: @session
22
22
  }
23
- resp.map { |group| Group.new(group, self) }
23
+ resp['data'].map { |group| Group.new(group, self) }
24
24
  end
25
25
 
26
26
  # Get member list of a group
@@ -31,7 +31,7 @@ module Rubirai
31
31
  sessionKey: @session,
32
32
  target: group_id
33
33
  }
34
- resp.map { |member| GroupUser.new(member, self) }
34
+ resp['data'].map { |member| GroupUser.new(member, self) }
35
35
  end
36
36
  end
37
37
  end
@@ -10,15 +10,17 @@ module Rubirai
10
10
  # @param target_qq [Integer] target qq id
11
11
  # @param group_id [Integer] group id
12
12
  # @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain, can be any type
13
+ # @param quote [NilClass, Integer] the message id to quote, nil for not quote
13
14
  # @return [Integer] message id
14
- def send_temp_msg(target_qq, group_id, *msgs)
15
+ def send_temp_msg(target_qq, group_id, *msgs, quote: nil)
15
16
  chain = Rubirai::MessageChain.make(*msgs, bot: self)
16
17
  resp = call :post, '/sendTempMessage', json: {
17
18
  sessionKey: @session,
18
19
  qq: target_qq.to_i,
19
20
  group: group_id.to_i,
21
+ quote: quote,
20
22
  messageChain: chain.to_a
21
- }
23
+ }.compact
22
24
  resp['messageId']
23
25
  end
24
26
 
@@ -27,15 +29,17 @@ module Rubirai
27
29
  # @param type [Symbol, String] options: [group, friend]
28
30
  # @param target_id [Integer] target qq/group id
29
31
  # @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain, can be any type
32
+ # @param quote [NilClass, Integer] the message id to quote, nil for not quote
30
33
  # @return [Integer] message id
31
- def send_msg(type, target_id, *msgs)
34
+ def send_msg(type, target_id, *msgs, quote: nil)
32
35
  self.class.ensure_type_in type, 'group', 'friend'
33
36
  chain = Rubirai::MessageChain.make(*msgs, bot: self)
34
37
  resp = call :post, "/send#{type.to_s.snake_to_camel}Message", json: {
35
38
  sessionKey: @session,
36
39
  target: target_id.to_i,
40
+ quote: quote,
37
41
  messageChain: chain.to_a
38
- }
42
+ }.compact
39
43
  resp['messageId']
40
44
  end
41
45
 
@@ -43,25 +47,28 @@ module Rubirai
43
47
  #
44
48
  # @param target_qq [Integer] target qq id
45
49
  # @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain, can be any type
50
+ # @param quote [NilClass, Integer] the message id to quote, nil for not quote
46
51
  # @return [Integer] message id
47
- def send_friend_msg(target_qq, *msgs)
48
- send_msg :friend, target_qq, *msgs
52
+ def send_friend_msg(target_qq, *msgs, quote: nil)
53
+ send_msg :friend, target_qq, *msgs, quote: quote
49
54
  end
50
55
 
51
56
  # Send group message
52
57
  #
53
58
  # @param target_group_id [Integer] group id
54
59
  # @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain, can be any type
60
+ # @param quote [NilClass, Integer] the message id to quote, nil for not quote
55
61
  # @return [Integer] message id
56
- def send_group_msg(target_group_id, *msgs)
57
- send_msg :group, target_group_id, *msgs
62
+ def send_group_msg(target_group_id, *msgs, quote: nil)
63
+ send_msg :group, target_group_id, *msgs, quote: quote
58
64
  end
59
65
 
60
66
  # Recall a message
61
67
  #
62
- # @param msg_id [Integer] message id
68
+ # @param msg_id [Integer, Rubirai::MessageChain] message id
63
69
  # @return [void]
64
70
  def recall(msg_id)
71
+ msg_id = msg_id.id if msg_id.is_a? Rubirai::MessageChain
65
72
  call :post, '/recall', json: {
66
73
  sessionKey: @session,
67
74
  target: msg_id
@@ -114,34 +121,20 @@ module Rubirai
114
121
  #
115
122
  # @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain
116
123
  # @param quote [Boolean] if to quote the original message
117
- # @return [void]
124
+ # @return [Integer] message id
118
125
  def respond(*msgs, quote: false)
119
126
  check_bot
120
- msgs.prepend(gen_quote) if quote
127
+ quote_id = quote ? (@message_chain.id || nil) : nil
121
128
  case self
122
129
  when FriendMessageEvent
123
- @bot.send_friend_msg(@sender.id, *msgs)
130
+ @bot.send_friend_msg(@sender.id, *msgs, quote: quote_id)
124
131
  when GroupMessageEvent
125
- @bot.send_group_msg(@sender.group.id, *msgs)
132
+ @bot.send_group_msg(@sender.group.id, *msgs, quote: quote_id)
126
133
  when TempMessageEvent
127
- @bot.send_temp_msg(@sender.id, @sender.group.id, *msgs)
134
+ @bot.send_temp_msg(@sender.id, @sender.group.id, *msgs, quote: quote_id)
128
135
  else
129
136
  raise 'undefined error'
130
137
  end
131
- nil
132
- end
133
-
134
- # Generates a quote message from this event
135
- #
136
- # @return [QuoteMessage] the quote message
137
- def gen_quote
138
- QuoteMessage.from(
139
- id: @message_chain.id,
140
- group_id: @sender.is_a?(GroupUser) ? @sender.group.id : 0,
141
- sender_id: @sender.id,
142
- target_id: @sender.is_a?(GroupUser) ? @sender.group.id : @bot.qq,
143
- origin: @message_chain
144
- )
145
138
  end
146
139
 
147
140
  private
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubirai/utils'
4
+
5
+ module Rubirai
6
+ # @!attribute [r] has_interpolation
7
+ # @return [Boolean] if this message chain has interpolation called by {#interpolated_str}
8
+ class MessageChain
9
+ attr_reader :has_interpolation
10
+
11
+ # Convert the message chain to an interpolated string.
12
+ #
13
+ # @return [String]
14
+ def interpolated_str
15
+ return @interpolated_str if @has_interpolation
16
+ @interpolated_str = _gen_interp_str
17
+ @has_interpolation = true
18
+ @interpolated_str
19
+ end
20
+
21
+ # Get the interpolated object by given id
22
+ #
23
+ # @param obj_id [String] the object id
24
+ # @return [Message, nil] the message. `nil` if `obj_id` is malformed or not found.
25
+ def get_object(obj_id)
26
+ _get_object(obj_id)
27
+ end
28
+
29
+ # Get a new chain from interpolated string generated from the original message chain.
30
+ # The given interpolated string can be a substring of original one so that elements
31
+ # can be extracted easily.
32
+ #
33
+ # @param str [String] the interpolated string
34
+ # @return [MessageChain] the message chain constructed
35
+ def chain_from_interpolated(str)
36
+ _interpolate_with_objects(str)
37
+ end
38
+
39
+ private
40
+
41
+ OBJ_INTERP_CHAR = '%'
42
+ OBJ_INTERP_LEN = 6
43
+
44
+ def _gen_interp_str
45
+ result = +''
46
+ @messages.each do |msg|
47
+ result << case msg
48
+ when PlainMessage
49
+ _transform_plain_txt(msg.text)
50
+ else
51
+ _transform_object(msg)
52
+ end
53
+ end
54
+ result
55
+ end
56
+
57
+ def _transform_plain_txt(str)
58
+ str.gsub(OBJ_INTERP_CHAR, OBJ_INTERP_CHAR * 2)
59
+ end
60
+
61
+ def _transform_object(obj)
62
+ obj_id = Utils.random_str(OBJ_INTERP_LEN)
63
+ obj_id = Utils.random_str(OBJ_INTERP_LEN) while @ipl_objs_map.include?(obj_id)
64
+ @ipl_objs_map[obj_id] = obj
65
+ "#{OBJ_INTERP_CHAR}#{obj_id}#{OBJ_INTERP_CHAR}"
66
+ end
67
+
68
+ def _get_object(obj_id)
69
+ return nil if obj_id.length != OBJ_INTERP_LEN && obj_id.length != (OBJ_INTERP_LEN + 2)
70
+ return @ipl_objs_map[obj_id] if obj_id.length == OBJ_INTERP_LEN
71
+ return nil if obj_id[0] != OBJ_INTERP_CHAR || obj_id[-1] != OBJ_INTERP_CHAR
72
+
73
+ @ipl_objs_map[obj_id[1...-1]]
74
+ end
75
+
76
+ # @private
77
+ # @param str [String]
78
+ def _interpolate_with_objects(str)
79
+ sb = +''
80
+ result = MessageChain.new(bot)
81
+ i = 0
82
+ while i < str.length
83
+ if i == str.length - 1
84
+ sb << str[i]
85
+ break
86
+ end
87
+
88
+ if str[i] != OBJ_INTERP_CHAR
89
+ sb << str[i]
90
+ i += 1
91
+ next
92
+ end
93
+
94
+ if str[i + 1] == OBJ_INTERP_CHAR
95
+ sb << OBJ_INTERP_CHAR
96
+ i += 1
97
+ else
98
+ result.append PlainMessage.from(text: sb) unless sb.empty?
99
+ sb = str[i...i + OBJ_INTERP_LEN + 2]
100
+ obj = _get_object(sb)
101
+ i += OBJ_INTERP_LEN + 1
102
+ unless obj.nil?
103
+ result.append obj
104
+ sb = +''
105
+ end
106
+ end
107
+
108
+ i += 1
109
+ end
110
+
111
+ result.append PlainMessage.from(text: sb) unless sb.nil? || sb.empty?
112
+ result
113
+ end
114
+ end
115
+ end
@@ -2,25 +2,75 @@
2
2
 
3
3
  require 'rubirai/utils'
4
4
 
5
+ # @!method self.AtMessage(**kwargs)
6
+ # Form an {Rubirai::AtMessage}. The `display` option has no effect when
7
+ # sending at messages.
8
+ # @option kwargs [Integer] :target the target id
9
+ # @return [Rubirai::AtMessage] the message object
10
+ # @see Rubirai::AtMessage.from
11
+ # @!method self.QuoteMessage(**kwargs)
12
+ # Form a {Rubirai::QuoteMessage}.
13
+ # @return [Rubirai::QuoteMessage] the message object
14
+ # @see Rubirai::QuoteMessage.from
15
+ # @!method self.AtAllMessage()
16
+ # Form an {Rubirai::AtAllMessage}.
17
+ # @return [Rubirai::AtAllMessage] the message object
18
+ # @see Rubirai::AtAllMessage.from
19
+ # @!method self.FaceMessage(**kwargs)
20
+ # Form a {Rubirai::FaceMessage}. Only needs to give one of the two arguments.
21
+ # @option kwargs [Integer] :face_id the face id (high priority)
22
+ # @option kwargs [String] :name the face's name (low priority)
23
+ # @return [Rubirai::FaceMessage] the message object
24
+ # @see Rubirai::FaceMessage.from
25
+ # @!method self.PlainMessage(**kwargs)
26
+ # @option kwargs [String] :text the plain text
27
+ # @return [Rubirai::PlainMessage] the message object
28
+ # @see Rubirai::PlainMessage.from
29
+ # @!method self.ImageMessage(**kwargs)
30
+ # Form an {Rubirai::ImageMessage}. Only needs to give one of the three arguments.
31
+ # @option kwargs [String] :image_id the image id
32
+ # @option kwargs [String] :url the url of the image
33
+ # @option kwargs [String] :path the local path of the image
34
+ # @return [Rubirai::ImageMessage] the message object
35
+ # @see Rubirai::ImageMessage.from
36
+ # @!method self.FlashImageMessage(**kwargs)
37
+ # Form a {Rubirai::FlashImageMessage}. Only needs to give one of the three arguments.
38
+ # @option kwargs [String] :image_id the image id
39
+ # @option kwargs [String] :url the url of the image
40
+ # @option kwargs [String] :path the local path of the image
41
+ # @return [Rubirai::FlashImageMessage] the message object
42
+ # @see Rubirai::FlashImageMessage.from
43
+ # @!method self.VoiceMessage(**kwargs)
44
+ # Form a {Rubirai::VoiceMessage}. Only needs to give one of the three arguments.
45
+ # @option kwargs [String] :voice_id the voice id
46
+ # @option kwargs [String] :url the url of the voice
47
+ # @option kwargs [String] :path the local path of the voice
48
+ # @return [Rubirai::VoiceMessage] the message object
49
+ # @see Rubirai::VoiceMessage.from
50
+ # @!method self.XmlMessage(**kwargs)
51
+ # Form a {Rubirai::XmlMessage}.
52
+ # @option kwargs [String] :xml the xml body
53
+ # @return [Rubirai::XmlMessage] the message object
54
+ # @see Rubirai::XmlMessage.from
55
+ # @!method self.JsonMessage(**kwargs)
56
+ # Form a {Rubirai::JsonMessage}.
57
+ # @option kwargs [String] :json the json body
58
+ # @return [Rubirai::JsonMessage] the message object
59
+ # @see Rubirai::JsonMessage.from
60
+ # @!method self.AppMessage(**kwargs)
61
+ # Form an {Rubirai::AppMessage}.
62
+ # @option kwargs [String] :content the app body
63
+ # @return [Rubirai::AppMessage] the message object
64
+ # @see Rubirai::AppMessage.from
65
+ # @!method self.PokeMessage(**kwargs)
66
+ # Form a {Rubirai::PokeMessage}.
67
+ # @option kwargs [String] :name the poke name
68
+ # @return [Rubirai::PokeMessage] the message object
69
+ # @see Rubirai::PokeMessage.from
5
70
  module Rubirai
6
71
  # The message abstract class.
7
72
  #
8
73
  # @abstract
9
- # @!method self.AtMessage(**kwargs)
10
- # @param kwargs [Hash{Symbol => Object}] arguments
11
- # @return [Rubirai::AtMessage]
12
- # @!method self.QuoteMessage(**kwargs)
13
- # @param kwargs [Hash{Symbol => Object}] arguments
14
- # @return [Rubirai::QuoteMessage]
15
- # @!method self.AtAllMessage(**kwargs)
16
- # @param kwargs [Hash{Symbol => Object}] arguments
17
- # @return [Rubirai::AtAllMessage]
18
- # @!method self.FaceMessage(**kwargs)
19
- # @param kwargs [Hash{Symbol => Object}] arguments
20
- # @return [Rubirai::FaceMessage]
21
- # @!method self.PlainMessage(**kwargs)
22
- # @option text [String] the plain text
23
- # @return [Rubirai::PlainMessage]
24
74
  class Message
25
75
  # @!attribute [r] bot
26
76
  # @return [Bot] the bot
@@ -30,7 +80,7 @@ module Rubirai
30
80
 
31
81
  # Objects to {Rubirai::Message}
32
82
  #
33
- # @param msg [Rubirai::Message, Hash, Object] the object to transform to a message
83
+ # @param msg [Rubirai::Message, Hash{String => Object}, Object] the object to transform to a message
34
84
  # @return [Rubirai::Message] the message
35
85
  def self.to_message(msg, bot = nil)
36
86
  # noinspection RubyYardReturnMatch
@@ -150,6 +200,10 @@ module Rubirai
150
200
  end
151
201
  end
152
202
 
203
+ # {include:Rubirai::Message.to_message}
204
+ # @param obj [Message, Hash{String => Object}, Object] the object
205
+ # @return [Message] the message
206
+ # @see Rubirai::Message.to_message
153
207
  def self.Message(obj, bot = nil)
154
208
  Message.to_message obj, bot
155
209
  end
@@ -185,7 +239,9 @@ module Rubirai
185
239
  # @return [Integer] the original receiver's (group or user) id
186
240
  # @!attribute [r] origin
187
241
  # @return [MessageChain] the original message chain
188
- set_message :Quote, :id, :group_id, :sender_id, :target_id, :origin
242
+ # @!method from(**kwargs)
243
+ # Form a {QuoteMessage}.
244
+ set_message :Quote, :id, :group_id, :sender_id, :target_id, :origin, :origin_raw
189
245
 
190
246
  # @private
191
247
  def initialize(hash, bot = nil)
@@ -195,6 +251,18 @@ module Rubirai
195
251
  @sender_id = hash['senderId']
196
252
  @target_id = hash['targetId']
197
253
  @origin = MessageChain.make(*hash['origin'], bot: bot)
254
+ @origin_raw = hash['origin']
255
+ end
256
+
257
+ def to_h
258
+ {
259
+ 'type' => 'Quote',
260
+ 'id' => @id,
261
+ 'groupId' => @group_id,
262
+ 'senderId' => @sender_id,
263
+ 'targetId' => @target_id,
264
+ 'origin' => @origin_raw || @origin.to_a
265
+ }.compact
198
266
  end
199
267
  end
200
268
 
@@ -205,15 +273,16 @@ module Rubirai
205
273
  # @!attribute [r] display
206
274
  # @return [String] the displayed name (not used when sending)
207
275
  # @!method from(**kwargs)
208
- # @param kwargs [Hash{Symbol => Object}] not used
276
+ # Form an {AtMessage}. The `display` option has no effect when
277
+ # sending at messages.
278
+ # @option kwargs [Integer] :target the target id
209
279
  # @return [AtMessage] the message object
210
280
  set_message :At, :target, :display
211
281
  end
212
282
 
213
283
  # The At All message type
214
284
  class AtAllMessage < Message
215
- # @!method from(**kwargs)
216
- # @param kwargs [Hash{Symbol => Object}] the fields to set
285
+ # @!method from()
217
286
  # @return [AtAllMessage] the message object
218
287
  set_message :AtAll
219
288
  end
@@ -224,6 +293,12 @@ module Rubirai
224
293
  # @return [Integer] the face's id
225
294
  # @!attribute [r] name
226
295
  # @return [String, nil] the face's name
296
+ # @!method from(**kwargs)
297
+ # Form a {Rubirai::FaceMessage}. Only needs to give one of the two arguments.
298
+ # @option kwargs [Integer] :face_id the face id (high priority)
299
+ # @option kwargs [String] :name the face's name (low priority)
300
+ # @return [Rubirai::FaceMessage] the message object
301
+ # @!scope class
227
302
  set_message :Face, :face_id, :name
228
303
  end
229
304
 
@@ -231,6 +306,10 @@ module Rubirai
231
306
  class PlainMessage < Message
232
307
  # @!attribute [r] text
233
308
  # @return [String] the text
309
+ # @!method from(**kwargs)
310
+ # @option kwargs [String] :text the plain text
311
+ # @return [PlainMessage] the message object
312
+ # @!scope class
234
313
  set_message :Plain, :text
235
314
  end
236
315
 
@@ -238,21 +317,54 @@ module Rubirai
238
317
  # Only one out of the three fields is needed to form the message.
239
318
  class ImageMessage < Message
240
319
  # @!attribute [r] image_id
241
- # @return [Integer, nil] the image id from mirai
320
+ # @return [String, nil] the image id from mirai
242
321
  # @!attribute [r] url
243
322
  # @return [String, nil] the url of the image
244
323
  # @!attribute [r] path
245
324
  # @return [String, nil] the local path of the image
325
+ # @!method from(**kwargs)
326
+ # Form an {Rubirai::ImageMessage}. Only needs to give one of the three arguments.
327
+ # @option kwargs [String] :image_id the image id
328
+ # @option kwargs [String] :url the url of the image
329
+ # @option kwargs [String] :path the local path of the image
330
+ # @return [Rubirai::ImageMessage] the message object
331
+ # @!scope class
246
332
  set_message :Image, :image_id, :url, :path
247
333
  end
248
334
 
249
335
  # The flash image message type
250
336
  class FlashImageMessage < Message
337
+ # @!attribute [r] image_id
338
+ # @return [String, nil] the image id from mirai
339
+ # @!attribute [r] url
340
+ # @return [String, nil] the url of the image
341
+ # @!attribute [r] path
342
+ # @return [String, nil] the local path of the image
343
+ # @!method from(**kwargs)
344
+ # Form a {Rubirai::FlashImageMessage}. Only needs to give one of the three arguments.
345
+ # @option kwargs [String] :image_id the image id
346
+ # @option kwargs [String] :url the url of the image
347
+ # @option kwargs [String] :path the local path of the image
348
+ # @return [Rubirai::FlashImageMessage] the message object
349
+ # @!scope class
251
350
  set_message :FlashImage, :image_id, :url, :path
252
351
  end
253
352
 
254
353
  # The voice message type
255
354
  class VoiceMessage < Message
355
+ # @!attribute [r] voice_id
356
+ # @return [String, nil] the voice id from mirai
357
+ # @!attribute [r] url
358
+ # @return [String, nil] the url of the voice
359
+ # @!attribute [r] path
360
+ # @return [String, nil] the local path of the voice
361
+ # @!method from(**kwargs)
362
+ # Form a {Rubirai::VoiceMessage}. Only needs to give one of the three arguments.
363
+ # @option kwargs [String] :voice_id the voice id
364
+ # @option kwargs [String] :url the url of the voice
365
+ # @option kwargs [String] :path the local path of the voice
366
+ # @return [Rubirai::VoiceMessage] the message object
367
+ # @!scope class
256
368
  set_message :Voice, :voice_id, :url, :path
257
369
  end
258
370
 
@@ -260,6 +372,11 @@ module Rubirai
260
372
  class XmlMessage < Message
261
373
  # @!attribute [r] xml
262
374
  # @return [String] the xml content
375
+ # @!method from(**kwargs)
376
+ # Form a {Rubirai::XmlMessage}.
377
+ # @option kwargs [String] :xml the xml body
378
+ # @return [Rubirai::XmlMessage] the message object
379
+ # @!scope class
263
380
  set_message :Xml, :xml
264
381
  end
265
382
 
@@ -267,6 +384,11 @@ module Rubirai
267
384
  class JsonMessage < Message
268
385
  # @!attribute [r] json
269
386
  # @return [String] the json content
387
+ # @!method from(**kwargs)
388
+ # Form a {Rubirai::JsonMessage}.
389
+ # @option kwargs [String] :json the json body
390
+ # @return [Rubirai::JsonMessage] the message object
391
+ # @!scope class
270
392
  set_message :Json, :json
271
393
  end
272
394
 
@@ -274,27 +396,72 @@ module Rubirai
274
396
  class AppMessage < Message
275
397
  # @!attribute [r] content
276
398
  # @return [String] the app content
399
+ # @!method from(**kwargs)
400
+ # Form an {Rubirai::AppMessage}.
401
+ # @option kwargs [String] :content the app body
402
+ # @return [Rubirai::AppMessage] the message object
403
+ # @!scope class
277
404
  set_message :App, :content
278
405
  end
279
406
 
407
+ # The poke message type
280
408
  class PokeMessage < Message
409
+ # @!attribute [r] name
410
+ # @return [String] type (name) of the poke
411
+ # @!method from(**kwargs)
412
+ # Form an {Rubirai::PokeMessage}.
413
+ # @option kwargs [String] :name the name (type) of poke
414
+ # @return [Rubirai::PokeMessage] the message object
415
+ # @!scope class
281
416
  set_message :Poke, :name
282
417
  end
283
418
 
419
+ # The forward message type
284
420
  class ForwardMessage < Message
421
+ # A message node in the forward message list
422
+ #
423
+ # @!attribute [r] sender_id
424
+ # @return [Integer] sender id
425
+ # @!attribute [r] time
426
+ # @return [Integer] send timestamp (second)
427
+ # @!attribute [r] sender_name
428
+ # @return [String] the sender name
429
+ # @!attribute [r] message_chain
430
+ # @return [MessageChain] the message chain
285
431
  class Node
286
432
  attr_reader :sender_id, :time, :sender_name, :message_chain
287
433
 
434
+ # @private
288
435
  def initialize(hash, bot = nil)
436
+ return unless hash
289
437
  @sender_id = hash['senderId']
290
438
  @time = hash['time']
291
439
  @sender_name = hash['senderName']
292
440
  @message_chain = MessageChain.make(*hash['messageChain'], bot: bot)
293
441
  end
442
+
443
+ def self.from(**kwargs)
444
+ n = new({})
445
+ %i[sender_id time sender_name message_chain].each do |attr|
446
+ n.instance_variable_set("@#{attr}", kwargs[attr])
447
+ end
448
+ end
294
449
  end
295
450
 
451
+ # @!attribute [r] title
452
+ # @return [String] the title
453
+ # @!attribute [r] brief
454
+ # @return [String] the brief text
455
+ # @!attribute [r] source
456
+ # @return [String] the source text
457
+ # @!attribute [r] summary
458
+ # @return [String] the summary text
459
+ # @!attribute [r] node_list
460
+ # @return [Array<Node>] the node list
461
+ # @see Node
296
462
  set_message :Forward, :title, :brief, :source, :summary, :node_list
297
463
 
464
+ # @private
298
465
  def initialize(hash, bot = nil)
299
466
  super :Forward, bot
300
467
  @title = hash['title']
@@ -307,15 +474,42 @@ module Rubirai
307
474
  end
308
475
  end
309
476
 
477
+ # The file message type
310
478
  class FileMessage < Message
479
+ # @!attribute [r] id
480
+ # @return [String] the file id
481
+ # @!attribute [r] internal_id
482
+ # @return [Integer] the internal id needed by server
483
+ # @!attribute [r] name
484
+ # @return [String] the filename
485
+ # @!attribute [r] size
486
+ # @return [Integer] the file size
311
487
  set_message :File, :id, :internal_id, :name, :size
312
488
  end
313
489
 
490
+ # The music share card message
314
491
  class MusicShareMessage < Message
492
+ # List all kinds of music providers
493
+ #
494
+ # @return [Array<String>] kinds
315
495
  def self.all_kinds
316
496
  %w[NeteaseCloudMusic QQMusic MiguMusic]
317
497
  end
318
498
 
499
+ # @!attribute [r] kind
500
+ # @return [String] the kind of music provider
501
+ # @!attribute [r] title
502
+ # @return [String] the music card title
503
+ # @!attribute [r] summary
504
+ # @return [String] the music card summary
505
+ # @!attribute [r] jump_url
506
+ # @return [String] the jump url
507
+ # @!attribute [r] picture_url
508
+ # @return [String] the picture's url
509
+ # @!attribute [r] music_url
510
+ # @return [String] the music's url
511
+ # @!attribute [r] brief
512
+ # @return [String, nil] the brief message (optional)
319
513
  set_message :MusicShare, :kind, :title, :summary, :jump_url, :picture_url, :music_url, :brief do |hash|
320
514
  raise(RubiraiError, 'non valid music type') unless all_kinds.include? hash['kind']
321
515
  end
@@ -5,18 +5,21 @@ require 'rubirai/messages/message'
5
5
 
6
6
  module Rubirai
7
7
  # Message chain
8
+ #
9
+ # @!attribute [r] bot
10
+ # @return [Bot] the bot object
11
+ # @!attribute [r] id
12
+ # @return [Integer, nil] the message id, may be `nil`
13
+ # @!attribute [r] raw
14
+ # @return [Hash{String => Object}, nil] the raw message chain, may be `nil`
15
+ # @!attribute [r] send_time
16
+ # @return [Integer, nil] the send time of the message chain, may be `nil`
17
+ # @!attribute [r] messages
18
+ # @return [Array<Message>] the raw message array
8
19
  class MessageChain
9
20
  include Enumerable
10
21
 
11
- # @!attribute [r] bot
12
- # @return [Bot] the bot object
13
- # @!attribute [r] id
14
- # @return [Integer, nil] the message id, may be `nil`
15
- # @!attribute [r] send_time
16
- # @return [Integer, nil] the send time of the message chain, may be `nil`
17
- # @!attribute [r] messages
18
- # @return [Array<Message>] the raw message array
19
- attr_reader :bot, :id, :send_time, :messages
22
+ attr_reader :bot, :id, :raw, :send_time, :messages
20
23
 
21
24
  # Makes a message chain from a list of messages
22
25
  #
@@ -87,10 +90,13 @@ module Rubirai
87
90
  # @private
88
91
  # @param bot [Rubirai::Bot, nil]
89
92
  # @param source [Array, nil]
90
- # @param id [Integer, nil]
91
93
  def initialize(bot = nil, source = nil)
92
94
  @bot = bot
93
95
  @messages = []
96
+ @has_interpolation = false
97
+ @interpolated_str = nil
98
+ @ipl_objs_map = {}
99
+ @raw = source
94
100
  return unless source
95
101
  raise(MiraiError, 'source is not array') unless source.is_a? Array
96
102
  raise(MiraiError, 'length is zero') if source.empty?
@@ -130,7 +136,12 @@ module Rubirai
130
136
  end
131
137
 
132
138
  # Makes a message chain. See {MessageChain#make}.
139
+ #
140
+ # @return [MessageChain] the message chain made.
141
+ # @see MessageChain#make
133
142
  def self.MessageChain(*messages, bot: nil)
134
143
  MessageChain.make(*messages, bot: bot)
135
144
  end
136
145
  end
146
+
147
+ require 'rubirai/messages/interpolation'
@@ -5,6 +5,11 @@ require 'rubirai/utils'
5
5
  module Rubirai
6
6
  # The abstract class for group information
7
7
  # @abstract
8
+ #
9
+ # @!attribute [r] raw
10
+ # @return [Hash{String => Object}] the raw hash
11
+ # @!attribute [r] bot
12
+ # @return [Bot] the bot
8
13
  class GroupInfo
9
14
  # @private
10
15
  def self.set_fields(*fields, **default_values)
@@ -34,10 +39,6 @@ module Rubirai
34
39
  attr_writer(*fields)
35
40
  end
36
41
 
37
- # @!attribute [r] raw
38
- # @return [Hash{String => Object}] the raw hash
39
- # @!attribute [r] bot
40
- # @return [Bot] the bot
41
42
  attr_reader :raw, :bot
42
43
 
43
44
  # @private
data/lib/rubirai/utils.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'securerandom'
4
+
3
5
  # @private
4
6
  class Hash
5
7
  def stringify_keys!
@@ -60,3 +62,11 @@ class Object
60
62
  end
61
63
  end
62
64
  end
65
+
66
+ module Rubirai
67
+ module Utils
68
+ def self.random_str(len)
69
+ SecureRandom.alphanumeric len
70
+ end
71
+ end
72
+ end
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Rubirai
4
4
  # Rubirai version
5
- VERSION = '0.0.3-a1'
5
+ VERSION = '0.2.0'
6
6
 
7
7
  # mirai-api-http version
8
- MIRAI_API_VERSION = '1.10.0'
8
+ MIRAI_API_VERSION = '2.5.0'
9
9
  end
data/lib/rubirai.rb CHANGED
@@ -1,3 +1,11 @@
1
+ # Copyright 2021 Rebuild.
2
+ #
3
+ # 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
4
+ # Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
5
+ #
6
+ # https://github.com/Shimogawa/rubirai/blob/master/LICENSE
7
+ #
8
+
1
9
  # frozen_string_literal: true
2
10
 
3
11
  require 'rubirai/errors'
@@ -8,13 +16,14 @@ module Rubirai
8
16
  require 'http'
9
17
 
10
18
  # Bot represents a QQ bot at mirai side. All functions are API calls to the http plugin.
19
+ #
20
+ # @!attribute [r] base_uri
21
+ # @return [String] the base uri of mirai-api-http which the bot will send messages to
22
+ # @!attribute [r] session
23
+ # @return [String] the session key
24
+ # @!attribute [r] qq
25
+ # @return [String, Integer] the qq of the bot
11
26
  class Bot
12
- # @!attribute [r] base_uri
13
- # @return [String] the base uri of mirai-api-http which the bot will send messages to
14
- # @!attribute [r] session
15
- # @return [String] the session key
16
- # @!attribute [r] qq
17
- # @return [String, Integer] the qq of the bot
18
27
  attr_reader :base_uri, :session, :qq
19
28
 
20
29
  alias id qq
@@ -28,10 +37,12 @@ module Rubirai
28
37
  @listener_funcs = []
29
38
  end
30
39
 
40
+ # @private
31
41
  def gen_uri(path)
32
42
  URI.join(base_uri, path)
33
43
  end
34
44
 
45
+ # @private
35
46
  def self.ensure_type_in(type, *types)
36
47
  types = types.map { |x| x.to_s.downcase }
37
48
  type.to_s.downcase.must_be_one_of! types, RubiraiError, "not valid type: should be one of #{types}"
@@ -47,7 +58,7 @@ module Rubirai
47
58
 
48
59
  body = JSON.parse(resp.body)
49
60
  if (body.is_a? Hash) && (body.include? 'code') && (body['code'] != 0)
50
- raise MiraiError.new(body['code'], body['msg'] || body['errorMessage'])
61
+ raise MiraiError.new(body['code'], body['msg'])
51
62
  end
52
63
 
53
64
  body
data/spec/auth_spec.rb CHANGED
@@ -12,38 +12,38 @@ describe 'auth api' do
12
12
  end
13
13
 
14
14
  it 'should be able to authenticate' do
15
- stub_request(:post, @mirai_bot.gen_uri('/auth'))
15
+ stub_request(:post, @mirai_bot.gen_uri('/verify'))
16
16
  .with(body: {
17
- "authKey": @auth_key
17
+ "verifyKey": @verify_key
18
18
  })
19
19
  .to_return(status: 200, body: %({
20
20
  "code": 0,
21
21
  "session": "#{@session_key}"
22
22
  }))
23
- res = @mirai_bot.auth @auth_key
23
+ res = @mirai_bot.verify @verify_key
24
24
  expect(res).to be_a_kind_of(String)
25
25
  expect(res).to eq(@session_key)
26
26
  end
27
27
 
28
28
  it 'should raise error if authenticate fails' do
29
29
  mirai_bot = new_bot
30
- stub_request(:post, @mirai_bot.gen_uri('/auth'))
30
+ stub_request(:post, @mirai_bot.gen_uri('/verify'))
31
31
  .with(body: {
32
- "authKey": @auth_key
32
+ "verifyKey": @verify_key
33
33
  })
34
34
  .to_return(status: 200, body: %({
35
35
  "code": 1,
36
36
  "session": ""
37
37
  }))
38
38
 
39
- expect { mirai_bot.auth @auth_key }.to raise_error(
39
+ expect { mirai_bot.verify @verify_key }.to raise_error(
40
40
  Rubirai::MiraiError,
41
41
  'Mirai error: 1 - Wrong auth key'
42
42
  )
43
43
  end
44
44
 
45
45
  it 'should be able to verify' do
46
- stub_request(:post, @mirai_bot.gen_uri('/verify'))
46
+ stub_request(:post, @mirai_bot.gen_uri('/bind'))
47
47
  .with(body: {
48
48
  "sessionKey": @session_key,
49
49
  "qq": @qq
@@ -53,11 +53,11 @@ describe 'auth api' do
53
53
  "session": "success"
54
54
  }))
55
55
 
56
- expect { @mirai_bot.verify @qq }.not_to raise_error
57
- expect(@mirai_bot.verify(@qq)).to be_nil
56
+ expect { @mirai_bot.bind @qq }.not_to raise_error
57
+ expect(@mirai_bot.bind(@qq)).to be_nil
58
58
 
59
- expect { @mirai_bot.verify '1ab39cde' }.to raise_error(Rubirai::RubiraiError, 'Wrong format for qq')
60
- expect { new_bot.verify @qq }.to raise_error(Rubirai::RubiraiError, 'No session provided')
59
+ expect { @mirai_bot.bind '1ab39cde' }.to raise_error(Rubirai::RubiraiError, 'Wrong format for qq')
60
+ expect { new_bot.bind @qq }.to raise_error(Rubirai::RubiraiError, 'No session provided')
61
61
  end
62
62
 
63
63
  it 'should be able to release' do
@@ -90,7 +90,7 @@ describe 'auth api' do
90
90
  "msg": "success"
91
91
  }))
92
92
  expect do
93
- expect(mirai_bot.login(@qq, @auth_key)).to be_nil
93
+ expect(mirai_bot.login(@qq, @verify_key)).to be_nil
94
94
  end.not_to raise_error
95
95
  expect(mirai_bot.instance_variable_get('@session')).to eq(@session_key)
96
96
 
@@ -76,6 +76,7 @@ describe Rubirai::Event do
76
76
  expect(e.class.type).to eq(:BotGroupPermissionChangeEvent)
77
77
  expect(e.origin).to eq(Rubirai::Group::Permission::MEMBER)
78
78
  expect(e.new).to eq(Rubirai::Group::Permission::ADMINISTRATOR)
79
+ expect(e.group).to be_a(Rubirai::Group)
79
80
  expect(e.group.id).to eq(123456789)
80
81
  end
81
82
  end
data/spec/message_spec.rb CHANGED
@@ -6,7 +6,7 @@ describe 'message api' do
6
6
  before :all do
7
7
  @mirai_bot = new_bot
8
8
  stub_login
9
- @mirai_bot.login @qq, @auth_key
9
+ @mirai_bot.login @qq, @verify_key
10
10
  end
11
11
 
12
12
  after do
@@ -84,4 +84,48 @@ describe 'message api' do
84
84
  expect(@mirai_bot.recall(123)).to be_nil
85
85
  end.not_to raise_error
86
86
  end
87
+
88
+ it 'should be able to respond to a message event' do
89
+ e = Rubirai::Event.parse({
90
+ "type": 'GroupMessage',
91
+ "messageChain": [
92
+ {
93
+ "type": 'Source',
94
+ "id": 123456,
95
+ "time": 123456789
96
+ }.stringify_keys,
97
+ {
98
+ "type": 'Plain',
99
+ "text": 'Miral牛逼'
100
+ }.stringify_keys
101
+ ],
102
+ "sender": {
103
+ "id": 123456789,
104
+ "memberName": '化腾',
105
+ "permission": 'MEMBER',
106
+ "group": {
107
+ "id": 1234567890,
108
+ "name": 'Miral Technology',
109
+ "permission": 'MEMBER'
110
+ }.stringify_keys
111
+ }.stringify_keys
112
+ }.stringify_keys, @mirai_bot)
113
+ stub_request(:post, @mirai_bot.gen_uri('/sendGroupMessage'))
114
+ .with(body: {
115
+ "sessionKey": 'test_session_key',
116
+ "target": 1234567890,
117
+ "quote": 123456,
118
+ "messageChain": [
119
+ { "text": 'hi', "type": 'Plain' }
120
+ ]
121
+ })
122
+ .to_return(status: 200, body: %({
123
+ "code": 0,
124
+ "msg": "success",
125
+ "messageId": 1234567890
126
+ }))
127
+ expect(e).to be_a(Rubirai::GroupMessageEvent)
128
+ msg_id = e.respond 'hi', quote: true
129
+ expect(msg_id).to eq(1234567890)
130
+ end
87
131
  end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Rubirai::MessageChain do
4
+ before do
5
+ hash = {
6
+ "type": 'Quote',
7
+ "id": 123456,
8
+ "groupId": 123456789,
9
+ "senderId": 987654321,
10
+ "targetId": 9876543210,
11
+ "origin": [
12
+ { "type": 'Plain', text: 'text' }.stringify_keys
13
+ ]
14
+ }.stringify_keys
15
+ @obj = Rubirai::AtMessage.from(target: 114514)
16
+ @chain = Rubirai::MessageChain.make(
17
+ 'hi%', 2, @obj, 3, 'great %%,', :good, hash
18
+ )
19
+ @expect_pattern = /^hi%%2%[a-zA-Z0-9]{6}%3great %%%%,good%[a-zA-Z0-9]{6}%$/
20
+ end
21
+
22
+ after do
23
+ end
24
+
25
+ it 'should convert message chains to strings correctly' do
26
+ expect(@chain.has_interpolation).to be_falsey
27
+
28
+ str = @chain.interpolated_str
29
+ expect(@chain.has_interpolation).to be_truthy
30
+ objs_map = @chain.instance_variable_get('@ipl_objs_map')
31
+ expect(objs_map.length).to be(2)
32
+ objs_map.each_key do |k|
33
+ expect(str.include?(k)).to be_truthy
34
+ end
35
+ expect(@expect_pattern.match?(str)).to be_truthy
36
+ expect(@chain.interpolated_str).to eq(str)
37
+ end
38
+
39
+ it 'should get back the original object' do
40
+ str = @chain.interpolated_str
41
+ idx = 5
42
+ obj = @chain.get_object(str[idx...idx + 8])
43
+ expect(obj).to eq(@obj)
44
+ obj = @chain.get_object(str[idx + 1...idx + 7])
45
+ expect(obj).to eq(@obj)
46
+ expect(@chain.get_object(str[idx + 2...idx + 8])).to be_nil
47
+ end
48
+
49
+ it 'should construct new message chain for interpolated strings' do
50
+ str = @chain.interpolated_str[5...5 + 8 + 3]
51
+ chain = @chain.chain_from_interpolated(str)
52
+ expect(chain.length).to eq(2)
53
+ expect(chain[0]).to eq(@obj)
54
+ expect(chain[1]).to be_a(Rubirai::PlainMessage)
55
+ expect(chain[1].text).to eq('3gr')
56
+
57
+ chain = @chain.chain_from_interpolated(@chain.interpolated_str)
58
+ expect(chain.length).to eq(@chain.length)
59
+ expect(chain[0].text).to eq('hi%2')
60
+ expect(chain[1]).to eq(@obj)
61
+ expect(chain[2].text).to eq('3great %%,good')
62
+ expect(chain[3]).to be_a(Rubirai::QuoteMessage)
63
+ end
64
+ end
data/spec/spec_helper.rb CHANGED
@@ -24,22 +24,22 @@ WebMock.disable_net_connect!(allow_localhost: false)
24
24
 
25
25
  RSpec.configure do |config|
26
26
  config.before :all do
27
- @auth_key = 'test_auth_key'
27
+ @verify_key = 'test_verify_key'
28
28
  @session_key = 'test_session_key'
29
29
  @qq = 1145141919
30
30
  end
31
31
  end
32
32
 
33
33
  def stub_login
34
- stub_request(:post, @mirai_bot.gen_uri('/auth'))
34
+ stub_request(:post, @mirai_bot.gen_uri('/verify'))
35
35
  .with(body: {
36
- "authKey": @auth_key
36
+ "verifyKey": @verify_key
37
37
  })
38
38
  .to_return(status: 200, body: %({
39
39
  "code": 0,
40
40
  "session": "#{@session_key}"
41
41
  }))
42
- stub_request(:post, @mirai_bot.gen_uri('/verify'))
42
+ stub_request(:post, @mirai_bot.gen_uri('/bind'))
43
43
  .with(body: {
44
44
  "sessionKey": @session_key,
45
45
  "qq": @qq
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubirai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3.pre.a1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rebuild
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-30 00:00:00.000000000 Z
11
+ date: 2022-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -73,6 +73,7 @@ files:
73
73
  - lib/rubirai/listing.rb
74
74
  - lib/rubirai/management.rb
75
75
  - lib/rubirai/message.rb
76
+ - lib/rubirai/messages/interpolation.rb
76
77
  - lib/rubirai/messages/message.rb
77
78
  - lib/rubirai/messages/message_chain.rb
78
79
  - lib/rubirai/multipart.rb
@@ -90,6 +91,7 @@ files:
90
91
  - spec/error_spec.rb
91
92
  - spec/events/event_spec.rb
92
93
  - spec/message_spec.rb
94
+ - spec/messages/interpolation_spec.rb
93
95
  - spec/messages/message_chain_spec.rb
94
96
  - spec/messages/message_spec.rb
95
97
  - spec/plugin_info_spec.rb
@@ -111,9 +113,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
113
  version: '2.6'
112
114
  required_rubygems_version: !ruby/object:Gem::Requirement
113
115
  requirements:
114
- - - ">"
116
+ - - ">="
115
117
  - !ruby/object:Gem::Version
116
- version: 1.3.1
118
+ version: '0'
117
119
  requirements: []
118
120
  rubygems_version: 3.0.3.1
119
121
  signing_key: