rubirai 0.0.2 → 0.0.3.pre.a1

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: c1e4f114e6246e5449ef45b0ffe65436287a13fb213675a831df0139e710f931
4
- data.tar.gz: f65b3a647129a20ca95ac94536a9ac25c750f26afe0ccf1fbf690da0255b0c81
3
+ metadata.gz: 9af7ce359d2d64f6e7f1228870a74558fc3004b6b5f23257b951c13893ca4599
4
+ data.tar.gz: 421a1ecaa61dd1049501873197b01b22fe78bbdc7ef8c38766f20582ee598125
5
5
  SHA512:
6
- metadata.gz: 98fee9c38a3ff90729799a97bd095dbe78f15fd96113528e151d23ef3ee1b6803c4225fd47104863b89d7a8b49d82c6a79af7720fc6ae2a9cb0dc15b2b24a3e3
7
- data.tar.gz: ecca01ed496c19207979bb056aec2b3dc5f70e775156fb11108025c58adf560cdffec58a5075b53ec546c891bdd609f763e5c7e0f48a9bfb7c68a39f6f764f49
6
+ metadata.gz: ae1ada8f42c7d9c8df3422262782b2c2a5ee16a8611d104ccd53d78c156430d8e88e9d8bff1283b05bca3c7faf530ab8af71e3ea1cdf81dbfab9b296838bbbc5
7
+ data.tar.gz: 9621c881cd3812da59a2c1371c5ed56d87bd8971c6c472c056ce05b1159a37333f1d3701a0b3fe287278fe9e33b5de357baa7f8df4c7bbea554ab93a4c035224
@@ -32,33 +32,3 @@ jobs:
32
32
  CI: "true"
33
33
  CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
34
34
  run: bundle exec rake
35
- publish:
36
- runs-on: ubuntu-latest
37
- steps:
38
- - uses: actions/checkout@v2
39
- - name: Set up Ruby 2.6
40
- uses: actions/setup-ruby@v1
41
- with:
42
- ruby-version: 2.6.x
43
- - name: Publish to GPR
44
- run: |
45
- mkdir -p $HOME/.gem
46
- touch $HOME/.gem/credentials
47
- chmod 0600 $HOME/.gem/credentials
48
- printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
49
- gem build *.gemspec
50
- gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
51
- env:
52
- GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
53
- OWNER: ${{ github.repository_owner }}
54
-
55
- - name: Publish to RubyGems
56
- run: |
57
- mkdir -p $HOME/.gem
58
- touch $HOME/.gem/credentials
59
- chmod 0600 $HOME/.gem/credentials
60
- printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
61
- gem build *.gemspec
62
- gem push *.gem
63
- env:
64
- GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
@@ -0,0 +1,39 @@
1
+ name: Package
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ publish:
10
+ if: github.event.base_ref == 'refs/heads/master'
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+ - name: Set up Ruby 2.6
15
+ uses: actions/setup-ruby@v1
16
+ with:
17
+ ruby-version: 2.6.x
18
+ - name: Publish to GPR
19
+ run: |
20
+ mkdir -p $HOME/.gem
21
+ touch $HOME/.gem/credentials
22
+ chmod 0600 $HOME/.gem/credentials
23
+ printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
24
+ gem build *.gemspec
25
+ gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
26
+ env:
27
+ GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
28
+ OWNER: ${{ github.repository_owner }}
29
+
30
+ - name: Publish to RubyGems
31
+ run: |
32
+ mkdir -p $HOME/.gem
33
+ touch $HOME/.gem/credentials
34
+ chmod 0600 $HOME/.gem/credentials
35
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
36
+ gem build *.gemspec
37
+ gem push *.gem
38
+ env:
39
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
data/.rubocop.yml CHANGED
@@ -39,3 +39,6 @@ Metrics/PerceivedComplexity:
39
39
 
40
40
  Naming/AccessorMethodName:
41
41
  Enabled: false
