matrix_sdk 2.6.0 → 2.7.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.
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MatrixSdk::Bot
4
+ PARAMS_CONFIG = {} # rubocop:disable Style/MutableConstant Intended
5
+
6
+ require 'optparse'
7
+ parser = OptionParser.new do |op|
8
+ op.on('-s homeserver', 'Specify homeserver') { |val| PARAMS_CONFIG[:homeserver] = val }
9
+
10
+ op.on('-T token', 'Token') { |val| PARAMS_CONFIG[:access_token] = val }
11
+ op.on('-U username', 'Username') { |val| PARAMS_CONFIG[:username] = val }
12
+ op.on('-P password', 'Password') { |val| PARAMS_CONFIG[:password] = val }
13
+
14
+ op.on('-q', 'Disable logging') { PARAMS_CONFIG[:logging] = false }
15
+ op.on('-v', 'Enable verbose output') { PARAMS_CONFIG[:logging] = !(PARAMS_CONFIG[:log_level] = :debug).nil? }
16
+ end
17
+
18
+ begin
19
+ parser.parse!(ARGV.dup)
20
+ rescue StandardError => e
21
+ PARAMS_CONFIG[:optparse_error] = e
22
+ end
23
+
24
+ MatrixSdk.logger.appenders.each do |log|
25
+ log.layout = Logging::Layouts.pattern(
26
+ pattern: "%d|%.1l %c : %m\n"
27
+ )
28
+ end
29
+ MatrixSdk.debug! if ENV['MATRIX_DEBUG'] == '1'
30
+
31
+ require 'matrix_sdk/bot/base'
32
+ class Instance < Base
33
+ set :logging, true
34
+ set :log_level, :info
35
+
36
+ set :app_file, caller_files.first || $PROGRAM_NAME
37
+ set(:run) { File.expand_path($PROGRAM_NAME) == File.expand_path(app_file) }
38
+
39
+ if run? && ARGV.any?
40
+ error = PARAMS_CONFIG.delete(:optparse_error)
41
+ raise error if error
42
+
43
+ PARAMS_CONFIG.each { |k, v| set k, v }
44
+ end
45
+ end
46
+
47
+ module Delegator
48
+ def self.delegate(*methods)
49
+ methods.each do |method_name|
50
+ define_method(method_name) do |*args, &block|
51
+ return super(*args, &block) if respond_to? method_name
52
+
53
+ Delegator.target.send(method_name, *args, &block)
54
+ end
55
+ # ensure keyword argument passing is compatible with ruby >= 2.7
56
+ ruby2_keywords(method_name) if respond_to?(:ruby2_keywords, true)
57
+ private method_name
58
+ end
59
+ end
60
+
61
+ delegate :command, :client, :event,
62
+ :settings,
63
+ :set, :enable, :disable
64
+
65
+ class << self
66
+ attr_accessor :target
67
+ end
68
+
69
+ self.target = Instance
70
+ end
71
+
72
+ # Trigger the global instance to run once the main class finishes
73
+ at_exit do
74
+ remove_const(:PARAMS_CONFIG)
75
+ Instance.run! if $!.nil? && Instance.run? # rubocop:disable Style/SpecialGlobalVars Don't want to require into global scope
76
+ end
77
+ end
78
+
79
+ extend MatrixSdk::Bot::Delegator # rubocop:disable Style/MixinUsage Intended
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'matrix_sdk'
4
+ require 'matrix_sdk/bot/main'
@@ -22,11 +22,11 @@ module MatrixSdk
22
22
  # @return [Hash,String] A filter definition, either as defined by the
23
23
  # Matrix spec, or as an identifier returned by a filter creation request
24
24
  attr_reader :api, :next_batch
25
- attr_accessor :cache, :sync_filter
25
+ attr_accessor :cache, :sync_filter, :sync_token
26
26
 
27
- events :error, :event, :presence_event, :invite_event, :leave_event, :ephemeral_event, :state_event
27
+ events :error, :event, :account_data, :presence_event, :invite_event, :leave_event, :ephemeral_event, :state_event
28
28
  ignore_inspect :api,
29
- :on_event, :on_presence_event, :on_invite_event, :on_leave_event, :on_ephemeral_event
29
+ :on_event, :on_account_data, :on_presence_event, :on_invite_event, :on_leave_event, :on_ephemeral_event
30
30
 
