Class: MatrixSdk::Room

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

Overview

A class for tracking the information about a room on Matrix

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Extensions

ignore_inspect

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

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)

    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)


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
104
105
# File 'lib/matrix_sdk/room.rb', line 74

def initialize(client, room_id, data = {})
  raise ArgumentError, 'Must be given a Client instance' unless client.is_a? 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?

  @name = nil
  @topic = nil
  @canonical_alias = nil
  @aliases = []
  @join_rule = nil
  @guest_access = nil
  @world_readable = nil
  @members = []
  @events = []
  @members_loaded = false
  @event_history_limit = 10
  @avatar_url = nil

  @prev_batch = nil

  data.each do |k, v|
    instance_variable_set("@#{k}", v) if instance_variable_defined? "@#{k}"
  end

  @client = client
  @id = room_id.to_s

  @name_checked = Time.new(0)

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

Instance Attribute Details

#aliasesArray(String) (readonly)

Returns a list of user-set aliases for the room.

See Also:



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

attr_reader :id, :client, :topic, :aliases, :members, :events

#canonical_aliasString?



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

def canonical_alias
  @canonical_alias
end

#clientClient (readonly)



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

attr_reader :id, :client, :topic, :aliases, :members, :events

#event_history_limitFixnum



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

attr_accessor :canonical_alias, :event_history_limit

#eventsObject (readonly)

Returns the value of attribute events.



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

attr_reader :id, :client, :topic, :aliases, :members, :events

#guest_access:can_join, :forbidden



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

attr_reader :id, :client, :topic, :aliases, :members, :events

#idString (readonly) Also known as: room_id



43
44
45
# File 'lib/matrix_sdk/room.rb', line 43

def id
  @id
end

#join_rule:invite, :public



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

attr_reader :id, :client, :topic, :aliases, :members, :events

#membersArray(User) (readonly)

Returns the members of the room.

See Also:

  • reload_members!


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

attr_reader :id, :client, :topic, :aliases, :members, :events

#nameString?

Note:

Will cache the current name for 15 minutes

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



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

attr_reader :id, :client, :topic, :aliases, :members, :events

#on_ephemeral_eventObject (readonly)



125
126
127
# File 'lib/matrix_sdk/room.rb', line 125

def on_ephemeral_event
  ensure_room_handlers[:ephemeral_event]
end

#on_eventObject (readonly)



113
114
115
# File 'lib/matrix_sdk/room.rb', line 113

def on_event
  ensure_room_handlers[:event]
end

#on_state_eventObject (readonly)



119
120
121
# File 'lib/matrix_sdk/room.rb', line 119

def on_state_event
  ensure_room_handlers[:state_event]
end

#topicString?

Returns the user-provided topic of the room.

See Also:



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

attr_reader :id, :client, :topic, :aliases, :members, :events

Instance Method Details

#add_alias(room_alias) ⇒ Boolean

Add an alias to the room



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

def add_alias(room_alias)
  client.api.set_room_alias(id, room_alias)
  @aliases << room_alias
  true
end

#add_tag(tag, **data) ⇒ Object

Add a tag to the room



507
508
509
510
# File 'lib/matrix_sdk/room.rb', line 507

def add_tag(tag, **data)
  client.api.add_user_tag(client.mxid, id, tag, data)
  true
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



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

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



623
624
625
626
# File 'lib/matrix_sdk/room.rb', line 623

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

#avatar_urlString?

Gets the avatar url of the room - if any



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

def avatar_url
  @avatar_url ||= client.api.get_room_avatar(id).url
rescue MatrixNotFoundError
  # No avatar has been set
  nil
end

#avatar_url=(avatar_url) ⇒ Object

Sets a new avatar URL for the room

Raises:

  • (ArgumentError)


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

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::MATRIX

  client.api.set_room_avatar(id, avatar_url)
  @avatar_url = avatar_url
end

#backfill_messages(reverse = false, limit = 10) ⇒ Object

Note:

This will trigger the on_event events as messages are added

Backfills messages into the room history



366
367
368
369
370
371
372
373
374
375
# File 'lib/matrix_sdk/room.rb', line 366

def backfill_messages(reverse = false, limit = 10) # rubocop:disable Style/OptionalBooleanParameter
  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



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

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

#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.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/matrix_sdk/room.rb', line 142

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

#get_account_data(type) ⇒ Hash

Retrieves a custom entry from the room-specific account data



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

def (type)
  client.api.(client.mxid, id, type)
end

#guest_access?Boolean

Checks if guest_access is set to :can_join



217
218
219
# File 'lib/matrix_sdk/room.rb', line 217

def guest_access?
  guest_access == :can_join
end

#inspectString

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



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

ignore_inspect :client, :members, :events, :prev_batch, :logger