42
+
43
+ Style/AsciiComments:
44
+ Enabled: false
data/README.md CHANGED
@@ -1,15 +1,26 @@
1
1
  # Rubirai
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/rubirai.svg)](https://rubygems.org/gems/rubirai)
2
4
  [![CI](https://github.com/Shimogawa/rubirai/actions/workflows/CI.yml/badge.svg?branch=master)](https://github.com/Shimogawa/rubirai/actions/workflows/CI.yml)
3
5
  [![codecov](https://codecov.io/gh/Shimogawa/rubirai/branch/master/graph/badge.svg?token=OVUVEWFPKY)](https://codecov.io/gh/Shimogawa/rubirai)
4
6
  [![Maintainability](https://api.codeclimate.com/v1/badges/9a9d8c887e5deb601e1e/maintainability)](https://codeclimate.com/github/Shimogawa/rubirai/maintainability)
5
7
  [![Inline docs](http://inch-ci.org/github/shimogawa/rubirai.svg?branch=master)](http://inch-ci.org/github/shimogawa/rubirai)
6
8
  [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FShimogawa%2Frubirai.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FShimogawa%2Frubirai?ref=badge_shield)
7
9
 
8
-
9
10
  A light-weight Mirai QQ bot http interface lib for Ruby.
10
11
 
12
+ [中文][wiki] | [Rubydocs][rubydocs]
13
+
11
14
  ## Usage
12
15
 
16
+ First, download the package using `gem`. In your `Gemfile`, add
17
+
18
+ ```ruby
19
+ gem 'rubirai'
20
+ ```
21
+
22
+ Then, start to write code (no matter if it's a rails application or something else):
23
+
13
24
  ```ruby
14
25
  require 'rubirai'
15
26
  # assuming your mirai http api address and port
@@ -17,8 +28,35 @@ require 'rubirai'
17
28
  bot = Rubirai::Bot.new('127.0.0.1', '8080')
18
29
  # qq and auth key
19
30
  bot.login 1145141919, 'ikisugi_key'
31
+
32
+ # Add a listener function
33
+ bot.add_listener do |event|
34
+ puts event.inspect
35
+ if event.is_a?(Rubirai::MessageEvent)
36
+ event.respond("Hello, world!")
37
+ end
38
+ end
39
+
40
+ # Listen to message every 0.5 seconds
41
+ # And blocks the current thread
42
+ bot.start_listen 0.5, is_blocking: true
43
+ ```
44
+
45
+ > If you want to install globally with `gem`, use
46
+
47
+ ```bash
48
+ gem install rubirai
20
49
  ```
21
50
 
51
+ ## Wiki and Documentation
52
+
53
+ - [中文 Wiki][wiki]
54
+ - [Docs][rubydocs]
55
+
22
56
 
23
57
  ## License
24
- [![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)
58
+ [![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
+
60
+
61
+ [wiki]: https://github.com/Shimogawa/rubirai/wiki
62
+ [rubydocs]: https://www.rebuild.moe/rubirai/
data/lib/rubirai.rb CHANGED
@@ -17,6 +17,8 @@ module Rubirai
17
17
  # @return [String, Integer] the qq of the bot
18
18
  attr_reader :base_uri, :session, :qq
19
19
 
20
+ alias id qq
21
+
20
22
  # Initializes the bot
21
23
  #
22
24
  # @param host [String] the host (IP or domain)
@@ -19,17 +19,29 @@ module Rubirai
19
19
  # Operations for responding to group join requests.
20
20
  # Only use the values defined in this module to respond to group join requests.
21
21
  module JoinGroupRequestOperation
22
+ # Approve the request
22
23
  APPROVE = 0
24
+
25
+ # Deny the request
23
26
  DENY = 1
27
+
28
+ # Ignore the request
24
29
  IGNORE = 2
30
+
31
+ # Deny and blacklist the sender of the request
25
32
  DENY_AND_BLACKLIST = 3
33
+
34
+ # Ignore and blacklist the sender of the request
26
35
  IGNORE_AND_BLACKLIST = 4
27
36
  end
28
37
 
29
38
  # Operations for responding to group invite requests.
30
39
  # Only use the values defined in this module to respond to group invite requests.
31
40
  module GroupInviteRequestOperation
41
+ # Approve the request
32
42
  APPROVE = 0
43
+
44
+ # Deny the request
33
45
  DENY = 1
34
46
  end
35
47
 
@@ -74,6 +86,14 @@ module Rubirai
74
86
  nil
75
87
  end
76
88
 
89
+ # Respond to group invitations (raw)
90
+ #
91
+ # @param event_id [Integer] the event id
92
+ # @param from_id [Integer] id of the sender
93
+ # @param group_id [Integer] the group id
94
+ # @param operation [Integer] see {GroupInviteRequestOperation}
95
+ # @param message [String] the message to reply
96
+ # @return [void]
77
97
  def respond_to_group_invite(event_id, from_id, group_id, operation, message = '')
78
98
  call :post, '/resp/botInvitedJoinGroupRequestEvent', json: {
79
99
  sessionKey: @session,
@@ -3,7 +3,11 @@
3
3
  require 'rubirai/events/event'
4
4
 
5
5
  module Rubirai
6
+ # Bot event
7
+ # @abstract
6
8
  class BotEvent < Event
9
+ # @!attribute [r] qq
10
+ # @return [Integer] qq id of the event's bot
7
11
  set_event nil, :qq
8
12
  end
9
13
 
@@ -102,6 +102,7 @@ module Rubirai
102
102
  # @return [Hash]
103
103
  attr_reader :bot, :raw
104
104
 
105
+ # @private
105
106
  def initialize(hash, bot = nil)
106
107
  @raw = hash
107
108
  @bot = bot
@@ -8,6 +8,8 @@ module Rubirai
8
8
  class MessageEvent < Event
9
9
  # @!attribute [r] message_chain
10
10
  # @return [MessageChain] the message chain
11
+ # @!attribute [r] sender
12
+ # @return [User] the sender
11
13
  set_event nil, :message_chain, :sender
12
14
  end
13
15
 
@@ -3,6 +3,8 @@
3
3
  require 'rubirai/events/event'
4
4
 
5
5
  module Rubirai
6
+ # Request events
7
+ # @abstract
6
8
  class RequestEvent < Event
7
9
  # @!attribute [r] event_id
8
10
  # @return [Integer] the event id
@@ -17,16 +19,19 @@ module Rubirai
17
19
  set_event nil, :event_id, :from_id, :group_id, :nick, :message
18
20
  end
19
21
 
22
+ # New friend request event
20
23
  class NewFriendRequestEvent < RequestEvent
21
24
  set_event :NewFriendRequestEvent
22
25
  end
23
26
 
27
+ # Join group request event
24
28
  class JoinGroupRequestEvent < RequestEvent
25
29
  # @!attribute [r] group_name
26
30
  # @return [String] the group name
27
31
  set_event :MemberJoinRequestEvent, :group_name
28
32
  end
29
33
 
34
+ # Event that the bot is invited to a group
30
35
  class BotInvitedToGroupEvent < RequestEvent
31
36
  # @!attribute [r] group_name
32
37
  # @return [String] the group name
@@ -3,7 +3,10 @@
3
3
  require 'rubirai/events/event'
4
4
 
5
5
  module Rubirai
6
+ # Error events thrown when errors happened in event listeners
6
7
  class RubiraiErrorEvent < Event
8
+ # @!attribute [r] err
9
+ # @return [RuntimeError] the error
7
10
  attr_reader :err
8
11
 
9
12
  # An error event just for internal use
@@ -5,6 +5,12 @@ require 'rubirai/events/rubirai_events'
5
5
 
6
6
  module Rubirai
7
7
  class Bot
8
+ # Start to listen for events
9
+ #
10
+ # @param interval [Numeric] the interval to fetch events in seconds.
11
+ # @param is_blocking [Boolean] if the listen thread should block the current thread
12
+ # @param ignore_error [Boolean] if errors should generate error events (see {RubiraiErrorEvent})
13
+ # @return [void]
8
14
  def start_listen(interval, is_blocking: false, ignore_error: false)
9
15
  raise RubiraiError, 'listener is already running' if @listener&.running?
10
16
  @listener_stop_event = Concurrent::Event.new if is_blocking
@@ -27,14 +33,24 @@ module Rubirai
27
33
  @listener_stop_event.wait if is_blocking
28
34
  end
29
35
 
36
+ # Add a listener
37
+ #
38
+ # @return [void]
30
39
  def add_listener(&listener_block)
31
40
  @listener_funcs << listener_block
32
41
  end
33
42
 
43
+ # Clear all listeners
44
+ #
45
+ # @return [void]
34
46
  def clear_listener
35
47
  @listener_funcs.clear
36
48
  end
37
49
 
50
+ # Stop listening to events. Will unblock the thread if
51
+ # `is_blocking` is `true` when calling {#start_listen}
52
+ #
53
+ # @return [void]
38
54
  def stop_listen
39
55
  @listener.shutdown
40
56
  @listener_stop_event&.set
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rubirai/objects/info'
3
+ require 'rubirai/objects/group_info'
4
4
 
5
5
  module Rubirai
6
6
  class Bot
@@ -62,7 +62,7 @@ module Rubirai
62
62
  nil
63
63
  end
64
64
 
65
- # Mute all group
65
+ # Mute all in a group
66
66
  #
67
67
  # @param group_id [Integer] group id
68
68
  # @return [void]
@@ -74,6 +74,10 @@ module Rubirai
74
74
  nil
75
75
  end
76
76
 
77
+ # Unmute all in a group
78
+ #
79
+ # @param group_id [Integer] group id
80
+ # @return [void]
77
81
  def unmute_all(group_id)
78
82
  call :post, '/unmuteAll', json: {
79
83
  sessionKey: @session,
@@ -82,6 +86,10 @@ module Rubirai
82
86
  nil
83
87
  end
84
88
 
89
+ # Get group config
90
+ #
91
+ # @param group_id [Integer] group id
92
+ # @return [GroupConfig] the config
85
93
  def get_group_config(group_id)
86
94
  resp = call :get, '/groupConfig', params: {
87
95
  sessionKey: @session,
@@ -93,7 +101,9 @@ module Rubirai
93
101
  # Set group config
94
102
  #
95
103
  # @param group_id [Integer] group id
96
- # @param config [GroupConfig, Hash{String => Object}] the configuration
104
+ # @param config [GroupConfig, Hash{String, Symbol => Object}] the configuration. If given as
105
+ # a hash, then it should be exactly named the same as given in `mirai-api-http`
106
+ # docs.
97
107
  # @return [void]
98
108
  def set_group_config(group_id, config)
99
109
  config.must_be! [GroupConfig, Hash], RubiraiError, 'must be GroupConfig or Hash'
@@ -107,6 +117,11 @@ module Rubirai
107
117
  nil
108
118
  end
109
119
 
120
+ # Get member info
121
+ #
122
+ # @param group_id [Integer] group id
123
+ # @param member_id [Integer] the member's qq id
124
+ # @return [MemberInfo] the member's info
110
125
  def get_member_info(group_id, member_id)
111
126
  resp = call :get, '/memberInfo', params: {
112
127
  sessionKey: @session,
@@ -116,6 +131,14 @@ module Rubirai
116
131
  MemberInfo.new resp, self
117
132
  end
118
133
 
134
+ # Set member info
135
+ #
136
+ # @param group_id [Integer] group id
137
+ # @param member_id [Integer] the member's qq id
138
+ # @param info [MemberInfo, Hash{String,Symbol => Object}] the info to set. If given as
139
+ # a hash, then it should be exactly named the same as given in `mirai-api-http`
140
+ # docs.
141
+ # @return [void]
119
142
  def set_member_info(group_id, member_id, info)
120
143
  info.must_be! [MemberInfo, Hash], RubiraiError, 'must be MemberInfo or Hash'
121
144
  info.stringify_keys! if info.is_a? Hash
@@ -129,6 +152,11 @@ module Rubirai
129
152
  nil
130
153
  end
131
154
 
155
+ # Get the group files as a list
156
+ #
157
+ # @param group_id [Integer] the group id
158
+ # @param dir [String, nil] the directory to get. If `nil`, then the root directory is asserted.
159
+ # @return [Array<GroupFileSimple>] the list of files
132
160
  def get_group_file_list(group_id, dir = nil)
133
161
  resp = call :get, '/groupFileList', params: {
134
162
  sessionKey: @session,
@@ -141,12 +169,18 @@ module Rubirai
141
169
 
142
170
  # Get the info about a group file
143
171
  # @param group_id [Integer] the group id
144
- # @param file_id [String] the file id, e.g. `/xxx-xxx-xxx-xxx`
145
- def get_group_file_info(group_id, file_id)
172
+ # @param file_or_id [GroupFileSimple, String] the file id, e.g. `/xxx-xxx-xxx-xxx`
173
+ #
174
+ # @return [GroupFile] the info about the file
175
+ def get_group_file_info(group_id, file_or_id)
176
+ file_or_id.must_be! [GroupFileSimple, String], RubiraiError, 'must be GroupFileSimple or String'
177
+ raise RubiraiError, "#{file_or_id} is not a file" if file_or_id.is_a?(GroupFileSimple) && !file_or_id.is_file?
178
+ id = file_or_id.is_a? String ? file_or_id : file_or_id.id
179
+
146
180
  resp = call :get, '/groupFileInfo', params: {
147
181
  sessionKey: @session,
148
182
  target: group_id,
149
- id: file_id
183
+ id: id
150
184
  }
151
185
  GroupFile.new resp, self
152
186
  end
@@ -22,6 +22,12 @@ module Rubirai
22
22
  resp['messageId']
23
23
  end
24
24
 
25
+ # Send friend or group message
26
+ #
27
+ # @param type [Symbol, String] options: [group, friend]
28
+ # @param target_id [Integer] target qq/group id
29
+ # @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain, can be any type
30
+ # @return [Integer] message id
25
31
  def send_msg(type, target_id, *msgs)
26
32
  self.class.ensure_type_in type, 'group', 'friend'
27
33
  chain = Rubirai::MessageChain.make(*msgs, bot: self)
@@ -33,14 +39,28 @@ module Rubirai
33
39
  resp['messageId']
34
40
  end
35
41
 
42
+ # Send friend message
43
+ #
44
+ # @param target_qq [Integer] target qq id
45
+ # @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain, can be any type
46
+ # @return [Integer] message id
36
47
  def send_friend_msg(target_qq, *msgs)
37
48
  send_msg :friend, target_qq, *msgs
38
49
  end
39
50
 
51
+ # Send group message
52
+ #
53
+ # @param target_group_id [Integer] group id
54
+ # @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain, can be any type
55
+ # @return [Integer] message id
40
56
  def send_group_msg(target_group_id, *msgs)
41
57
  send_msg :group, target_group_id, *msgs
42
58
  end
43
59
 
60
+ # Recall a message
61
+ #
62
+ # @param msg_id [Integer] message id
63
+ # @return [void]
44
64
  def recall(msg_id)
45
65
  call :post, '/recall', json: {
46
66
  sessionKey: @session,
@@ -70,6 +90,13 @@ module Rubirai
70
90
  call :post, '/sendImageMessage', json: res
71
91
  end
72
92
 
93
+ # Send nudge
94
+ #
95
+ # @param target_id [Integer] target id
96
+ # @param subject_id [Integer] the id of the place where the nudge will be seen.
97
+ # Should be a group id or a friend's id
98
+ # @param kind [String, Symbol] options: `[Group, Friend]`
99
+ # @return [void]
73
100
  def send_nudge(target_id, subject_id, kind)
74
101
  kind.to_s.downcase.must_be_one_of! %w[group friend], RubiraiError, 'kind must be one of group or friend'
75
102
  call :post, '/sendNudge', json: {
@@ -81,4 +108,46 @@ module Rubirai
81
108
  nil
82
109
  end
83
110
  end
111
+
112
+ class MessageEvent
113
+ # Respond to a message event
114
+ #
115
+ # @param msgs [Array<Rubirai::Message, Hash, String, Object>] messages to form a chain
116
+ # @param quote [Boolean] if to quote the original message
117
+ # @return [void]
118
+ def respond(*msgs, quote: false)
119
+ check_bot
120
+ msgs.prepend(gen_quote) if quote
121
+ case self
122
+ when FriendMessageEvent
123
+ @bot.send_friend_msg(@sender.id, *msgs)
124
+ when GroupMessageEvent
125
+ @bot.send_group_msg(@sender.group.id, *msgs)
126
+ when TempMessageEvent
127
+ @bot.send_temp_msg(@sender.id, @sender.group.id, *msgs)
128
+ else
129
+ raise 'undefined error'
130
+ 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
+ end
146
+
147
+ private
148
+
149
+ def check_bot
150
+ raise RubiraiError, 'no bot found in event' unless @bot
151
+ end
152
+ end
84
153
  end
@@ -22,6 +22,10 @@ module Rubirai
22
22
  # @option text [String] the plain text
23
23
  # @return [Rubirai::PlainMessage]
24
24
  class Message
25
+ # @!attribute [r] bot
26
+ # @return [Bot] the bot
27
+ # @!attribute [r] type
28
+ # @return [Symbol] the type
25
29
  attr_reader :bot, :type
26
30
 
27
31
  # Objects to {Rubirai::Message}
@@ -58,10 +62,12 @@ module Rubirai
58
62
  raise(RubiraiError, 'type not in all message types') unless Message.all_types.include? type
59
63
  end
60
64
 
65
+ # @private
61
66
  def self.get_msg_klass(type)
62
67
  Object.const_get "Rubirai::#{type}Message"
63
68
  end
64
69
 
70
+ # @private
65
71
  def self.build_from(hash, bot = nil)
66
72
  hash = hash.stringify_keys
67
73
  raise(RubiraiError, 'not a valid message') unless hash.key? 'type'
@@ -72,6 +78,7 @@ module Rubirai
72
78
  klass.new hash, bot
73
79
  end
74
80
 
81
+ # @private
75
82
  def self.set_message(type, *attr_keys, &initialize_block)
76
83
  attr_reader(*attr_keys)
77
84
 
@@ -109,12 +116,16 @@ module Rubirai
109
116
  end
110
117
  end
111
118
 
119
+ # @private
112
120
  def initialize(type, bot = nil)
113
121
  Message.check_type type
114
122
  @bot = bot
115
123
  @type = type
116
124
  end
117
125
 
126
+ # Convert the message to a hash
127
+ #
128
+ # @return [Hash{String => Object}]
118
129
  def to_h
119
130
  res = self.class.keys.to_h do |k|
120
131
  v = instance_variable_get("@#{k}")
@@ -131,6 +142,7 @@ module Rubirai
131
142
  res.compact.stringify_keys
132
143
  end
133
144
 
145
+ # @private
134
146
  def self.metaclass
135
147
  class << self
136
148
  self
@@ -154,15 +166,19 @@ module Rubirai
154
166
  # @return [Integer] the message (chain) id
155
167
  # @!attribute [r] time
156
168
  # @return [Integer] the timestamp
169
+ # @!method from(**kwargs)
170
+ # @option kwargs [Integer] :id the id
171
+ # @option kwargs [Integer] :time the timestamp
172
+ # @!scope class
157
173
  set_message :Source, :id, :time
158
174
  end
159
175
 
160
176
  # The quote message type
161
177
  class QuoteMessage < Message
162
178
  # @!attribute [r] id
163
- # @return [Integer] the original (quoted) message (chain) id
179
+ # @return [Integer] the original (quoted) message chain id
164
180
  # @!attribute [r] group_id
165
- # @return [Integer] the group id
181
+ # @return [Integer] the group id. `0` if from friend.
166
182
  # @!attribute [r] sender_id
167
183
  # @return [Integer] the original sender's id
168
184
  # @!attribute [r] target_id
@@ -171,13 +187,14 @@ module Rubirai
171
187
  # @return [MessageChain] the original message chain
172
188
  set_message :Quote, :id, :group_id, :sender_id, :target_id, :origin
173
189
 
190
+ # @private
174
191
  def initialize(hash, bot = nil)
175
192
  super :Quote, bot
176
193
  @id = hash['id']
177
194
  @group_id = hash['groupId']
178
195
  @sender_id = hash['senderId']
179
196
  @target_id = hash['targetId']
180
- @origin = MessageChain.make(*hash['origin'], sender_id: @sender_id, bot: bot)
197
+ @origin = MessageChain.make(*hash['origin'], bot: bot)
181
198
  end
182
199
  end
183
200
 
@@ -272,7 +289,7 @@ module Rubirai
272
289
  @sender_id = hash['senderId']
273
290
  @time = hash['time']
274
291
  @sender_name = hash['senderName']
275
- @message_chain = MessageChain.make(*hash['messageChain'], sender_id: hash['senderId'], bot: bot)
292
+ @message_chain = MessageChain.make(*hash['messageChain'], bot: bot)
276
293
  end
277
294
  end
278
295
 
@@ -4,19 +4,27 @@ require 'rubirai/utils'
4
4
  require 'rubirai/messages/message'
5
5
 
6
6
  module Rubirai
7
+ # Message chain
7
8
  class MessageChain
8
9
  include Enumerable
9
10
 
10
- attr_reader :bot, :sender_id, :send_time, :messages, :read_only
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
11
20
 
12
21
  # Makes a message chain from a list of messages
13
22
  #
14
23
  # @param messages [Array<Rubirai::Message, Rubirai::MessageChain, Hash, String, Object>] a list of messages
15
- # @param sender_id [Integer, nil]
16
24
  # @param bot [Rubirai::Bot, nil]
17
25
  # @return [Rubirai::MessageChain] the message chain
18
- def self.make(*messages, sender_id: nil, bot: nil)
19
- chain = new(bot, sender_id: sender_id)
26
+ def self.make(*messages, bot: nil)
27
+ chain = new(bot)
20
28
  result = []
21
29
  messages.map { |msg| Message.to_message(msg, bot) }.each do |msg|
22
30
  if !result.empty? && result[-1].is_a?(PlainMessage) && msg.is_a?(PlainMessage)
@@ -43,8 +51,12 @@ module Rubirai
43
51
  alias << extend
44
52
  alias append extend
45
53
 
46
- def concat(msg_chain)
47
- msg_chain.to_a.each do |msg|
54
+ # Concats this message chain with another one
55
+ #
56
+ # @param msg_chain [MessageChain] another message chain
57
+ # @return [MessageChain] self
58
+ def concat!(msg_chain)
59
+ msg_chain.messages.each do |msg|
48
60
  internal_append msg
49
61
  end
50
62
  self
@@ -70,19 +82,21 @@ module Rubirai
70
82
  @messages.empty?
71
83
  end
72
84
 
85
+ # Don't use the constructor. Use {.make}.
86
+ #
87
+ # @private
73
88
  # @param bot [Rubirai::Bot, nil]
74
89
  # @param source [Array, nil]
75
- # @param sender_id [Integer, nil]
76
- def initialize(bot = nil, source = nil, sender_id: nil)
90
+ # @param id [Integer, nil]
91
+ def initialize(bot = nil, source = nil)
77
92
  @bot = bot
78
- @sender_id = sender_id
79
93
  @messages = []
80
94
  return unless source
81
95
  raise(MiraiError, 'source is not array') unless source.is_a? Array
82
96
  raise(MiraiError, 'length is zero') if source.empty?
83
97
 
84
98
  if source[0]['type'] == 'Source'
85
- @sender_id = source[0]['id']
99
+ @id = source[0]['id']
86
100
  @send_time = source[0]['time']
87
101
  extend(*source.drop(1))
88
102
  else
@@ -90,6 +104,9 @@ module Rubirai
90
104
  end
91
105
  end
92
106
 
107
+ # Convert the message chain to an array of hashes.
108
+ #
109
+ # @return [Array<Hash{String => Object}>]
93
110
  def to_a
94
111
  @messages.map(&:to_h)
95
112
  end
@@ -113,7 +130,7 @@ module Rubirai
113
130
  end
114
131
 
115
132
  # Makes a message chain. See {MessageChain#make}.
116
- def self.MessageChain(*messages, sender_id: nil, bot: nil)
117
- MessageChain.make(*messages, sender_id: sender_id, bot: bot)
133
+ def self.MessageChain(*messages, bot: nil)
134
+ MessageChain.make(*messages, bot: bot)
118
135
  end
119
136
  end
@@ -1,6 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rubirai
4
+ # The group
5
+ #
6
+ # @!attribute [r] bot
7
+ # @return [Bot] the bot
8
+ # @!attribute [r] id
9
+ # @return [Integer] group id
10
+ # @!attribute [r] name
11
+ # @return [String] group name
12
+ # @!attribute [r] permission
13
+ # @return [String] the group permission of the bot. See {Permission}
4
14
  class Group
5
15
  attr_reader :bot, :id, :name, :permission
6
16
 
@@ -14,9 +24,15 @@ module Rubirai
14
24
  @permission = hash['permission']
15
25
  end
16
26
 
27
+ # Group permissions
17
28
  class Permission
29
+ # Owner
18
30
  OWNER = 'OWNER'
31
+
32
+ # Administrator
19
33
  ADMINISTRATOR = 'ADMINISTRATOR'
34
+
35
+ # Member
20
36
  MEMBER = 'MEMBER'
21
37
  end
22
38
  end
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubirai/utils'
4
+
5
+ module Rubirai
6
+ # The abstract class for group information
7
+ # @abstract
8
+ class GroupInfo
9
+ # @private
10
+ def self.set_fields(*fields, **default_values)
11
+ attr_reader(*fields)
12
+
13
+ class_eval do
14
+ define_method(:initialize) do |hash, bot = nil|
15
+ # noinspection RubySuperCallWithoutSuperclassInspection
16
+ super hash, bot
17
+ fields.each do |field|
18
+ value = hash[field.to_s.snake_to_camel(lower: true)] || default_values[field]
19
+ instance_variable_set("@#{field}", value)
20
+ end
21
+ end
22
+
23
+ define_method(:to_h) do
24
+ fields.to_h do |field|
25
+ [field.to_s.snake_to_camel(lower: true), instance_variable_get(field)]
26
+ end.compact
27
+ end
28
+ end
29
+ end
30
+
31
+ # @private
32
+ def self.set_modifiable_fields(*fields)
33
+ set_fields(*fields)
34
+ attr_writer(*fields)
35
+ end
36
+
37
+ # @!attribute [r] raw
38
+ # @return [Hash{String => Object}] the raw hash
39
+ # @!attribute [r] bot
40
+ # @return [Bot] the bot
41
+ attr_reader :raw, :bot
42
+
43
+ # @private
44
+ def initialize(hash, bot = nil)
45
+ @raw = hash
46
+ @bot = bot
47
+ end
48
+ end
49
+
50
+ # Group config
51
+ class GroupConfig < GroupInfo
52
+ # @!method initialize(hash, bot = nil)
53
+ # @param hash [Hash{String => Object}]
54
+ # @param bot [Rubirai::Bot, nil]
55
+ # @!method to_h
56
+ # @return [Hash{String => Object}]
57
+ # @!attribute [rw] name
58
+ # @return [String]
59
+ # @!attribute [rw] announcement
60
+ # @return [String]
61
+ # @!attribute [rw] confess_talk
62
+ # @return [Boolean] is confess talk enabled
63
+ # @!attribute [rw] allow_member_invite
64
+ # @return [Boolean]
65
+ # @!attribute [rw] auto_approve
66
+ # @return [Boolean]
67
+ # @!attribute [rw] anonymous_chat
68
+ # @return [Boolean] is anonymous chat enabled
69
+ set_modifiable_fields :name, :announcement, :confess_talk, :allow_member_invite, :auto_approve, :anonymous_chat
70
+ end
71
+
72
+ # Member info
73
+ class MemberInfo < GroupInfo
74
+ # @!method initialize(hash, bot = nil)
75
+ # @param hash [Hash{String => Object}]
76
+ # @param bot [Rubirai::Bot, nil]
77
+ # @!method to_h
78
+ # @return [Hash{String => Object}]
79
+ # @!attribute [rw] name
80
+ # @return [String] member's name in the group
81
+ # @!attribute [r] nick
82
+ # @return [String] member's personal nickname
83
+ # @!attribute [rw] special_title
84
+ # @return [String] member's special title in the group
85
+ set_fields :name, :nick, :special_title
86
+ attr_writer :name, :special_title
87
+ end
88
+
89
+ # Group file with less information
90
+ class GroupFileSimple < GroupInfo
91
+ # @!method initialize(hash, bot = nil)
92
+ # @param hash [Hash{String => Object}]
93
+ # @param bot [Rubirai::Bot, nil]
94
+ # @!method to_h
95
+ # @return [Hash{String => Object}]
96
+ # @!attribute [r] name
97
+ # @return [String]
98
+ # @!attribute [r] id
99
+ # @return [Integer]
100
+ # @!attribute [r] is_file
101
+ # @return [Boolean]
102
+ set_fields :name, :id, :path, :is_file, is_file: true
103
+
104
+ alias is_file? is_file
105
+ end
106
+
107
+ # Group file with detailed information
108
+ class GroupFile < GroupFileSimple
109
+ # @!method initialize(hash, bot = nil)
110
+ # @param hash [Hash{String => Object}]
111
+ # @param bot [Rubirai::Bot, nil]
112
+ # @!method to_h
113
+ # @return [Hash{String => Object}]
114
+ # @!attribute [r] length
115
+ # @return [Integer]
116
+ # @!attribute [r] download_times
117
+ # @return [Integer]
118
+ # @!attribute [r] uploader_id
119
+ # @return [Integer]
120
+ # @!attribute [r] upload_time
121
+ # @return [Integer]
122
+ # @!attribute [r] last_modify_time
123
+ # @return [Integer]
124
+ # @!attribute [r] download_url
125
+ # @return [String]
126
+ # @!attribute [r] sha1
127
+ # @return [String]
128
+ # @!attribute [r] md5
129
+ # @return [String]
130
+ set_fields :length,
131
+ :download_times,
132
+ :uploader_id,
133
+ :upload_time,
134
+ :last_modify_time,
135
+ :download_url,
136
+ :sha1,
137
+ :md5
138
+ end
139
+ end
@@ -2,8 +2,9 @@
2
2
 
3
3
  module Rubirai
4
4
  class Bot
5
- # Get Mirai API plugin information such as
5
+ # Get Mirai API plugin information.
6
6
  #
7
+ # The information is like
7
8
  # ```ruby
8
9
  # {
9
10
  # 'version' => '1.0.0'
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Rubirai
4
4
  # Rubirai version
5
- VERSION = '0.0.2'
5
+ VERSION = '0.0.3-a1'
6
6
 
7
7
  # mirai-api-http version
8
8
  MIRAI_API_VERSION = '1.10.0'
data/misc/common.css CHANGED
@@ -7,5 +7,5 @@ h1, h2, h3, h4, h5, h6, h3.signature .aliases {
7
7
 
8
8
  pre, code, tt, dt code, table tr td dt code, ul.summary, h3.signature .aliases .names,
9
9
  p.signature, h3.signature, .tags ul .name, p.inherited a {
10
- font-family: 'Menlo', 'Roboto Mono', monospace !important;
10
+ font-family: 'Roboto Mono', monospace !important;
11
11
  }
data/rubirai.gemspec CHANGED
@@ -10,7 +10,6 @@ Gem::Specification.new do |s|
10
10
  s.description = 'A Mirai QQ bot http interface lib for Ruby.'
11
11
  s.authors = ['Rebuild']
12
12
  s.email = 'admin@rebuild.moe'
13
- s.licenses = ['AGPLv3']
14
13
  s.files = `git ls-files`.split("\n")
15
14
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
15
  s.require_paths = ['lib']
@@ -20,5 +19,5 @@ Gem::Specification.new do |s|
20
19
  s.add_dependency 'concurrent-ruby', '~> 1.1.8'
21
20
  s.add_dependency 'http', '~> 5.0'
22
21
  s.homepage = 'https://github.com/Shimogawa/rubirai'
23
- s.license = 'AGPLv3'
22
+ s.license = 'AGPL-3.0'
24
23
  end
data/spec/auth_spec.rb CHANGED
@@ -79,23 +79,7 @@ describe 'auth api' do
79
79
 
80
80
  it 'should be able to login and logout' do
81
81
  mirai_bot = Rubirai::Bot.new 'test'
82
- stub_request(:post, @mirai_bot.gen_uri('/auth'))
83
- .with(body: {
84
- "authKey": @auth_key
85
- })
86
- .to_return(status: 200, body: %({
87
- "code": 0,
88
- "session": "#{@session_key}"
89
- }))
90
- stub_request(:post, @mirai_bot.gen_uri('/verify'))
91
- .with(body: {
92
- "sessionKey": @session_key,
93
- "qq": @qq
94
- })
95
- .to_return(status: 200, body: %({
96
- "code": 0,
97
- "session": "success"
98
- }))
82
+ stub_login
99
83
  stub_request(:post, @mirai_bot.gen_uri('/release'))
100
84
  .with(body: {
101
85
  "sessionKey": @session_key,
@@ -73,6 +73,9 @@ describe Rubirai::Event do
73
73
  }
74
74
  e = Rubirai::Event.parse hash
75
75
  expect(e).to be_a(Rubirai::BotGroupPermissionChangedEvent)
76
- expect(e.class.type)
76
+ expect(e.class.type).to eq(:BotGroupPermissionChangeEvent)
77
+ expect(e.origin).to eq(Rubirai::Group::Permission::MEMBER)
78
+ expect(e.new).to eq(Rubirai::Group::Permission::ADMINISTRATOR)
79
+ expect(e.group.id).to eq(123456789)
77
80
  end
78
81
  end
data/spec/message_spec.rb CHANGED
@@ -5,8 +5,83 @@ require 'spec_helper'
5
5
  describe 'message api' do
6
6
  before :all do
7
7
  @mirai_bot = new_bot
8
+ stub_login
9
+ @mirai_bot.login @qq, @auth_key
8
10
  end
9
11
 
10
12
  after do
11
13
  end
14
+
15
+ it 'should be able to send friend message' do
16
+ stub_request(:post, @mirai_bot.gen_uri('/sendFriendMessage'))
17
+ .with(body: {
18
+ "sessionKey": @session_key,
19
+ "target": 987654321,
20
+ "messageChain": [
21
+ { "type": 'Plain', "text": "hello\nworld" },
22
+ { "type": 'Image', "url": 'a' }
23
+ ]
24
+ })
25
+ .to_return(status: 200, body: %({
26
+ "code": 0,
27
+ "msg": "success",
28
+ "messageId": 1234567890
29
+ }))
30
+ res = @mirai_bot.send_friend_msg 987654321, "hello\nworld", Rubirai::ImageMessage(url: 'a')
31
+ expect(res).to eq(1234567890)
32
+ end
33
+
34
+ it 'should be able to send temp message' do
35
+ stub_request(:post, @mirai_bot.gen_uri('/sendTempMessage'))
36
+ .with(body: {
37
+ "sessionKey": @session_key,
38
+ "qq": 123,
39
+ "group": 456,
40
+ "messageChain": [
41
+ { "type": 'Plain', "text": "hello\nworld" },
42
+ { "type": 'Image', "url": 'a' }
43
+ ]
44
+ })
45
+ .to_return(status: 200, body: %({
46
+ "code": 0,
47
+ "msg": "success",
48
+ "messageId": 1234567890
49
+ }))
50
+ res = @mirai_bot.send_temp_msg 123, 456, "hello\nworld", Rubirai::ImageMessage(url: 'a')
51
+ expect(res).to eq(1234567890)
52
+ end
53
+
54
+ it 'should be able to send group message' do
55
+ stub_request(:post, @mirai_bot.gen_uri('/sendGroupMessage'))
56
+ .with(body: {
57
+ "sessionKey": @session_key,
58
+ "target": 456,
59
+ "messageChain": [
60
+ { "type": 'Plain', "text": "hello\nworld" },
61
+ { "type": 'Image', "url": 'a' }
62
+ ]
63
+ })
64
+ .to_return(status: 200, body: %({
65
+ "code": 0,
66
+ "msg": "success",
67
+ "messageId": 1234567890
68
+ }))
69
+ res = @mirai_bot.send_group_msg 456, "hello\nworld", Rubirai::ImageMessage(url: 'a')
70
+ expect(res).to eq(1234567890)
71
+ end
72
+
73
+ it 'should be able to recall a message' do
74
+ stub_request(:post, @mirai_bot.gen_uri('/recall'))
75
+ .with(body: {
76
+ "sessionKey": @session_key,
77
+ "target": 123
78
+ })
79
+ .to_return(status: 200, body: %({
80
+ "code": 0,
81
+ "msg": "success"
82
+ }))
83
+ expect do
84
+ expect(@mirai_bot.recall(123)).to be_nil
85
+ end.not_to raise_error
86
+ end
12
87
  end
@@ -37,7 +37,7 @@ describe Rubirai::Message do
37
37
  qm = Rubirai::QuoteMessage.new hash
38
38
  expect(qm.id).to eq(123456)
39
39
  expect(qm.origin).to be_a(Rubirai::MessageChain)
40
- expect(qm.origin.sender_id).to eq(987654321)
40
+ expect(qm.origin.id).to be_nil
41
41
  expect(qm.origin.messages).to be_a(Array)
42
42
  expect(qm.origin.messages.length).to eq(1)
43
43
  expect(qm.origin.messages[0]).to be_a(Rubirai::Message)
data/spec/spec_helper.rb CHANGED
@@ -29,3 +29,23 @@ RSpec.configure do |config|
29
29
  @qq = 1145141919
30
30
  end
31
31
  end
32
+
33
+ def stub_login
34
+ stub_request(:post, @mirai_bot.gen_uri('/auth'))
35
+ .with(body: {
36
+ "authKey": @auth_key
37
+ })
38
+ .to_return(status: 200, body: %({
39
+ "code": 0,
40
+ "session": "#{@session_key}"
41
+ }))
42
+ stub_request(:post, @mirai_bot.gen_uri('/verify'))
43
+ .with(body: {
44
+ "sessionKey": @session_key,
45
+ "qq": @qq
46
+ })
47
+ .to_return(status: 200, body: %({
48
+ "code": 0,
49
+ "session": "success"
50
+ }))
51
+ end
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.2
4
+ version: 0.0.3.pre.a1
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-28 00:00:00.000000000 Z
11
+ date: 2021-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -47,6 +47,7 @@ files:
47
47
  - ".github/dependabot.yml"
48
48
  - ".github/workflows/CI.yml"
49
49
  - ".github/workflows/docs.yml"
50
+ - ".github/workflows/package.yml"
50
51
  - ".github/workflows/pull_request.yml"
51
52
  - ".gitignore"
52
53
  - ".rubocop.yml"
@@ -76,7 +77,7 @@ files:
76
77
  - lib/rubirai/messages/message_chain.rb
77
78
  - lib/rubirai/multipart.rb
78
79
  - lib/rubirai/objects/group.rb
79
- - lib/rubirai/objects/info.rb
80
+ - lib/rubirai/objects/group_info.rb
80
81
  - lib/rubirai/objects/user.rb
81
82
  - lib/rubirai/plugin_info.rb
82
83
  - lib/rubirai/retcode.rb
@@ -97,7 +98,7 @@ files:
97
98
  - spec/utils_spec.rb
98
99
  homepage: https://github.com/Shimogawa/rubirai
99
100
  licenses:
100
- - AGPLv3
101
+ - AGPL-3.0
101
102
  metadata: {}
102
103
  post_install_message:
103
104
  rdoc_options: []
@@ -110,9 +111,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
111
  version: '2.6'
111
112
  required_rubygems_version: !ruby/object:Gem::Requirement
112
113
  requirements:
113
- - - ">="
114
+ - - ">"
114
115
  - !ruby/object:Gem::Version
115
- version: '0'
116
+ version: 1.3.1
116
117
  requirements: []
117
118
  rubygems_version: 3.0.3.1
118
119
  signing_key:
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rubirai/utils'
4
-
5
- module Rubirai
6
- # @abstract
7
- class Info
8
- # @!method initialize(hash, bot = nil)
9
- # @param hash [Hash{String => Object}]
10
- # @param bot [Rubirai::Bot, nil]
11
- # @!method to_h
12
- # @return [Hash{String => Object}]
13
- def self.set_fields(*fields, **default_values)
14
- attr_reader(*fields)
15
-
16
- class_eval do
17
- define_method(:initialize) do |hash, bot = nil|
18
- # noinspection RubySuperCallWithoutSuperclassInspection
19
- super hash, bot
20
- fields.each do |field|
21
- value = hash[field.to_s.snake_to_camel(lower: true)] || default_values[field]
22
- instance_variable_set("@#{field}", value)
23
- end
24
- end
25
-
26
- define_method(:to_h) do
27
- fields.to_h do |field|
28
- [field.to_s.snake_to_camel(lower: true), instance_variable_get(field)]
29
- end.compact
30
- end
31
- end
32
- end
33
-
34
- def self.set_modifiable_fields(*fields)
35
- set_fields(*fields)
36
- attr_writer(*fields)
37
- end
38
-
39
- attr_reader :raw, :bot
40
-
41
- def initialize(hash, bot = nil)
42
- @raw = hash
43
- @bot = bot
44
- end
45
- end
46
-
47
- class GroupConfig < Info
48
- set_modifiable_fields :name, :announcement, :confess_talk, :allow_member_invite, :auto_approve, :anonymous_chat
49
- end
50
-
51
- class MemberInfo < Info
52
- set_fields :name, :nick, :special_title
53
- attr_writer :name, :special_title
54
- end
55
-
56
- class GroupFileSimple < Info
57
- set_fields :name, :id, :path, :is_file, is_file: true
58
- end
59
-
60
- class GroupFile < GroupFileSimple
61
- set_fields :length,
62
- :download_times,
63
- :uploader_id,
64
- :upload_time,
65
- :last_modify_time,
66
- :download_url,
67
- :sha1,
68
- :md5,
69
- call_super: true
70
- end
71
- end