Class: MatrixSdk::Bot::Base
- Extended by:
- Extensions
- Defined in:
- lib/matrix_sdk/bot/base.rb
Direct Known Subclasses
Defined Under Namespace
Classes: RequestHandler
Constant Summary collapse
- CALLERS_TO_IGNORE =
[ /\/matrix_sdk\/.+\.rb$/, # all MatrixSdk code /^\(.*\)$/, # generated code /rubygems\/(custom|core_ext\/kernel)_require\.rb$/, # rubygems require hacks /bundler(\/(?:runtime|inline))?\.rb/, # bundler require hacks /<internal:/ # internal in ruby >= 1.9.2 ].freeze
- EMPTY_BOT_FILTER =
A filter that should only result in a valid sync token and no other data
{ account_data: { types: [] }, event_fields: [], presence: { types: [] }, room: { account_data: { types: [] }, ephemeral: { types: [] }, state: { types: [], lazy_load_members: true }, timeline: { types: [] } } }.freeze
Class Attribute Summary collapse
-
.handlers ⇒ Object
readonly
Returns the value of attribute handlers.
Instance Attribute Summary collapse
-
#client ⇒ Object
readonly
Returns the value of attribute client.
-
#event ⇒ Object
readonly
Returns the value of attribute event.
- #logger ⇒ Object
Class Method Summary collapse
-
.all_handlers(type: :command) ⇒ Array[RequestHandler]
Retrieves all registered - including inherited - handlers for the bot.
-
.client(&block) ⇒ Object
Registers a block to be run when configuring the client, before starting the sync.
-
.command(command, desc: nil, notes: nil, only: nil, **params, &block) ⇒ Object
Register a bot command.
-
.command?(command, ignore_inherited: false) ⇒ Boolean
Check if a command is registered.
-
.disable(*opts) ⇒ Object
Same as calling ‘set :option, false` for each of the given options.
-
.enable(*opts) ⇒ Object
Same as calling ‘set :option, true` for each of the given options.
-
.event(event, only: nil, **_params, &block) ⇒ Object
Register a Matrix event.
-
.event?(event, ignore_inherited: false) ⇒ Boolean
Check if an event is registered.
-
.get_command(command, ignore_inherited: false) ⇒ RequestHandler?
Retrieves the RequestHandler for a given command.
-
.get_event(event, ignore_inherited: false) ⇒ RequestHandler?
Retrieves the RequestHandler for a given event.
- .logger ⇒ Object
-
.quit! ⇒ Object
Stops any running instance of the bot.
-
.remove_command(command) ⇒ Object
Removes a registered command from the bot.
-
.remove_event(event) ⇒ Object
Removes a registered event from the bot.
-
.reset! ⇒ Object
Reset the bot class, removing any local handlers that have been registered.
-
.run!(options = {}, &block) ⇒ Object
Starts the bot up.
-
.running? ⇒ Boolean
Check whether the self-hosted server is running or not.
-
.set(option, value = (not_set = true), ignore_setter = false, &block) ⇒ Object
Set a class-wide option for the bot.
-
.settings ⇒ Object
Access settings defined with Base.set.
Instance Method Summary collapse
- #bot ⇒ Object
-
#command?(command, **params) ⇒ Boolean
Checks for the existence of a command.
- #command_allowed?(command, event) ⇒ Boolean
-
#event?(event, **params) ⇒ Boolean
Checks for the existence of a handled event.
- #event_allowed?(event) ⇒ Boolean
-
#expanded_prefix ⇒ Object
Helpers.
-
#get_command(command, **params) ⇒ RequestHandler
Gets the handler for a command.
-
#get_event(event, **params) ⇒ RequestHandler
Gets the handler for an event.
-
#in_event? ⇒ Boolean
Helpers for handling events.
-
#initialize(hs_url, **params) ⇒ Base
constructor
A new instance of Base.
-
#register_command(command, **params, &block) ⇒ Object
Register a command during runtime.
-
#register_event(event, **params, &block) ⇒ Object
Register an event during runtime.
- #room ⇒ Object
- #sender ⇒ Object
-
#sender_admin? ⇒ Boolean
Helpers for checking power levels.
- #sender_moderator? ⇒ Boolean
-
#settings ⇒ Object
Access settings defined with Base.set.
-
#unregister_command(command) ⇒ Object
Removes a registered command during runtime.
-
#unregister_event(command) ⇒ Object
Removes a registered event during runtime.
Methods included from Extensions
Constructor Details
#initialize(hs_url, **params) ⇒ Base
Returns a new instance of Base.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/matrix_sdk/bot/base.rb', line 30 def initialize(hs_url, **params) @client = case hs_url when MatrixSdk::Api MatrixSdk::Client.new hs_url when MatrixSdk::Client hs_url when %r{^https?://.*} MatrixSdk::Client.new hs_url, **params else MatrixSdk::Client.new_for_domain hs_url, **params end @client.on_event.add_handler { |ev| _handle_event(ev) } @client.on_invite_event.add_handler do |ev| break unless settings.accept_invites? logger.info "Received invite to #{ev[:room_id]}, joining." client.join_room(ev[:room_id]) end logger.warn 'The bot abstraction is not fully finalized and can be expected to change.' end |
Class Attribute Details
.handlers ⇒ Object (readonly)
Returns the value of attribute handlers.
145 146 147 |
# File 'lib/matrix_sdk/bot/base.rb', line 145 def handlers @handlers end |
Instance Attribute Details
#client ⇒ Object (readonly)
Returns the value of attribute client.
25 26 27 |
# File 'lib/matrix_sdk/bot/base.rb', line 25 def client @client end |
#event ⇒ Object (readonly)
Returns the value of attribute event.
25 26 27 |
# File 'lib/matrix_sdk/bot/base.rb', line 25 def event @event end |
#logger ⇒ Object
53 54 55 |
# File 'lib/matrix_sdk/bot/base.rb', line 53 def logger @logger || self.class.logger end |
Class Method Details
.all_handlers(type: :command) ⇒ Array[RequestHandler]
Retrieves all registered - including inherited - handlers for the bot
183 184 185 186 |
# File 'lib/matrix_sdk/bot/base.rb', line 183 def all_handlers(type: :command) parent = superclass&.all_handlers(type: type) if superclass.respond_to? :all_handlers (parent || {}).merge(@handlers.select { |_, h| type == :all || h.type == type }).compact end |
.client(&block) ⇒ Object
Registers a block to be run when configuring the client, before starting the sync
303 304 305 |
# File 'lib/matrix_sdk/bot/base.rb', line 303 def client(&block) @client_handler = block end |
.command(command, desc: nil, notes: nil, only: nil, **params, &block) ⇒ Object
Due to the way blocks are handled, required parameters won’t block execution. If your command requires all parameters to be valid, you will need to check for nil yourself.
Execution will be performed with a MatrixSdk::Bot::Request object as self. To access the bot instance, use MatrixSdk::Bot::Request#bot
Register a bot command
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/matrix_sdk/bot/base.rb', line 259 def command(command, desc: nil, notes: nil, only: nil, **params, &block) args = params[:args] || convert_to_lambda(&block).parameters.map do |type, name| case type when :req name.to_s.upcase when :opt "[#{name.to_s.upcase}]" when :rest "[#{name.to_s.upcase}...]" end end.compact.join(' ') logger.debug "Registering command #{command} with args #{args}" add_handler( command.to_s.downcase, type: :command, args: args, desc: desc, notes: notes, only: [only].flatten.compact, &block ) end |
.command?(command, ignore_inherited: false) ⇒ Boolean
Check if a command is registered
311 312 313 314 315 |
# File 'lib/matrix_sdk/bot/base.rb', line 311 def command?(command, ignore_inherited: false) return @handlers[command.to_s.downcase]&.command? if ignore_inherited all_handlers[command.to_s.downcase]&.command? || false end |
.disable(*opts) ⇒ Object
Same as calling ‘set :option, false` for each of the given options.
242 243 244 |
# File 'lib/matrix_sdk/bot/base.rb', line 242 def disable(*opts) opts.each { |key| set(key, false) } end |
.enable(*opts) ⇒ Object
Same as calling ‘set :option, true` for each of the given options.
235 236 237 |
# File 'lib/matrix_sdk/bot/base.rb', line 235 def enable(*opts) opts.each { |key| set(key, true) } end |
.event(event, only: nil, **_params, &block) ⇒ Object
Currently it’s only possible to register one handler per event type
Register a Matrix event
291 292 293 294 295 296 297 298 299 300 |
# File 'lib/matrix_sdk/bot/base.rb', line 291 def event(event, only: nil, **_params, &block) logger.debug "Registering event #{event}" add_handler( event.to_s, type: :event, only: [only].flatten.compact, &block ) end |
.event?(event, ignore_inherited: false) ⇒ Boolean
Check if an event is registered
321 322 323 324 325 |
# File 'lib/matrix_sdk/bot/base.rb', line 321 def event?(event, ignore_inherited: false) return @handlers[event]&.event? if ignore_inherited all_handlers(type: :event)[event]&.event? || false end |
.get_command(command, ignore_inherited: false) ⇒ RequestHandler?
Retrieves the RequestHandler for a given command
332 333 334 335 336 337 338 |
# File 'lib/matrix_sdk/bot/base.rb', line 332 def get_command(command, ignore_inherited: false) if ignore_inherited && @handlers[command]&.command? @handlers[command] elsif !ignore_inherited && all_handlers[command]&.command? all_handlers[command] end end |
.get_event(event, ignore_inherited: false) ⇒ RequestHandler?
Retrieves the RequestHandler for a given event
345 346 347 348 349 350 351 |
# File 'lib/matrix_sdk/bot/base.rb', line 345 def get_event(event, ignore_inherited: false) if ignore_inherited && @handlers[event]&.event? @handlers[event] elsif !ignore_inherited && all_handlers(type: :event)[event]&.event? all_handlers(type: :event)[event] end end |
.logger ⇒ Object
57 58 59 60 61 62 63 64 65 66 |
# File 'lib/matrix_sdk/bot/base.rb', line 57 def self.logger Logging.logger[self].tap do |l| begin l.level = :debug if MatrixSdk::Bot::PARAMS_CONFIG[:logging] rescue NameError # Not running as instance end l.level = settings.log_level unless settings.logging? end end |
.quit! ⇒ Object
Stops any running instance of the bot
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 |
# File 'lib/matrix_sdk/bot/base.rb', line 376 def quit! return unless running? active_bot.logger.info "Stopping #{settings.bot_name}..." if settings.store_sync_token begin active_bot.client.api.set_account_data( active_bot.client.mxid, "dev.ananace.ruby-sdk.#{settings.bot_name}", { sync_token: active_bot.client.sync_token } ) rescue StandardError => e active_bot.logger.error "Failed to save sync token, #{e.class}: #{e}" end end active_bot.client.logout if login? active_bot.client.api.stop_inflight active_bot.client.stop_listener_thread set :active_bot, nil end |
.remove_command(command) ⇒ Object
This will only affect local commands, not ones inherited
Removes a registered command from the bot
357 358 359 360 361 362 |
# File 'lib/matrix_sdk/bot/base.rb', line 357 def remove_command(command) return false unless @handlers[command]&.command? @handers.delete command true end |
.remove_event(event) ⇒ Object
This will only affect local event, not ones inherited
Removes a registered event from the bot
368 369 370 371 372 373 |
# File 'lib/matrix_sdk/bot/base.rb', line 368 def remove_event(event) return false unless @handlers[event]&.event? @handers.delete event true end |
.reset! ⇒ Object
Reset the bot class, removing any local handlers that have been registered
174 175 176 177 |
# File 'lib/matrix_sdk/bot/base.rb', line 174 def reset! @handlers = {} @client_handler = nil end |
.run!(options = {}, &block) ⇒ Object
Starts the bot up
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 |
# File 'lib/matrix_sdk/bot/base.rb', line 403 def run!( = {}, &block) return if running? set bot_settings = settings.respond_to?(:bot_settings) ? settings.bot_settings : {} bot_settings.merge!( threadsafe: settings.threadsafe, client_cache: settings.client_cache, sync_filter: settings.sync_filter ) bot_settings[:auth] = if settings.access_token? { access_token: settings.access_token } else { username: settings.username, password: settings.password } end begin start_bot(bot_settings, &block) ensure quit! end end |
.running? ⇒ Boolean
Check whether the self-hosted server is running or not.
429 430 431 |
# File 'lib/matrix_sdk/bot/base.rb', line 429 def running? active_bot? end |
.set(option, value = (not_set = true), ignore_setter = false, &block) ⇒ Object
Set a class-wide option for the bot
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/matrix_sdk/bot/base.rb', line 194 def set(option, value = (not_set = true), ignore_setter = false, &block) # rubocop:disable Style/OptionalBooleanParameter raise ArgumentError if block && !not_set if block value = block not_set = false end if not_set raise ArgumentError unless option.respond_to?(:each) option.each { |k, v| set(k, v) } return self end return send("#{option}=", value) if respond_to?("#{option}=") && !ignore_setter setter = proc { |val| set option, val, true } getter = proc { value } case value when Proc getter = value when Symbol, Integer, FalseClass, TrueClass, NilClass getter = value.inspect when Hash setter = proc do |val| val = value.merge val if val.is_a? Hash set option, val, true end end define_singleton("#{option}=", setter) define_singleton(option, getter) define_singleton("#{option}?", "!!#{option}") unless method_defined? "#{option}?" self end |
.settings ⇒ Object
Access settings defined with Base.set
140 141 142 |
# File 'lib/matrix_sdk/bot/base.rb', line 140 def self.settings self end |
Instance Method Details
#bot ⇒ Object
597 598 599 |
# File 'lib/matrix_sdk/bot/base.rb', line 597 def bot self end |
#command?(command, **params) ⇒ Boolean
Checks for the existence of a command
122 123 124 |
# File 'lib/matrix_sdk/bot/base.rb', line 122 def command?(command, **params) self.class.command?(command, **params) end |
#command_allowed?(command, event) ⇒ Boolean
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 |
# File 'lib/matrix_sdk/bot/base.rb', line 529 def command_allowed?(command, event) pre_event = @event return false unless command? command handler = get_command(command) return true if (handler.data[:only] || []).empty? # Avoid modifying input data for a checking method @event = MatrixSdk::Response.new(client.api, event.dup) return false if [handler.data[:only]].flatten.compact.any? do |only| if only.is_a? Proc !instance_exec(&only) else case only.to_s.downcase.to_sym when :dm !room.dm?(members_only: true) when :admin !sender_admin? when :mod !sender_moderator? end end end true ensure @event = pre_event end |
#event?(event, **params) ⇒ Boolean
Checks for the existence of a handled event
130 131 132 |
# File 'lib/matrix_sdk/bot/base.rb', line 130 def event?(event, **params) self.class.event?(event, **params) end |
#event_allowed?(event) ⇒ Boolean
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 |
# File 'lib/matrix_sdk/bot/base.rb', line 559 def event_allowed?(event) pre_event = @event return false unless event? event[:type] handler = get_event(event[:type]) return true if (handler.data[:only] || []).empty? # Avoid modifying input data for a checking method @event = MatrixSdk::Response.new(client.api, event.dup) return false if [handler.data[:only]].flatten.compact.any? do |only| if only.is_a? Proc instance_exec(&only) else case only.to_s.downcase.to_sym when :dm !room.dm?(members_only: true) when :admin !sender_admin? when :mod !sender_moderator? end end end true ensure @event = pre_event end |
#expanded_prefix ⇒ Object
Helpers
622 623 624 625 626 |
# File 'lib/matrix_sdk/bot/base.rb', line 622 def return "#{settings.command_prefix}#{settings.bot_name} " if settings.bot_name? settings.command_prefix end |
#get_command(command, **params) ⇒ RequestHandler
Gets the handler for a command
105 106 107 |
# File 'lib/matrix_sdk/bot/base.rb', line 105 def get_command(command, **params) self.class.get_command(command, **params) end |
#get_event(event, **params) ⇒ RequestHandler
Gets the handler for an event
114 115 116 |
# File 'lib/matrix_sdk/bot/base.rb', line 114 def get_event(event, **params) self.class.get_event(event, **params) end |
#in_event? ⇒ Boolean
Helpers for handling events
593 594 595 |
# File 'lib/matrix_sdk/bot/base.rb', line 593 def in_event? !@event.nil? end |
#register_command(command, **params, &block) ⇒ Object
Register a command during runtime
72 73 74 |
# File 'lib/matrix_sdk/bot/base.rb', line 72 def register_command(command, **params, &block) self.class.command(command, **params, &block) end |
#register_event(event, **params, &block) ⇒ Object
Register an event during runtime
80 81 82 |
# File 'lib/matrix_sdk/bot/base.rb', line 80 def register_event(event, **params, &block) self.class.event(event, **params, &block) end |
#room ⇒ Object
601 602 603 |
# File 'lib/matrix_sdk/bot/base.rb', line 601 def room client.ensure_room(event[:room_id]) if in_event? end |
#sender ⇒ Object
605 606 607 |
# File 'lib/matrix_sdk/bot/base.rb', line 605 def sender client.get_user(event[:sender]) if in_event? end |
#sender_admin? ⇒ Boolean
Helpers for checking power levels
610 611 612 |
# File 'lib/matrix_sdk/bot/base.rb', line 610 def sender_admin? sender&.admin? room end |
#sender_moderator? ⇒ Boolean
614 615 616 |
# File 'lib/matrix_sdk/bot/base.rb', line 614 def sender_moderator? sender&.moderator? room end |
#settings ⇒ Object
Access settings defined with Base.set
135 136 137 |
# File 'lib/matrix_sdk/bot/base.rb', line 135 def settings self.class.settings end |
#unregister_command(command) ⇒ Object
Removes a registered command during runtime
88 89 90 |
# File 'lib/matrix_sdk/bot/base.rb', line 88 def unregister_command(command) self.class.remove_command(command) end |
#unregister_event(command) ⇒ Object
Removes a registered event during runtime
96 97 98 |
# File 'lib/matrix_sdk/bot/base.rb', line 96 def unregister_event(command) self.class.remove_event(command) end |