Class: Botiasloop::Channels::Base
- Inherits:
-
Object
- Object
- Botiasloop::Channels::Base
- Defined in:
- lib/botiasloop/channels/base.rb
Class Attribute Summary collapse
-
.channel_identifier ⇒ Object
writeonly
Sets the attribute channel_identifier.
Class Method Summary collapse
-
.channel_name(name = nil) ⇒ Symbol
(also: channel_identifier)
Get or set the channel identifier.
-
.required_config_keys ⇒ Array<Symbol>
Get required configuration keys.
-
.requires_config(*keys) ⇒ Object
Declare required configuration keys.
Instance Method Summary collapse
-
#after_process(source_id, user_id, response, raw_message) ⇒ Object
Hook called after processing a message Override in subclasses for custom post-processing (e.g., logging).
-
#authorized?(_source_id) ⇒ Boolean
Check if a source is authorized to use this channel.
-
#before_process(source_id, user_id, content, raw_message) ⇒ Object
Hook called before processing a message Override in subclasses for custom pre-processing (e.g., logging).
-
#channel_config ⇒ Hash
Get channel-specific configuration Override in subclasses for custom config access.
-
#channel_type ⇒ String
Get the channel type string (e.g., “telegram”, “cli”) Override in subclasses if needed.
-
#chat_for(source_id, user_identifier: nil) ⇒ Chat
Get or create a chat for a source.
-
#deliver_message(source_id, formatted_content) ⇒ Object
Deliver a formatted message to a source.
-
#extract_content(raw_message) ⇒ String
Extract content from raw message.
-
#extract_user_id(source_id, _raw_message) ⇒ String
Extract user ID from raw message for authorization Override in subclasses if user ID differs from source_id.
-
#format_message(content) ⇒ String
Format a message for this channel.
-
#handle_error(_source_id, _user_id, error, _raw_message) ⇒ Object
Handle errors during message processing Override in subclasses for custom error handling.
-
#handle_unauthorized(source_id, user_id, _raw_message) ⇒ Object
Handle unauthorized access Override in subclasses for custom unauthorized handling.
-
#initialize ⇒ Base
constructor
Initialize the channel.
-
#process_message(source_id, raw_message, _metadata = {}) ⇒ Object
Process an incoming message using template method pattern.
-
#running? ⇒ Boolean
Check if the channel is currently running.
-
#send_message(source_id, message) ⇒ Object
Send a message to a source.
-
#start_listening ⇒ Object
Start the channel and begin listening for messages.
-
#stop_listening ⇒ Object
Stop the channel and cleanup.
Constructor Details
#initialize ⇒ Base
Initialize the channel
40 41 42 |
# File 'lib/botiasloop/channels/base.rb', line 40 def initialize validate_required_config! end |
Class Attribute Details
.channel_identifier=(value) ⇒ Object (writeonly)
Sets the attribute channel_identifier
10 11 12 |
# File 'lib/botiasloop/channels/base.rb', line 10 def channel_identifier=(value) @channel_identifier = value end |
Class Method Details
.channel_name(name = nil) ⇒ Symbol Also known as: channel_identifier
Get or set the channel identifier
15 16 17 18 |
# File 'lib/botiasloop/channels/base.rb', line 15 def channel_name(name = nil) @channel_identifier = name if name @channel_identifier end |
.required_config_keys ⇒ Array<Symbol>
Get required configuration keys
32 33 34 |
# File 'lib/botiasloop/channels/base.rb', line 32 def required_config_keys @required_config_keys ||= [] end |
.requires_config(*keys) ⇒ Object
Declare required configuration keys
24 25 26 27 28 |
# File 'lib/botiasloop/channels/base.rb', line 24 def requires_config(*keys) @required_config_keys ||= [] @required_config_keys.concat(keys) if keys.any? @required_config_keys end |
Instance Method Details
#after_process(source_id, user_id, response, raw_message) ⇒ Object
Hook called after processing a message Override in subclasses for custom post-processing (e.g., logging)
165 166 167 |
# File 'lib/botiasloop/channels/base.rb', line 165 def after_process(source_id, user_id, response, ) # No-op by default end |
#authorized?(_source_id) ⇒ Boolean
Check if a source is authorized to use this channel
195 196 197 |
# File 'lib/botiasloop/channels/base.rb', line 195 def (_source_id) false end |
#before_process(source_id, user_id, content, raw_message) ⇒ Object
Hook called before processing a message Override in subclasses for custom pre-processing (e.g., logging)
154 155 156 |
# File 'lib/botiasloop/channels/base.rb', line 154 def before_process(source_id, user_id, content, ) # No-op by default end |
#channel_config ⇒ Hash
Get channel-specific configuration Override in subclasses for custom config access
48 49 50 |
# File 'lib/botiasloop/channels/base.rb', line 48 def channel_config Config.instance.channels[self.class.channel_identifier.to_s] || {} end |
#channel_type ⇒ String
Get the channel type string (e.g., “telegram”, “cli”) Override in subclasses if needed
56 57 58 |
# File 'lib/botiasloop/channels/base.rb', line 56 def channel_type self.class.channel_identifier.to_s end |
#chat_for(source_id, user_identifier: nil) ⇒ Chat
Get or create a chat for a source
204 205 206 |
# File 'lib/botiasloop/channels/base.rb', line 204 def chat_for(source_id, user_identifier: nil) Chat.find_or_create(channel_type, source_id, user_identifier: user_identifier) end |
#deliver_message(source_id, formatted_content) ⇒ Object
Deliver a formatted message to a source
230 231 232 |
# File 'lib/botiasloop/channels/base.rb', line 230 def (source_id, formatted_content) raise NotImplementedError, "Subclass must implement #deliver_message" end |
#extract_content(raw_message) ⇒ String
Extract content from raw message. Subclasses must implement.
133 134 135 |
# File 'lib/botiasloop/channels/base.rb', line 133 def extract_content() raise NotImplementedError, "Subclass must implement #extract_content" end |
#extract_user_id(source_id, _raw_message) ⇒ String
Extract user ID from raw message for authorization Override in subclasses if user ID differs from source_id
143 144 145 |
# File 'lib/botiasloop/channels/base.rb', line 143 def extract_user_id(source_id, ) source_id end |
#format_message(content) ⇒ String
Format a message for this channel
212 213 214 |
# File 'lib/botiasloop/channels/base.rb', line 212 def (content) content end |
#handle_error(_source_id, _user_id, error, _raw_message) ⇒ Object
Handle errors during message processing Override in subclasses for custom error handling
186 187 188 189 |
# File 'lib/botiasloop/channels/base.rb', line 186 def handle_error(_source_id, _user_id, error, ) Logger.error "[#{self.class.channel_identifier}] Error processing message: #{error.}" raise error end |
#handle_unauthorized(source_id, user_id, _raw_message) ⇒ Object
Handle unauthorized access Override in subclasses for custom unauthorized handling
175 176 177 |
# File 'lib/botiasloop/channels/base.rb', line 175 def (source_id, user_id, ) Logger.warn "[#{self.class.channel_identifier}] Unauthorized access from #{user_id} (source: #{source_id})" end |
#process_message(source_id, raw_message, _metadata = {}) ⇒ Object
Process an incoming message using template method pattern
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/botiasloop/channels/base.rb', line 84 def (source_id, , = {}) # Hook: Extract content from raw message content = extract_content() return if content.nil? || content.to_s.empty? # Hook: Extract user ID for authorization user_id = extract_user_id(source_id, ) # Authorization check unless (user_id) (source_id, user_id, ) return end # Hook: Pre-processing before_process(source_id, user_id, content, ) # Core processing logic chat = chat_for(source_id, user_identifier: user_id) conversation = chat.current_conversation response = if Commands.command?(content) context = Commands::Context.new( conversation: conversation, chat: chat, channel: self, user_id: source_id ) Commands.execute(content, context) else verbose_callback = proc do || (source_id, ) end Agent.chat(content, conversation: conversation, verbose_callback: verbose_callback) end (source_id, response) # Hook: Post-processing after_process(source_id, user_id, response, ) rescue => e handle_error(source_id, user_id, e, ) end |
#running? ⇒ Boolean
Check if the channel is currently running
75 76 77 |
# File 'lib/botiasloop/channels/base.rb', line 75 def running? raise NotImplementedError, "Subclass must implement #running?" end |
#send_message(source_id, message) ⇒ Object
Send a message to a source
220 221 222 223 |
# File 'lib/botiasloop/channels/base.rb', line 220 def (source_id, ) formatted = () (source_id, formatted) end |
#start_listening ⇒ Object
Start the channel and begin listening for messages
62 63 64 |
# File 'lib/botiasloop/channels/base.rb', line 62 def start_listening raise NotImplementedError, "Subclass must implement #start_listening" end |
#stop_listening ⇒ Object
Stop the channel and cleanup
68 69 70 |
# File 'lib/botiasloop/channels/base.rb', line 68 def stop_listening raise NotImplementedError, "Subclass must implement #stop_listening" end |