#invite_only=(invite_only) ⇒ Object

Sets if the room should be invite only or not



607
608
609
610
# File 'lib/matrix_sdk/room.rb', line 607

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

#invite_only?Boolean

Checks if join_rule is set to :invite



222
223
224
# File 'lib/matrix_sdk/room.rb', line 222

def invite_only?
  join_rule == :invite
end

#invite_user(user_id) ⇒ Boolean

Invites a user into the room



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

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

#joined_membersArray(User)

Populates and returns the #members array



160
161
162
163
164
165
166
167
168
169
170
# File 'lib/matrix_sdk/room.rb', line 160

def joined_members
  return members if @members_loaded && !members.empty?

  client.api.get_room_joined_members(id)[:joined].each do |mxid, data|
    ensure_member(User.new(client, mxid.to_s,
                           display_name: data.fetch(:display_name, nil),
                           avatar_url: data.fetch(:avatar_url, nil)))
  end
  @members_loaded = true
  members
end

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

Kicks a user from the room



396
397
398
399
400
# File 'lib/matrix_sdk/room.rb', line 396

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

#leaveBoolean

Requests to be removed from the room



426
427
428
429
430
# File 'lib/matrix_sdk/room.rb', line 426

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

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

Modifies the required power levels for actions in the room



673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
# File 'lib/matrix_sdk/room.rb', line 673

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

  data = client.api.get_power_levels(id)
  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

  client.api.set_power_levels(id, data)
  true
end

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

Modifies the power levels of the room



652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
# File 'lib/matrix_sdk/room.rb', line 652

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

  data = client.api.get_power_levels(id)
  data[:users_default] = users_default unless users_default.nil?

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

  client.api.set_power_levels(id, data)
  true
end

#redact_message(event_id, reason = nil) ⇒ Object

Redacts a message from the room



346
347
348
349
# File 'lib/matrix_sdk/room.rb', line 346

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



517
518
519
520
521
522
# File 'lib/matrix_sdk/room.rb', line 517

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



585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
# File 'lib/matrix_sdk/room.rb', line 585

def reload_aliases!
  begin
    new_aliases = client.api.get_room_aliases(id).aliases
  rescue MatrixNotFoundError
    data = client.api.get_room_state_all(id)
    new_aliases = data.select { |chunk| chunk[:type] == 'm.room.aliases' && chunk.key?(:content) && chunk[:content].key?(:aliases) }
                      .map { |chunk| chunk[:content][:aliases] }
                      .flatten
                      .compact
  end

  return false if new_aliases.nil?

  changed = new_aliases != aliases
  @aliases = new_aliases if changed
  changed
end

#reload_name!Boolean Also known as: refresh_name!

Reloads the name of the room



536
537
538
539
540
541
542
543
544
545
# File 'lib/matrix_sdk/room.rb', line 536

def reload_name!
  data = begin
    client.api.get_room_name(id)
  rescue MatrixNotFoundError
    nil
  end
  changed = data[:name] != @name
  @name = data[:name] if changed
  changed
end

#reload_topic!Boolean Also known as: refresh_topic!

Reloads the topic of the room



559
560
561
562
563
564
565
566
567
568
# File 'lib/matrix_sdk/room.rb', line 559

def reload_topic!
  data = begin
    client.api.get_room_topic(id)
  rescue MatrixNotFoundError
    nil
  end
  changed = data[:topic] != @topic
  @topic = data[:topic] if changed
  changed
end

#remove_tag(tag) ⇒ Object

Remove a tag from the room



498
499
500
501
# File 'lib/matrix_sdk/room.rb', line 498

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



356
357
358
359
# File 'lib/matrix_sdk/room.rb', line 356

def report_message(event_id, reason:, score: -100)
  client.api.report_event(id, event_id, reason: reason, score: score)
  true
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

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



338
339
340
# File 'lib/matrix_sdk/room.rb', line 338

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

#send_emote(text) ⇒ Object

Sends an emote (/me) message to the room



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

def send_emote(text)
  client.api.send_emote(id, text)
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

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



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

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



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

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

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



297
298
299
# File 'lib/matrix_sdk/room.rb', line 297

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



308
309
310
# File 'lib/matrix_sdk/room.rb', line 308

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



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

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

#send_text(text) ⇒ Object

Sends a plain-text message to the room



233
234
235
# File 'lib/matrix_sdk/room.rb', line 233

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

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



325
326
327
# File 'lib/matrix_sdk/room.rb', line 325

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



444
445
446
447
# File 'lib/matrix_sdk/room.rb', line 444

def (type, )
  client.api.(client.mxid, id, type, )
  true
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



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

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

#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} }


477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
# File 'lib/matrix_sdk/room.rb', line 477

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

#unban_user(user_id) ⇒ Boolean

Unbans a user from the room



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

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