31
31
  def_delegators :@api,
32
32
  :access_token, :access_token=, :device_id, :device_id=, :homeserver, :homeserver=,
@@ -45,10 +45,10 @@ module MatrixSdk
45
45
  # @see #initialize
46
46
  def self.new_for_domain(domain, **params)
47
47
  api = MatrixSdk::Api.new_for_domain(domain, keep_wellknown: true)
48
- return new(api, params) unless api.well_known&.key?('m.identity_server')
48
+ return new(api, **params) unless api.well_known&.key?('m.identity_server')
49
49
 
50
50
  identity_server = MatrixSdk::Api.new(api.well_known['m.identity_server']['base_url'], protocols: %i[IS])
51
- new(api, params.merge(identity_server: identity_server))
51
+ new(api, **params.merge(identity_server: identity_server))
52
52
  end
53
53
 
54
54
  # @param hs_url [String,URI,Api] The URL to the Matrix homeserver, without the /_matrix/ part, or an existing Api instance
@@ -161,7 +161,14 @@ module MatrixSdk
161
161
  #
162
162
  # @return [Hash[String,Array[String]]] A mapping of MXIDs to a list of direct rooms with that user
163
163
  def direct_rooms
164
- api.get_account_data(mxid, 'm.direct').transform_keys(&:to_s)
164
+ account_data['m.direct'].transform_keys(&:to_s)
165
+ end
166
+
167
+ # Retrieve an account data helper
168
+ def account_data
169
+ return MatrixSdk::Util::AccountDataCache.new self if cache == :none
170
+
171
+ @account_data ||= MatrixSdk::Util::AccountDataCache.new self
165
172
  end
166
173
 
167
174
  # Gets a direct message room for the given user if one exists
@@ -498,8 +505,9 @@ module MatrixSdk
498
505
  else
499
506
  @should_listen = false
500
507
  end
508
+
501
509
  if @sync_thread.alive?
502
- ret = @sync_thread.join(2)
510
+ ret = @sync_thread.join(0.1)
503
511
  @sync_thread.kill unless ret
504
512
  end
505
513
  @sync_thread = nil
@@ -568,10 +576,13 @@ module MatrixSdk
568
576
  while @should_listen
569
577
  begin
570
578
  sync(**params.merge(timeout: timeout))
579
+ return unless @should_listen
571
580
 
572
581
  bad_sync_timeout = orig_bad_sync_timeout
573
582
  sleep(sync_interval) if sync_interval.positive?
574
583
  rescue MatrixRequestError => e
584
+ return unless @should_listen
585
+
575
586
  logger.warn("A #{e.class} occurred during sync")
576
587
  if e.httpstatus >= 500
577
588
  logger.warn("Serverside error, retrying in #{bad_sync_timeout} seconds...")
@@ -606,6 +617,14 @@ module MatrixSdk
606
617
  end
607
618
 
608
619
  def handle_sync_response(data)
620
+ data.dig(:account_data, :events)&.each do |account_data|
621
+ if cache != :none
622
+ adapter = self.account_data.tinycache_adapter
623
+ adapter.write(account_data[:type], account_data[:content], expires_in: self.account_data.cache_time)
624
+ end
625
+ fire_account_data(MatrixEvent.new(self, account_data))
626
+ end
627
+
609
628
  data.dig(:presence, :events)&.each do |presence_update|
610
629
  fire_presence_event(MatrixEvent.new(self, presence_update))
611
630
  end
@@ -625,6 +644,13 @@ module MatrixSdk
625
644
  room.instance_variable_set '@prev_batch', join.dig(:timeline, :prev_batch)
626
645
  room.instance_variable_set :@members_loaded, true unless sync_filter.fetch(:room, {}).fetch(:state, {}).fetch(:lazy_load_members, false)
627
646
 
647
+ join.dig(:account_data, :events)&.each do |account_data|
648
+ account_data[:room_id] = room_id.to_s
649
+ room.send :put_account_data, account_data
650
+
651
+ fire_account_data(MatrixEvent.new(self, account_data))
652
+ end
653
+
628
654
  join.dig(:state, :events)&.each do |event|
629
655
  event[:room_id] = room_id.to_s
630
656
  handle_state(room_id, event)
@@ -652,10 +678,12 @@ module MatrixSdk
652
678
  end
653
679
 
654
680
  unless cache == :none
