Class: MatrixSdk::Room

Inherits:
Object show all
Extended by:
Extensions, Util::Tinycache
Includes:
Logging
Defined in:
lib/matrix_sdk/room.rb

Overview

A class for tracking the information about a room on Matrix

Direct Known Subclasses

MatrixSdk::Rooms::Space

Constant Summary

Constants included from Util::Tinycache

Util::Tinycache::CACHE_LEVELS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Extensions

ignore_inspect

Methods included from Util::Tinycache

adapter, adapter=, cached, extended, tinycache_adapter_config

Methods included from Logging

#logger, #logger=

Constructor Details

#initialize(client, room_id, data = {}) ⇒ Room

Note:

This method isn’t supposed to be used directly, rather rooms should be retrieved from the Client abstraction.

Create a new room instance

Parameters:

  • client (Client)

    The underlying connection

  • room_id (MXID)

    The room ID

  • data (Hash) (defaults to: {})

    Additional data to assign to the room

Options Hash (data):

  • :name (String)

    The current name of the room

  • :topic (String)

    The current topic of the room

  • :canonical_alias (String, MXID)

    The canonical alias of the room

  • :aliases (Array(String, MXID))

    All non-canonical aliases of the room

  • :join_rule (:invite, :public, :knock)

    The join rule for the room

  • :guest_access (:can_join, :forbidden)

    The guest access setting for the room

  • :world_readable (Boolean)

    If the room is readable by the entire world

  • :members (Array(User))

    The list of joined members

  • :events (Array(Object))

    The list of current events in the room

  • :members_loaded (Boolean)

    If the list of members is already loaded

  • :event_history_limit (Integer) — default: 10

    The limit of events to store for the room

  • :avatar_url (String, URI)

    The avatar URL for the room

  • :prev_batch (String)

    The previous batch token for backfill

Raises:

  • (ArgumentError)


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/matrix_sdk/room.rb', line 64

def initialize(client, room_id, data = {})
  if client.is_a? Room
    copy = client
    client = copy.client
    room_id = copy.id
    # data = copy.attributes
  end

  raise ArgumentError, 'Must be given a Client instance' unless client.is_a? Client

  @client = client
  room_id = MXID.new room_id unless room_id.is_a?(MXID)
  raise ArgumentError, 'room_id must be a valid Room ID' unless room_id.room_id?

  @events = []
  @event_history_limit = 10
  @room_type = nil

  @prev_batch = nil

  %i[name topic canonical_alias avatar_url].each do |type|
    room_state.tinycache_adapter.write("m.room.#{type}", { type => data.delete(type) }) if data.key? type
  end
  room_state.tinycache_adapter.write('m.room.join_rules', { join_rule: data.delete(:join_rule) }) if data.key? :join_rule
  room_state.tinycache_adapter.write('m.room.history_visibility', { history_visibility: data.delete(:world_readable) ? :world_readable : nil }) if data.key? :world_readable

  data.each do |k, v|
    next if %i[client].include? k

    if respond_to?("#{k}_cached?".to_sym) && send("#{k}_cached?".to_sym)
      tinycache_adapter.write(k, v)
    elsif instance_variable_defined? "@#{k}"
      instance_variable_set("@#{k}", v)
    end
  end

  @id = room_id.to_s

  logger.debug "Created room #{room_id}"
end

Instance Attribute Details

#clientClient (readonly)

Returns the client for the room.

Returns:

  • (Client)

    the client for the room



25
# File 'lib/matrix_sdk/room.rb', line 25

attr_reader :id, :client, :events

#event_history_limitFixnum

Returns the limit of events to keep in the event log.

Returns:

  • (Fixnum)

    the limit of events to keep in the event log



16
17
18
# File 'lib/matrix_sdk/room.rb', line 16

def event_history_limit
  @event_history_limit
end

#eventsObject (readonly)

Returns the value of attribute events.



25
# File 'lib/matrix_sdk/room.rb', line 25

attr_reader :id, :client, :events

#idString (readonly) Also known as: room_id

Returns the internal ID of the room.

Returns:

  • (String)

    the internal ID of the room



25
26
27
# File 'lib/matrix_sdk/room.rb', line 25

def id
  @id
end

#on_account_dataObject (readonly)



134
135
136
# File 'lib/matrix_sdk/room.rb', line 134

def 
  ensure_room_handlers[:account_data]
end

#on_ephemeral_eventObject (readonly)



146
147
148
# File 'lib/matrix_sdk/room.rb', line 146

def on_ephemeral_event
  ensure_room_handlers[:ephemeral_event]
end

#on_eventObject (readonly)



128
129
130
# File 'lib/matrix_sdk/room.rb', line 128

def on_event
  ensure_room_handlers[:event]
end

#on_state_eventObject (readonly)



140
141
142
# File 'lib/matrix_sdk/room.rb', line 140

def on_state_event
  ensure_room_handlers[:state_event]
end

Instance Method Details

#account_dataObject



574
575
576
577
578
# File 'lib/matrix_sdk/room.rb', line 574