681
+ account_data.tinycache_adapter.cleanup if instance_variable_defined?(:@account_data) && @account_data
655
682
  @rooms.each do |_id, room|
656
683
  # Clean up old cache data after every sync
657
684
  # TODO Run this in a thread?
658
685
  room.tinycache_adapter.cleanup
686
+ room.account_data.tinycache_adapter.cleanup
659
687
  end
660
688
  end
661
689
 
@@ -45,6 +45,8 @@ module MatrixSdk
45
45
  "#{sigil}#{localpart}#{homeserver_suffix}"
46
46
  end
47
47
 
48
+ alias to_str to_s
49
+
48
50
  # Returns the type of the ID
49
51
  #
50
52
  # @return [Symbol] The MXID type, one of (:user_id, :room_id, :event_id, :group_id, or :room_alias)
@@ -31,6 +31,8 @@ module MatrixSdk
31
31
  return data
32
32
  end
33
33
 
34
+ return data if data.instance_variables.include? :@api
35
+
34
36
  raise ArgumentError, 'Input data was not a hash' unless data.is_a? Hash
35
37
 
36
38
  data.extend(Extensions)
@@ -127,6 +127,12 @@ module MatrixSdk
127
127
  ensure_room_handlers[:event]
128
128
  end
129
129
 
130
+ # @!attribute [r] on_account_data
131
+ # @return [EventHandlerArray] The list of event handlers for account data changes
132
+ def on_account_data
133
+ ensure_room_handlers[:account_data]
134
+ end
135
+
130
136
  # @!attribute [r] on_state_event
131
137
  # @return [EventHandlerArray] The list of event handlers for only state events
132
138
  def on_state_event
@@ -208,6 +214,32 @@ module MatrixSdk
208
214
  nil
209
215
  end
210
216
 
217
+ # Checks if the room is a direct message / 1:1 room
218
+ #
219
+ # @param members_only [Boolean] Should directness only care about member count?
220
+ # @return [Boolean]
221
+ def dm?(members_only: false)
222
+ return true if !members_only && client.direct_rooms.any? { |_uid, rooms| rooms.include? id.to_s }
223
+
224
+ joined_members.count <= 2
225
+ end
226
+
227
+ # Mark a room as a direct (1:1) message Room
228
+ def dm=(direct)
229
+ rooms = client.direct_rooms
230
+ dirty = false
231
+ list_for_room = (rooms[id.to_s] ||= [])
232
+ if direct && !list_for_room.include?(id.to_s)
233
+ list_for_room << id.to_s
234
+ dirty = true
235
+ elsif !direct && list_for_room.include?(id.to_s)
236
+ list_for_room.delete id.to_s
237
+ rooms.delete id.to_s if list_for_room.empty?
238
+ dirty = true
239
+ end
240
+ client.account_data['m.direct'] = rooms if dirty
241
+ end
242
+
211
243
  # Gets the avatar url of the room - if any
212
244
  #
213
245
  # @return [String,nil] The avatar URL - if any
@@ -400,6 +432,31 @@ module MatrixSdk
400
432
  client.api.send_content(id, url, name, 'm.audio', extra_information: audio_info)
401
433
  end
402
434
 
435
+ # Sends a customized message to the Room
436
+ #
437
+ # @param body [String] The clear-text body of the message
438
+ # @param content [Hash] The custom content of the message
439
+ # @param msgtype [String] The type of the message, should be one of the known types (m.text, m.notice, m.emote, etc)
440
+ def send_custom_message(body, content = {}, msgtype: nil)
441
+ content.merge!(
442
+ body: body,
443
+ msgtype: msgtype || 'm.text'
444
+ )
445
+
446
+ client.api.send_message_event(id, 'm.room.message', content)
447
+ end
448
+
449
+ # Sends a custom timeline event to the Room
450
+ #
451
+ # @param type [String,Symbol] The type of the Event.
452
+ # For custom events, this should be written in reverse DNS format (e.g. com.example.event)
453
+ # @param content [Hash] The contents of the message, this will be the
454
+ # :content key of the resulting event object
455
+ # @see Protocols::CS#send_message_event
456
+ def send_event(type, content = {})
457
+ client.api.send_message_event(id, type, content)
458
+ end
459
+
403
460
  # Redacts a message from the room
404
461
  #
405
462
  # @param event_id [String] the ID of the event to redact
@@ -496,12 +553,18 @@ module MatrixSdk
496
553
  true
497
554
  end
498
555
 
556
+ def account_data
557
+ return MatrixSdk::Util::AccountDataCache.new client, room: self if client.cache == :none
558
+
559
+ @account_data ||= MatrixSdk::Util::AccountDataCache.new client, room: self
560
+ end
561
+
499
562
  # Retrieves a custom entry from the room-specific account data
500
563
  #
501
564
  # @param type [String] the data type to retrieve
502
565
  # @return [Hash] the data that was stored under the given type
503
566
  def get_account_data(type)
504
- client.api.get_room_account_data(client.mxid, id, type)
567
+ account_data[type]
505
568
  end
506
569
 
507
570
  # Stores a custom entry into the room-specific account data
@@ -509,7 +572,7 @@ module MatrixSdk
509
572
  # @param type [String] the data type to store
510
573
  # @param account_data [Hash] the data to store
511
574
  def set_account_data(type, account_data)
512
- client.api.set_room_account_data(client.mxid, id, type, account_data)
575
+ self.account_data[type] = account_data
513
576
  true
514
577
  end
515
578
 
@@ -741,13 +804,27 @@ module MatrixSdk
741
804
  def user_powerlevel(user, use_default: true)
742
805
  user = user.id if user.is_a? User
743
806
  user = MXID.new(user.to_s) unless user.is_a? MXID
744
- raise ArgumentError, 'Must provide a valid user or MXID' unless user.user?
807
+ raise ArgumentError, 'Must provide a valid User or MXID' unless user.user?
745
808
 
746
809
  level = power_levels.dig(:users, user.to_s.to_sym)
747
- level = power_levels[:users_default] || 0 if level.nil? && use_default
810
+ level ||= power_levels[:users_default] || 0 if use_default
748
811
  level
749
812
  end
750
813
 
814
+ # Checks if a user can send a given event type in the room
815
+ #
816
+ # @param user [User,MXID,String] The user to check
817
+ # @param event [String,Symbol] The event type to check
818
+ # @param state [Boolean] If the given event is a state event or a message event
819
+ # @return [Boolean] If the given user is allowed to send an event of the given type
820
+ def user_can_send?(user, event, state: false)
821
+ user_pl = user_powerlevel(user)
822
+ event_pl = power_levels.dig(:events, event.to_s.to_sym)
823
+ event_pl ||= state ? (power_levels[:state_default] || 50) : (power_levels[:events_default] || 0)
824
+
825
+ user_pl >= event_pl
826
+ end
827
+
751
828
  # Check if a user is an admin in the room
752
829
  #
753
830
  # @param user [User,MXID,String] The user to check for admin privileges
@@ -861,10 +938,14 @@ module MatrixSdk
861
938
  private
862
939
 
863
940
  def ensure_member(member)
941
+ return unless client.cache == :all
942
+
864
943
  tinycache_adapter.write(:joined_members, []) unless tinycache_adapter.exist? :joined_members
865
944
 
866
945
  members = tinycache_adapter.read(:joined_members) || []
867
946
  members << member unless members.any? { |m| m.id == member.id }
947
+
948
+ tinycache_adapter.write(:joined_members, members)
868
949
  end
869
950
 
870
951
  def handle_power_levels(event)
@@ -915,6 +996,7 @@ module MatrixSdk
915
996
 
916
997
  def ensure_room_handlers
917
998
  client.instance_variable_get(:@room_handlers)[id] ||= {
999
+ account_data: MatrixSdk::EventHandlerArray.new,
918
1000
  event: MatrixSdk::EventHandlerArray.new,
919
1001
  state_event: MatrixSdk::EventHandlerArray.new,
920
1002
  ephemeral_event: MatrixSdk::EventHandlerArray.new
@@ -930,6 +1012,7 @@ module MatrixSdk
930
1012
  'm.room.power_levels' => :handle_power_levels,
931
1013
  'm.room.topic' => :handle_room_topic
932
1014
  }.freeze
1015
+
933
1016
  def put_event(event)
934
1017
  ensure_room_handlers[:event].fire(MatrixEvent.new(self, event), event[:type]) if room_handlers?
935
1018
 
@@ -937,6 +1020,17 @@ module MatrixSdk
937
1020
  @events.shift if @events.length > @event_history_limit
938
1021
  end
939
1022
 