def 
  return MatrixSdk::Util::AccountDataCache.new client, room: self if client.cache == :none

  @account_data ||= MatrixSdk::Util::AccountDataCache.new client, room: self
end

#add_alias(room_alias) ⇒ Boolean

Add an alias to the room

Returns:

  • (Boolean)

    if the addition was successful or not



740
741
742
743
744
# File 'lib/matrix_sdk/room.rb', line 740

def add_alias(room_alias)
  client.api.set_room_alias(id, room_alias)
  tinycache_adapter.read(:aliases) << room_alias if tinycache_adapter.exist?(:aliases)
  true
end

#add_tag(tag, **data) ⇒ Object

Add a tag to the room

Parameters:

  • tag (String)

    The tag to add

  • data (Hash)

    The data to assign to the tag



687
688
689
690
# File 'lib/matrix_sdk/room.rb', line 687

def add_tag(tag, **data)
  client.api.add_user_tag(client.mxid, id, tag, data)
  true
end

#admin!(user, level: 100) ⇒ Object

Make a user an admin in the room

Parameters:

  • user (User, MXID, String)

    The user to give admin privileges

  • level (Integer) (defaults to: 100)

    The power level to set the user to

Raises:

  • (ArgumentError)

See Also:



857
858
859
860
861
862
863
864
865
# File 'lib/matrix_sdk/room.rb', line 857

def admin!(user, level: 100)
  return true if admin?(user, target_level: level)

  user = user.id if user.is_a? User
  user = MXID.new(user.to_s) unless user.is_a? MXID
  raise ArgumentError, 'Must provide a valid user or MXID' unless user.user?

  modify_user_power_levels({ user.to_s.to_sym => level })
end

#admin?(user, target_level: 100) ⇒ Boolean

Check if a user is an admin in the room

Parameters:

  • user (User, MXID, String)

    The user to check for admin privileges

  • target_level (Integer) (defaults to: 100)

    The power level that’s to be considered as admin privileges

Returns:

  • (Boolean)

    If the requested user has a power level highe enough to be an admin

See Also:



845
846
847
848
849
850
# File 'lib/matrix_sdk/room.rb', line 845

def admin?(user, target_level: 100)
  level = user_powerlevel(user, use_default: false)
  return false unless level

  level >= target_level
end

#aliases(canonical_only: true) ⇒ Array[String]

Gets the room aliases

Parameters:

  • canonical_only (Boolean) (defaults to: true)

    Should the list of aliases only contain the canonical ones

Returns:

  • (Array[String])

    The assigned room aliases



329
330
331
332
333
334
335
# File 'lib/matrix_sdk/room.rb', line 329

def aliases(canonical_only: true)
  canonical = get_state('m.room.canonical_alias') rescue {}
  aliases = ([canonical[:alias]].compact + (canonical[:alt_aliases] || [])).uniq.sort
  return aliases if canonical_only

  (aliases + client.api.get_room_aliases(id).aliases).uniq.sort
end

#all_members(**params) ⇒ Array(User)

Note:

This will also count members who’ve knocked, been invited, have left, or have been banned.

Get all members (member events) in the room

Parameters:

  • params (Hash)

    Additional query parameters to pass to the room member listing - e.g. for filtering purposes.

Returns:

  • (Array(User))

    The complete list of members in the room, regardless of membership state



203
204
205
# File 'lib/matrix_sdk/room.rb', line 203

def all_members(**params)
  client.api.get_room_members(id, **params)[:chunk].map { |ch| client.get_user(ch[:state_key]) }
end

#allow_guests=(allow_guests) ⇒ Object

Sets if guests are allowed in the room

Parameters:

  • allow_guests (Boolean)

    If guests are allowed to join or not



776
777
778
779
# File 'lib/matrix_sdk/room.rb', line 776

def allow_guests=(allow_guests)
  self.guest_access = (allow_guests ? :can_join : :forbidden)
  allow_guests
end

#avatar_urlString?

Gets the avatar url of the room - if any

Returns:

  • (String, nil)

    The avatar URL - if any



248
249
250
251
252
253
# File 'lib/matrix_sdk/room.rb', line 248

def avatar_url
  get_state('m.room.avatar_url')[:url]
rescue MatrixNotFoundError
  # No avatar has been set
  nil
end

#avatar_url=(avatar_url) ⇒ Object

Sets a new avatar URL for the room

Parameters:

  • avatar_url (URI::MXC)

    The mxc:// URL for the new room avatar

Raises:

  • (ArgumentError)


792
793
794
795
796
797
798
# File 'lib/matrix_sdk/room.rb', line 792

def avatar_url=(avatar_url)
  avatar_url = URI(avatar_url) unless avatar_url.is_a? URI
  raise ArgumentError, 'Must be a valid MXC URL' unless avatar_url.is_a? URI::MXC

  room_state['m.room.avatar_url'] = { avatar_url: avatar_url }
  avatar_url
end

#backfill_messages(*args, reverse: false, limit: 10) ⇒ Object

Note:

This will trigger the ‘on_event` events as messages are added

Backfills messages into the room history

Parameters:

  • reverse (Boolean) (defaults to: false)

    whether to fill messages in reverse or not

  • limit (Integer) (defaults to: 10)

    the maximum number of messages to backfill



502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
# File 'lib/matrix_sdk/room.rb', line 502

def backfill_messages(*args, reverse: false, limit: 10)
  # To be backwards-compatible
  if args.length == 2
    reverse = args.first
    limit = args.last
  end

  data = client.api.get_room_messages(id, @prev_batch, direction: :b, limit: limit)

  events = data[:chunk]
  events.reverse! unless reverse
  events.each do |ev|
    put_event(ev)
  end
  true
end

#ban_user(user_id, reason = '') ⇒ Boolean

Bans a user from the room

Parameters:

  • user_id (String, User)

    the MXID of the user

  • reason (String) (defaults to: '')

    the reason for the ban

Returns:

  • (Boolean)

    wether the action succeeded



549
550
551
552
553
# File 'lib/matrix_sdk/room.rb', line 549

def ban_user(user_id, reason = '')
  user_id = user_id.id if user_id.is_a? MatrixSdk::User
  client.api.ban_user(id, user_id, reason: reason)
  true
end

#canonical_aliasString?

Returns the canonical alias of the room.

Returns:

  • (String, nil)

    the canonical alias of the room



179
180
181
182
183
# File 'lib/matrix_sdk/room.rb', line 179

def canonical_alias
  get_state('m.room.canonical_alias')[:alias]
rescue MatrixSdk::MatrixNotFoundError
  nil
end

#creation_infoResponse

Gets the room creation information

Returns:

  • (Response)

    The content of the m.room.create event



618
619
620
# File 'lib/matrix_sdk/room.rb', line 618

def creation_info
  room_state['m.room.create']
end

#display_nameString

Note:

This method will populate the #members list if it has to fall back to the member name generation.

Gets a human-readable name for the room

This will return #name or #canonical_alias if they’ve been set, otherwise it will query the API for members and generate a string from a subset of their names.

Returns:

  • (String)

    a human-readable name for the room



163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/matrix_sdk/room.rb', line 163

def display_name
  return name if name
  return canonical_alias if canonical_alias

  members = joined_members
            .reject { |m| m.user_id == client.mxid }
            .map(&:display_name)

  return members.first if members.one?
  return "#{members.first} and #{members.last}" if members.count == 2
  return "#{members.first} and #{members.count - 1} others" if members.count > 2

  'Empty Room'
end

#dm=(direct) ⇒ Object

Mark a room as a direct (1:1) message Room



230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/matrix_sdk/room.rb', line 230

def dm=(direct)
  rooms = client.direct_rooms
  dirty = false
  list_for_room = (rooms[id.to_s] ||= [])
  if direct && !list_for_room.include?(id.to_s)
    list_for_room << id.to_s
    dirty = true
  elsif !direct && list_for_room.include?(id.to_s)
    list_for_room.delete id.to_s
    rooms.delete id.to_s if list_for_room.empty?
    dirty = true
  end
  client.['m.direct'] = rooms if dirty
end

#dm?(members_only: false) ⇒ Boolean

Checks if the room is a direct message / 1:1 room

Parameters:

  • members_only (Boolean) (defaults to: false)

    Should directness only care about member count?

Returns:

  • (Boolean)


223
224
225
226
227
# File 'lib/matrix_sdk/room.rb', line 223

def dm?(members_only: false)
  return true if !members_only && client.direct_rooms.any? { |_uid, rooms| rooms.include? id.to_s }

  joined_members.count <= 2
end

#get_account_data(type) ⇒ Hash

Retrieves a custom entry from the room-specific account data

Parameters:

  • type (String)

    the data type to retrieve

Returns:

  • (Hash)

    the data that was stored under the given type



584
585
586
# File 'lib/matrix_sdk/room.rb', line 584

def (type)
  [type]
end

#get_state(type, state_key: nil) ⇒ Object

Gets a state object in the room



301
302
303
# File 'lib/matrix_sdk/room.rb', line 301

def get_state(type, state_key: nil)
  room_state[type, state_key]
end

#guest_access:can_join, :forbidden

Gets the guest access rights for the room

Returns:

  • (:can_join, :forbidden)

    The current guest access right



268
269
270
# File 'lib/matrix_sdk/room.rb', line 268

def guest_access
  get_state('m.room.guest_access')[:guest_access]&.to_sym
end

#guest_access=(guest_access) ⇒ Object

Sets the guest access status for the room

Parameters:

  • guest_access (:can_join, :forbidden)

    The new guest access status of the room



784
785
786
787
# File 'lib/matrix_sdk/room.rb', line 784

def guest_access=(guest_access)
  room_state['m.room.guest_access'] = { guest_access: guest_access }
  guest_access
end

#guest_access?Boolean

Checks if guest_access is set to :can_join

Returns:

  • (Boolean)


280
281
282
# File 'lib/matrix_sdk/room.rb', line 280

def guest_access?
  guest_access == :can_join
end

#history_visibility:invited, ...

Gets the history visibility of the room

Returns:

  • (:invited, :joined, :shared, :world_readable)

    The current history visibility for the room



313
314
315
# File 'lib/matrix_sdk/room.rb', line 313

def history_visibility
  get_state('m.room.history_visibility')[:history_visibility]&.to_sym
end

#inspectString

An inspect method that skips a handful of instance variables to avoid flooding the terminal with debug data.

Returns:

  • (String)

    a regular inspect string without the data for some variables



31
# File 'lib/matrix_sdk/room.rb', line 31

ignore_inspect :client, :events, :prev_batch, :logger, :tinycache_adapter

#invite_only=(invite_only) ⇒ Object

Sets if the room should be invite only or not

Parameters:

  • invite_only (Boolean)

    If it should be invite only or not



760
761
762
763
# File 'lib/matrix_sdk/room.rb', line 760

def invite_only=(invite_only)
  self.join_rule = invite_only ? :invite : :public
  invite_only
end

#invite_only?Boolean

Checks if join_rule is set to :invite

Returns:

  • (Boolean)


285
286
287
# File 'lib/matrix_sdk/room.rb', line 285

def invite_only?
  join_rule == :invite
end

#invite_user(user_id) ⇒ Boolean

Invites a user into the room

Parameters:

  • user_id (String, User)

    the MXID of the user

Returns:

  • (Boolean)

    wether the action succeeded



527
528
529
530
531
# File 'lib/matrix_sdk/room.rb', line 527

def invite_user(user_id)
  user_id = user_id.id if user_id.is_a? MatrixSdk::User
  client.api.invite_user(id, user_id)
  true
end

#join_rule:public, ...

Gets the join rule for the room

Returns:

  • (:public, :knock, :invite, :private)

    The current join rule



275
276
277
# File 'lib/matrix_sdk/room.rb', line 275

def join_rule
  get_state('m.room.join_rules')[:join_rule]&.to_sym
end

#join_rule=(join_rule) ⇒ Object

Sets the join rule of the room

Parameters:

  • join_rule (:invite, :public)

    The join rule of the room



768
769
770
771
# File 'lib/matrix_sdk/room.rb', line 768

def join_rule=(join_rule)
  room_state['m.room.join_rules'] = { join_rule: join_rule }
  join_rule
end

#joined_membersArray(User)

Populates and returns the #members array

Returns:

  • (Array(User))

    The list of members in the room



188
189
190
191
192
193
194
# File 'lib/matrix_sdk/room.rb', line 188

def joined_members
  client.api.get_room_joined_members(id)[:joined].map do |mxid, data|
    User.new(client, mxid.to_s,
             display_name: data.fetch(:display_name, nil),
             avatar_url: data.fetch(:avatar_url, nil))
  end
end

#kick_user(user_id, reason = '') ⇒ Boolean

Kicks a user from the room

Parameters:

  • user_id (String, User)

    the MXID of the user

  • reason (String) (defaults to: '')

    the reason for the kick

Returns:

  • (Boolean)

    wether the action succeeded



538
539
540
541
542
# File 'lib/matrix_sdk/room.rb', line 538

def kick_user(user_id, reason = '')
  user_id = user_id.id if user_id.is_a? MatrixSdk::User
  client.api.kick_user(id, user_id, reason: reason)
  true
end

#knock_only?Boolean

Checks if join_rule is set to :knock

Returns:

  • (Boolean)


290
291
292
# File 'lib/matrix_sdk/room.rb', line 290

def knock_only?
  join_rule == :knock
end

#leaveBoolean

Requests to be removed from the room

Returns:

  • (Boolean)

    wether the request succeeded



568
569
570
571
572
# File 'lib/matrix_sdk/room.rb', line 568

def leave
  client.api.leave_room(id)
  client.instance_variable_get(:@rooms).delete id
  true
end

#membersObject



41
# File 'lib/matrix_sdk/room.rb', line 41

alias members joined_members

#moderator!(user, level: 50) ⇒ Object

Make a user a moderator in the room

Parameters:

  • user (User, MXID, String)

    The user to give moderator privileges

  • level (Integer) (defaults to: 50)

    The power level to set the user to

Raises:

  • (ArgumentError)

See Also:



885
886
887
888
889
890
891
892
893
# File 'lib/matrix_sdk/room.rb', line 885

def moderator!(user, level: 50)
  return true if moderator?(user, target_level: level)

  user = user.id if user.is_a? User
  user = MXID.new(user.to_s) unless user.is_a? MXID
  raise ArgumentError, 'Must provide a valid user or MXID' unless user.user?

  modify_user_power_levels({ user.to_s.to_sym => level })
end

#moderator?(user, target_level: 50) ⇒ Boolean

Check if a user is a moderator in the room

Parameters:

  • user (User, MXID, String)

    The user to check for admin privileges

  • target_level (Integer) (defaults to: 50)

    The power level that’s to be considered as admin privileges

Returns:

  • (Boolean)

    If the requested user has a power level highe enough to be an admin

See Also:



873
874
875
876
877
878
# File 'lib/matrix_sdk/room.rb', line 873

def moderator?(user, target_level: 50)
  level = user_powerlevel(user, use_default: false)
  return false unless level

  level >= target_level
end

#modify_required_power_levels(events = nil, params = {}) ⇒ Boolean

Modifies the required power levels for actions in the room

Parameters:

  • events (Hash) (defaults to: nil)

    the event-specific power levels to change

  • params (Hash) (defaults to: {})

    other power-level params to change

Returns:

  • (Boolean)

    if the change was successful



932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
# File 'lib/matrix_sdk/room.rb', line 932

def modify_required_power_levels(events = nil, params = {})
  return false if events.nil? && (params.nil? || params.empty?)

  room_state.tinycache_adapter.expire 'm.room.power_levels'

  data = power_levels
  data.merge!(params)
  data.delete_if { |_k, v| v.nil? }

  if events
    data[:events] = {} unless data.key? :events
    data[:events].merge!(events)
    data[:events].delete_if { |_k, v| v.nil? }
  end

  room_state['m.room.power_levels'] = data
  true
end

#modify_user_power_levels(users = nil, users_default = nil) ⇒ Boolean

Modifies the power levels of the room

Parameters:

  • users (Hash) (defaults to: nil)

    the user-specific power levels to set or remove

  • users_default (Hash) (defaults to: nil)

    the default user power levels to set

Returns:

  • (Boolean)

    if the change was successful



900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
# File 'lib/matrix_sdk/room.rb', line 900

def modify_user_power_levels(users = nil, users_default = nil)
  return false if users.nil? && users_default.nil?

  room_state.tinycache_adapter.expire 'm.room.power_levels'

  data = power_levels
  data[:users_default] = users_default unless users_default.nil?

  if users
    data[:users] = {} unless data.key? :users
    users.each do |user, level|
      user = user.id if user.is_a? User
      user = MXID.new(user.to_s) unless user.is_a? MXID
      raise ArgumentError, 'Must provide a valid user or MXID' unless user.user?

      if level.nil?
        data[:users].delete(user.to_s.to_sym)
      else
        data[:users][user.to_s.to_sym] = level
      end
    end
  end

  room_state['m.room.power_levels'] = data
  true
end

#nameString?

Note:

Will cache the current name for 15 minutes

Gets the current name of the room, querying the API if necessary

Returns:

  • (String, nil)

    The room name - if any



212
213
214
215
216
217
# File 'lib/matrix_sdk/room.rb', line 212

def name
  get_state('m.room.name')[:name]
rescue MatrixNotFoundError
  # No room name has been specified
  nil
end

#name=(name) ⇒ Object

Sets a new name on the room

Parameters:

  • name (String)

    The new name to set



708
709
710
711
# File 'lib/matrix_sdk/room.rb', line 708

def name=(name)
  room_state['m.room.name'] = { name: name }
  name
end

#power_levelsHash

Note:

The returned power levels are cached for a minute

Get the power levels of the room

Returns:

  • (Hash)

    The current power levels as set for the room

See Also:



805
806
807
# File 'lib/matrix_sdk/room.rb', line 805

def power_levels
  get_state('m.room.power_levels')
end

#redact_message(event_id, reason = nil) ⇒ Object

Redacts a message from the room

Parameters:

  • event_id (String)

    the ID of the event to redact

  • reason (String, nil) (defaults to: nil)

    the reason for the redaction



482
483
484
485
# File 'lib/matrix_sdk/room.rb', line 482

def redact_message(event_id, reason = nil)
  client.api.redact_event(id, event_id, reason: reason)
  true
end

#reload!Object Also known as: refresh!

Refreshes the room state caches for name, topic, and aliases



697
698
699
700
701
702
# File 'lib/matrix_sdk/room.rb', line 697

def reload!
  reload_name!
  reload_topic!
  reload_aliases!
  true
end

#reload_aliases!Boolean Also known as: refresh_aliases!

Note:

The list of aliases is not sorted, ordering changes will result in alias list updates.

Reloads the list of aliases by an API query

Returns:

  • (Boolean)

    if the alias list was updated or not



751
752
753
754
# File 'lib/matrix_sdk/room.rb', line 751

def reload_aliases!
  room_state.expire('m.room.canonical_alias')
  clear_aliases_cache
end

#reload_name!Boolean Also known as: refresh_name!

Reloads the name of the room

Returns:

  • (Boolean)

    if the name was changed or not



716
717
718
# File 'lib/matrix_sdk/room.rb', line 716

def reload_name!
  room_state.expire('m.room.name')
end

#reload_topic!Boolean Also known as: refresh_topic!

Reloads the topic of the room

Returns:

  • (Boolean)

    if the topic was changed or not



732
733
734
# File 'lib/matrix_sdk/room.rb', line 732

def reload_topic!
  room_state.expire('m.room.topic')
end

#remove_tag(tag) ⇒ Object

Remove a tag from the room

Parameters:

  • tag (String)

    The tag to remove



678
679
680
681
# File 'lib/matrix_sdk/room.rb', line 678

def remove_tag(tag)
  client.api.remove_user_tag(client.mxid, id, tag)
  true
end

#report_message(event_id, reason:, score: -100)) ⇒ Object

Reports a message in the room

Parameters:

  • event_id (MXID, String)

    The ID of the event to redact

  • reason (String)

    The reason for the report

  • score (Integer) (defaults to: -100))

    The severity of the report in the range of -100 - 0



492
493
494
495
# File 'lib/matrix_sdk/room.rb', line 492

def report_message(event_id, reason:, score: -100)
  client.api.report_event(id, event_id, reason: reason, score: score)
  true
end

#room_stateObject



294
295
296
297
298
# File 'lib/matrix_sdk/room.rb', line 294

def room_state
  return MatrixSdk::Util::StateEventCache.new self if client.cache == :none

  @room_state ||= MatrixSdk::Util::StateEventCache.new self
end

#room_type'm.space', ...

Retrieves the type of the room

Returns:

  • ('m.space', String, nil)

    The type of the room



625
626
627
628
# File 'lib/matrix_sdk/room.rb', line 625

def room_type
  # Can't change, so a permanent cache is ok
  @room_type ||= creation_info[:type]
end

#room_versionString

Retrieves the room version

Returns:

  • (String)

    The version of the room



633
634
635
636
# File 'lib/matrix_sdk/room.rb', line 633

def room_version
  # Can't change, so a permanent cache is ok
  @room_version ||= creation_info[:room_version]
end

#send_audio(url, name, audio_info = {}) ⇒ Object

Note:

The URLs should all be of the ‘mxc://’ schema

Sends a link to an audio clip to the room

Parameters:

  • url (String, URI)

    the URL to the audio clip

  • name (String)

    the name of the audio clip

  • audio_info (Hash) (defaults to: {})

    extra information about the audio clip

Options Hash (audio_info):

  • :duration (Integer)

    the duration of the audio clip in milliseconds

  • :mimetype (String)

    the MIME type of the audio clip

  • :size (Integer)

    the size of the audio clip in bytes



449
450
451
# File 'lib/matrix_sdk/room.rb', line 449

def send_audio(url, name, audio_info = {})
  client.api.send_content(id, url, name, 'm.audio', extra_information: audio_info)
end

#send_custom_message(body, content = {}, msgtype: nil) ⇒ Object

Sends a customized message to the Room

Parameters:

  • body (String)

    The clear-text body of the message

  • content (Hash) (defaults to: {})

    The custom content of the message

  • msgtype (String) (defaults to: nil)

    The type of the message, should be one of the known types (m.text, m.notice, m.emote, etc)



458
459
460
461
462
463
464
465
# File 'lib/matrix_sdk/room.rb', line 458

def send_custom_message(body, content = {}, msgtype: nil)
  content.merge!(
    body: body,
    msgtype: msgtype || 'm.text'
  )

  client.api.send_message_event(id, 'm.room.message', content)
end

#send_emote(text) ⇒ Object

Sends an emote (/me) message to the room

Parameters:

  • text (String)

    the emote to send



371
372
373
# File 'lib/matrix_sdk/room.rb', line 371

def send_emote(text)
  client.api.send_emote(id, text)
end

#send_event(type, content = {}) ⇒ Object

Sends a custom timeline event to the Room

Parameters:

  • type (String, Symbol)

    The type of the Event. For custom events, this should be written in reverse DNS format (e.g. com.example.event)

  • content (Hash) (defaults to: {})

    The contents of the message, this will be the :content key of the resulting event object

See Also:



474
475
476
# File 'lib/matrix_sdk/room.rb', line 474

def send_event(type, content = {})
  client.api.send_message_event(id, type, content)
end

#send_file(url, name, file_info = {}) ⇒ Object

Note:

The URLs should all be of the ‘mxc://’ schema

Sends a link to a generic file to the room

Parameters:

  • url (String, URI)

    the URL to the file

  • name (String)

    the name of the file

  • file_info (Hash) (defaults to: {})

    extra information about the file

Options Hash (file_info):

  • :mimetype (String)

    the MIME type of the file

  • :size (Integer)

    the size of the file in bytes

  • :thumbnail_url (String, URI)

    the URL to a thumbnail of the file

  • :thumbnail_info (Hash)

    ThumbnailInfo about the thumbnail file



385
386
387
# File 'lib/matrix_sdk/room.rb', line 385

def send_file(url, name, file_info = {})
  client.api.send_content(id, url, name, 'm.file', extra_information: file_info)
end

#send_html(html, body = nil, msgtype: nil, format: nil) ⇒ Object

Sends a custom HTML message to the room

Parameters:

  • html (String)

    the HTML message to send

  • body (String, nil) (defaults to: nil)

    a plain-text representation of the object (Will default to the HTML with all tags stripped away)

  • msgtype (String) (defaults to: nil)

    (‘m.text’) The message type for the message

  • format (String) (defaults to: nil)

    (‘org.matrix.custom.html’) The message format

See Also:



357
358
359
360
361
362
363
364
365
366
# File 'lib/matrix_sdk/room.rb', line 357

def send_html(html, body = nil, msgtype: nil, format: nil)
  content = {
    body: body || html.gsub(/<\/?[^>]*>/, ''),
    msgtype: msgtype || 'm.text',
    format: format || 'org.matrix.custom.html',
    formatted_body: html
  }

  client.api.send_message_event(id, 'm.room.message', content)
end

#send_image(url, name, image_info = {}) ⇒ Object

Note:

The URLs should all be of the ‘mxc://’ schema

Sends a link to an image to the room

Parameters:

  • url (String, URI)

    the URL to the image

  • name (String)

    the name of the image

  • image_info (Hash) (defaults to: {})

    extra information about the image

Options Hash (image_info):

  • :h (Integer)

    the height of the image in pixels

  • :w (Integer)

    the width of the image in pixels

  • :mimetype (String)

    the MIME type of the image

  • :size (Integer)

    the size of the image in bytes

  • :thumbnail_url (String, URI)

    the URL to a thumbnail of the image

  • :thumbnail_info (Hash)

    ThumbnailInfo about the thumbnail image



408
409
410
# File 'lib/matrix_sdk/room.rb', line 408

def send_image(url, name, image_info = {})
  client.api.send_content(id, url, name, 'm.image', extra_information: image_info)
end

#send_location(geo_uri, name, thumbnail_url = nil, thumbnail_info = {}) ⇒ Object

Note:

The thumbnail URL should be of the ‘mxc://’ schema

Sends a location object to the room

Parameters:

  • geo_uri (String, URI)

    the geo-URL (e.g. geo:<coords>) of the location

  • name (String)

    the name of the location

  • thumbnail_url (String, URI) (defaults to: nil)

    the URL to a thumbnail image of the location

  • thumbnail_info (Hash) (defaults to: {})

    a ThumbnailInfo for the location thumbnail



419
420
421
# File 'lib/matrix_sdk/room.rb', line 419

def send_location(geo_uri, name, thumbnail_url = nil, thumbnail_info = {})
  client.api.send_location(id, geo_uri, name, thumbnail_url: thumbnail_url, thumbnail_info: thumbnail_info)
end

#send_notice(text) ⇒ Object

Sends a notice (bot) message to the room

Parameters:

  • text (String)

    the notice to send



392
393
394
# File 'lib/matrix_sdk/room.rb', line 392

def send_notice(text)
  client.api.send_notice(id, text)
end

#send_text(text) ⇒ Object

Sends a plain-text message to the room

Parameters:

  • text (String)

    the message to send



344
345
346
# File 'lib/matrix_sdk/room.rb', line 344

def send_text(text)
  client.api.send_message(id, text)
end

#send_video(url, name, video_info = {}) ⇒ Object

Note:

The URLs should all be of the ‘mxc://’ schema

Sends a link to a video to the room

Parameters:

  • url (String, URI)

    the URL to the video

  • name (String)

    the name of the video

  • video_info (Hash) (defaults to: {})

    extra information about the video

Options Hash (video_info):

  • :duration (Integer)

    the duration of the video in milliseconds

  • :h (Integer)

    the height of the video in pixels

  • :w (Integer)

    the width of the video in pixels

  • :mimetype (String)

    the MIME type of the video

  • :size (Integer)

    the size of the video in bytes

  • :thumbnail_url (String, URI)

    the URL to a thumbnail of the video

  • :thumbnail_info (Hash)

    ThumbnailInfo about the thumbnail of the video



436
437
438
# File 'lib/matrix_sdk/room.rb', line 436

def send_video(url, name, video_info = {})
  client.api.send_content(id, url, name, 'm.video', extra_information: video_info)
end

#set_account_data(type, account_data) ⇒ Object

Stores a custom entry into the room-specific account data

Parameters:

  • type (String)

    the data type to store

  • account_data (Hash)

    the data to store



592
593
594
595
# File 'lib/matrix_sdk/room.rb', line 592

def (type, )
  self.[type] = 
  true
end

#set_state(type, data, state_key: nil) ⇒ Object

Sets a state object in the room



306
307
308
# File 'lib/matrix_sdk/room.rb', line 306

def set_state(type, data, state_key: nil)
  room_state[type, state_key] = data
end

#set_user_profile(display_name: nil, avatar_url: nil, reason: nil) ⇒ Object

Note:

the avatar URL should be a mxc:// URI

Changes the room-specific user profile

Parameters:

  • display_name (String) (defaults to: nil)

    the new display name to use in the room

  • avatar_url (String, URI) (defaults to: nil)

    the new avatar URL to use in the room



602
603
604
605
606
607
608
609
610
611
612
613
# File 'lib/matrix_sdk/room.rb', line 602

def (display_name: nil, avatar_url: nil, reason: nil)
  return nil unless display_name || avatar_url

  data = client.api.get_membership(id, client.mxid)
  raise "Can't set profile if you haven't joined the room" unless data[:membership] == 'join'

  data[:displayname] = display_name unless display_name.nil?
  data[:avatar_url] = avatar_url unless avatar_url.nil?

  client.api.set_membership(id, client.mxid, 'join', reason || 'Updating room profile information', data)
  true
end

#space?Boolean?

Checks if the room is a Matrix Space

Returns:

  • (Boolean, nil)

    True if the room is a space



641
642
643
644
645
# File 'lib/matrix_sdk/room.rb', line 641

def space?
  room_type == 'm.space'
rescue MatrixSdk::MatrixForbiddenError, MatrixSdk::MatrixNotFoundError
  nil
end

#tagsResponse

Returns a list of the room tags

Examples:

Managing tags

room.tags
# => { :room_tag => { data: false } }
room.tags.add('some_tag', data: true)
# => { :some_tag => { data: true }, :room_tag => { data: false} }
room.tags.remove('room_tag')
# => { :some_tag => { data: true} }

Returns:

  • (Response)

    A list of the tags and their data, with add and remove methods implemented



657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
# File 'lib/matrix_sdk/room.rb', line 657

def tags
  client.api.get_user_tags(client.mxid, id)[:tags].tap do |tag_obj|
    tag_obj.instance_variable_set(:@room, self)
    tag_obj.define_singleton_method(:room) do
      @room
    end
    tag_obj.define_singleton_method(:add) do |tag, **data|
      @room.add_tag(tag.to_s.to_sym, **data)
      self[tag.to_s.to_sym] = data
      self
    end
    tag_obj.define_singleton_method(:remove) do |tag|
      @room.remove_tag(tag.to_s.to_sym)
      delete tag.to_s.to_sym
    end
  end
end

#to_sObject



115
116
117
118
119
120
# File 'lib/matrix_sdk/room.rb', line 115

def to_s
  prefix = canonical_alias || id
  return "#{prefix} | #{name}" unless name.nil?

  prefix
end

#to_spaceObject

Casting operators



109
110
111
112
113
# File 'lib/matrix_sdk/room.rb', line 109

def to_space
  return nil unless space?

  Rooms::Space.new self, nil
end

#topicString?

Gets the room topic - if any

Returns:

  • (String, nil)

    The topic of the room



258
259
260
261
262
263
# File 'lib/matrix_sdk/room.rb', line 258

def topic
  get_state('m.room.topic')[:topic]
rescue MatrixNotFoundError
  # No room name has been specified
  nil
end

#topic=(topic) ⇒ Object

Sets a new topic on the room

Parameters:

  • topic (String)

    The new topic to set



724
725
726
727
# File 'lib/matrix_sdk/room.rb', line 724

def topic=(topic)
  room_state['m.room.topic'] = { topic: topic }
  topic
end

#unban_user(user_id) ⇒ Boolean

Unbans a user from the room

Parameters:

  • user_id (String, User)

    the MXID of the user

Returns:

  • (Boolean)

    wether the action succeeded



559
560
561
562
563
# File 'lib/matrix_sdk/room.rb', line 559

def unban_user(user_id)
  user_id = user_id.id if user_id.is_a? MatrixSdk::User
  client.api.unban_user(id, user_id)
  true
end

#user_can_send?(user, event, state: false) ⇒ Boolean

Checks if a user can send a given event type in the room

Parameters:

  • user (User, MXID, String)

    The user to check

  • event (String, Symbol)

    The event type to check

  • state (Boolean) (defaults to: false)

    If the given event is a state event or a message event

Returns:

  • (Boolean)

    If the given user is allowed to send an event of the given type



831
832
833
834
835
836
837
# File 'lib/matrix_sdk/room.rb', line 831

def user_can_send?(user, event, state: false)
  user_pl = user_powerlevel(user)
  event_pl = power_levels.dig(:events, event.to_s.to_sym)
  event_pl ||= state ? (power_levels[:state_default] || 50) : (power_levels[:events_default] || 0)

  user_pl >= event_pl
end

#user_powerlevel(user, use_default: true) ⇒ Integer?

Gets the power level of a user in the room

Parameters:

  • user (User, MXID, String)

    The user to check the power level for

  • use_default (Boolean) (defaults to: true)

    Should the user default level be checked if no user-specific one exists

Returns:

  • (Integer, nil)

    The current power level for the requested user, nil if there’s no user specific level and use_default is false

Raises:

  • (ArgumentError)


815
816
817
818
819
820
821
822
823
# File 'lib/matrix_sdk/room.rb', line 815

def user_powerlevel(user, use_default: true)
  user = user.id if user.is_a? User
  user = MXID.new(user.to_s) unless user.is_a? MXID
  raise ArgumentError, 'Must provide a valid User or MXID' unless user.user?

  level = power_levels.dig(:users, user.to_s.to_sym)
  level ||= power_levels[:users_default] || 0 if use_default
  level
end

#world_readable?Boolean Also known as: world_readable

Checks if the room history is world readable

Returns:

  • (Boolean)

    If the history is world readable



320
321
322
# File 'lib/matrix_sdk/room.rb', line 320

def world_readable?
  history_visibility == :world_readable
end