1023
+ def put_account_data(event)
1024
+ if client.cache != :none
1025
+ adapter = account_data.tinycache_adapter
1026
+ adapter.write(event[:type], event[:content], expires_in: account_data.cache_time)
1027
+ end
1028
+
1029
+ return unless room_handlers?
1030
+
1031
+ ensure_room_handlers[:account_data].fire(MatrixEvent.new(self, event))
1032
+ end
1033
+
940
1034
  def put_ephemeral_event(event)
941
1035
  return unless room_handlers?
942
1036
 
@@ -28,6 +28,12 @@ module MatrixSdk
28
28
  end
29
29
  end
30
30
 
31
+ def to_s
32
+ "#{display_name} (#{id})" if @display_name
33
+
34
+ @id.to_s
35
+ end
36
+
31
37
  # @return [String] the display name
32
38
  # @see MatrixSdk::Protocols::CS#get_display_name
33
39
  def display_name
@@ -68,6 +74,22 @@ module MatrixSdk
68
74
  @avatar_url = url
69
75
  end
70
76
 
77
+ # Check if the user is an admin in a given room
78
+ #
79
+ # @param room [String,MXID] the room to check
80
+ # @return [Boolean] If the user is an admin (PL >= 100)
81
+ def admin?(room)
82
+ client.ensure_room(room).user_powerlevel(self) >= 100
83
+ end
84
+
85
+ # Check if the user is a moderator in a given room
86
+ #
87
+ # @param room [String,MXID] the room to check
88
+ # @return [Boolean] If the user is an admin (PL >= 50)
89
+ def moderator?(room)
90
+ client.ensure_room(room).user_powerlevel(self) >= 50
91
+ end
92
+
71
93
  # Get the user's current presence status
72
94
  #
73
95
  # @return [Symbol] One of :online, :offline, :unavailable
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MatrixSdk::Util
4
+ class AccountDataCache
5
+ extend MatrixSdk::Extensions
6
+ extend MatrixSdk::Util::Tinycache
7
+ include Enumerable
8
+
9
+ attr_reader :client, :room
10
+
11
+ attr_accessor :cache_time
12
+
13
+ ignore_inspect :client, :room, :tinycache_adapter
14
+
15
+ def initialize(client, room: nil, cache_time: 1 * 60 * 60, **_params)
16
+ raise ArgumentError, 'Must be given a Client instance' unless client.is_a? MatrixSdk::Client
17
+
18
+ @client = client
19
+ @cache_time = cache_time
20
+
21
+ return unless room
22
+
23
+ @room = room
24
+ @room = client.ensure_room room unless @room.is_a? MatrixSdk::Room
25
+ end
26
+
27
+ def reload!
28
+ tinycache_adapter.clear
29
+ end
30
+
31
+ def keys
32
+ tinycache_adapter.send(:cache).keys
33
+ end
34
+
35
+ def values
36
+ keys.map { |key| tinycache_adapter.read(key) }
37
+ end
38
+
39
+ def size
40
+ keys.count
41
+ end
42
+
43
+ def key?(key)
44
+ keys.key?(key.to_s)
45
+ end
46
+
47
+ def each(live: false)
48
+ return to_enum(__method__, live: live) { keys.count } unless block_given?
49
+
50
+ keys.each do |key|
51
+ v = live ? self[key] : tinycache_adapter.read(key)
52
+ # hash = v.hash
53
+ yield key, v
54
+ # self[key] = v if hash != v.hash
55
+ end
56
+ end
57
+
58
+ def delete(key)
59
+ key = key.to_s unless key.is_a? String
60
+ if room
61
+ client.api.set_room_account_data(client.mxid, room.id, key, {})
62
+ else
63
+ client.api.set_account_data(client.mxid, key, {})
64
+ end
65
+ tinycache_adapter.delete(key)
66
+ end
67
+
68
+ def [](key)
69
+ key = key.to_s unless key.is_a? String
70
+ tinycache_adapter.fetch(key, expires_in: @cache_time) do
71
+ if room
72
+ client.api.get_room_account_data(client.mxid, room.id, key)
73
+ else
74
+ client.api.get_account_data(client.mxid, key)
75
+ end
76
+ rescue MatrixSdk::MatrixNotFoundError
77
+ {}
78
+ end
79
+ end
80
+
81
+ def []=(key, value)
82
+ key = key.to_s unless key.is_a? String
83
+ if room
84
+ client.api.set_room_account_data(client.mxid, room.id, key, value)
85
+ else
86
+ client.api.set_account_data(client.mxid, key, value)
87
+ end
88
+ tinycache_adapter.write(key, value)
89
+ end
90
+ end
91
+ end
@@ -62,7 +62,7 @@ module MatrixSdk
62
62
  end
63
63
 
64
64
  def pretty_print(pp)
65
- pp.pp_object(self)
65
+ pp.pp(self)
66
66
  end
67
67
 
68
68
  alias inspect pretty_print_inspect
@@ -73,8 +73,9 @@ module MatrixSdk
73
73
  module Logging
74
74
  def logger
75
75
  return MatrixSdk.logger if MatrixSdk.global_logger?
76
+ return @logger if instance_variable_defined?(:@logger) && @logger
76
77
 
77
- @logger ||= ::Logging.logger[self]
78
+ ::Logging.logger[self]
78
79
  end
79
80
 
80
81
  def logger=(logger)
@@ -2,8 +2,12 @@
2
2
 
3
3
  module MatrixSdk::Util
4
4
  class TinycacheAdapter
5
+ extend MatrixSdk::Extensions
6
+
5
7
  attr_accessor :config, :client
6
8
 
9
+ ignore_inspect :client
10
+
7
11
  def initialize
8
12
  @config = {}
9
13
 
@@ -59,7 +63,7 @@ module MatrixSdk::Util
59
63
  end
60
64
 
61
65
  def cleanup
62
- @cache.delete_if { |_, v| v.expired? }
66
+ @cache.select { |_, v| v.expired? }.each { |_, v| v.value = nil }
63
67
  end
64
68
 
65
69
  private
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MatrixSdk
4
- VERSION = '2.6.0'
4
+ VERSION = '2.7.0'
5
5
  end
data/lib/matrix_sdk.rb CHANGED
@@ -10,7 +10,7 @@ autoload :Logging, 'logging'
10
10
 
11
11
  module MatrixSdk
12
12
  autoload :Api, 'matrix_sdk/api'
13
- autoload :ApplicationService, 'matrix_sdk/application_service'
13
+ # autoload :ApplicationService, 'matrix_sdk/application_service'
14
14
  autoload :Client, 'matrix_sdk/client'
15
15
  autoload :MXID, 'matrix_sdk/mxid'
16
16
  autoload :Response, 'matrix_sdk/response'
@@ -28,11 +28,16 @@ module MatrixSdk
28
28
  autoload :MatrixTimeoutError, 'matrix_sdk/errors'
29
29
  autoload :MatrixUnexpectedResponseError, 'matrix_sdk/errors'
30
30
 
31
+ module Bot
32
+ autoload :Base, 'matrix_sdk/bot/base'
33
+ end
34
+
31
35
  module Rooms
32
36
  autoload :Space, 'matrix_sdk/rooms/space'
33
37
  end
34
38
 
35
39
  module Util
40
+ autoload :AccountDataCache, 'matrix_sdk/util/account_data_cache'
36
41
  autoload :Tinycache, 'matrix_sdk/util/tinycache'
37
42
  autoload :TinycacheAdapter, 'matrix_sdk/util/tinycache_adapter'
38
43
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: matrix_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.0
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Olofsson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-15 00:00:00.000000000 Z
11
+ date: 2022-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mocha
@@ -95,6 +95,9 @@ files:
95
95
  - README.md
96
96
  - lib/matrix_sdk.rb
97
97
  - lib/matrix_sdk/api.rb
98
+ - lib/matrix_sdk/bot.rb
99
+ - lib/matrix_sdk/bot/base.rb
100
+ - lib/matrix_sdk/bot/main.rb
98
101
  - lib/matrix_sdk/client.rb
99
102
  - lib/matrix_sdk/errors.rb
100
103
  - lib/matrix_sdk/mxid.rb
@@ -107,6 +110,7 @@ files:
107
110
  - lib/matrix_sdk/room.rb
108
111
  - lib/matrix_sdk/rooms/space.rb
109
112
  - lib/matrix_sdk/user.rb
113
+ - lib/matrix_sdk/util/account_data_cache.rb
110
114
  - lib/matrix_sdk/util/events.rb
111
115
  - lib/matrix_sdk/util/extensions.rb
112
116
  - lib/matrix_sdk/util/tinycache.rb