Module: Brainiac::Plugins::Discord::Gateway
- Defined in:
- lib/brainiac/plugins/discord/gateway.rb
Overview
Discord WebSocket gateway connections.
Each agent with a DISCORD_BOT_TOKEN gets its own persistent WebSocket connection. The gateway dispatches MESSAGE_CREATE, MESSAGE_UPDATE, and MESSAGE_REACTION_ADD events to handler functions.
Constant Summary collapse
- GATEWAY_URL =
"wss://gateway.discord.gg/?v=10&encoding=json"
Class Attribute Summary collapse
-
.bots ⇒ Object
readonly
Returns the value of attribute bots.
-
.bots_mutex ⇒ Object
readonly
Returns the value of attribute bots_mutex.
Class Method Summary collapse
- .bot_count ⇒ Object
-
.bot_token(agent_key) ⇒ Object
Get a bot's token.
-
.bot_user_id(agent_key) ⇒ Object
Get a bot's user_id.
-
.bots_status ⇒ Object
Summary of all bot statuses for the API endpoint.
-
.detect_sender_agent(author, current_agent_key) ⇒ Object
Detect if a message author is a known bot (local or remote).
-
.discord_bot_tokens ⇒ Object
Collect all agent Discord bot tokens from the registry.
-
.each_bot ⇒ Object
Iterate over bots under mutex.
-
.start_all! ⇒ Object
Start all per-agent Discord bots.
-
.start_bot!(agent_key, token) ⇒ Object
Start a single bot gateway connection dynamically (e.g. after agent is added).
-
.stop_bot!(agent_key) ⇒ Object
Stop a bot gateway connection (e.g. after agent is removed).
Class Attribute Details
.bots ⇒ Object (readonly)
Returns the value of attribute bots.
22 23 24 |
# File 'lib/brainiac/plugins/discord/gateway.rb', line 22 def bots @bots end |
.bots_mutex ⇒ Object (readonly)
Returns the value of attribute bots_mutex.
22 23 24 |
# File 'lib/brainiac/plugins/discord/gateway.rb', line 22 def bots_mutex @bots_mutex end |
Class Method Details
.bot_count ⇒ Object
24 25 26 |
# File 'lib/brainiac/plugins/discord/gateway.rb', line 24 def bot_count @bots_mutex.synchronize { @bots.size } end |
.bot_token(agent_key) ⇒ Object
Get a bot's token.
36 37 38 |
# File 'lib/brainiac/plugins/discord/gateway.rb', line 36 def bot_token(agent_key) @bots_mutex.synchronize { @bots.dig(agent_key, :token) } end |
.bot_user_id(agent_key) ⇒ Object
Get a bot's user_id.
41 42 43 |
# File 'lib/brainiac/plugins/discord/gateway.rb', line 41 def bot_user_id(agent_key) @bots_mutex.synchronize { @bots.dig(agent_key, :user_id) } end |
.bots_status ⇒ Object
Summary of all bot statuses for the API endpoint.
104 105 106 107 108 109 110 |
# File 'lib/brainiac/plugins/discord/gateway.rb', line 104 def bots_status @bots_mutex.synchronize do @bots.transform_values do |info| { status: info[:status], user_id: info[:user_id] } end end end |
.detect_sender_agent(author, current_agent_key) ⇒ Object
Detect if a message author is a known bot (local or remote). Returns the agent_key of the sender, or nil if unknown.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/brainiac/plugins/discord/gateway.rb', line 114 def detect_sender_agent(, current_agent_key) sender_id = ["id"] sender_agent_key = nil @bots_mutex.synchronize do @bots.each do |key, info| if info[:user_id] == sender_id && key != current_agent_key sender_agent_key = key break end end end unless sender_agent_key Config.user_mappings.each do |name, discord_id| if discord_id == sender_id sender_agent_key = name.downcase break end end end if !sender_agent_key && defined?(LOG) LOG.info "[Discord:#{current_agent_key}] Ignoring unknown bot: id=#{sender_id}, username=#{["username"]}" end sender_agent_key end |
.discord_bot_tokens ⇒ Object
Collect all agent Discord bot tokens from the registry. Returns { "galen" => "token...", "glados" => "token..." }
47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/brainiac/plugins/discord/gateway.rb', line 47 def discord_bot_tokens tokens = {} AGENT_REGISTRY.each do |key, entry| next unless entry.is_a?(Hash) token = (entry["env"] || {})["DISCORD_BOT_TOKEN"] next unless token tokens[key] = token end tokens end |
.each_bot ⇒ Object
Iterate over bots under mutex.
29 30 31 32 33 |
# File 'lib/brainiac/plugins/discord/gateway.rb', line 29 def each_bot(&) @bots_mutex.synchronize do @bots.each(&) end end |
.start_all! ⇒ Object
Start all per-agent Discord bots.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/brainiac/plugins/discord/gateway.rb', line 61 def start_all! tokens = discord_bot_tokens if tokens.empty? LOG.info "[Discord] No agents have DISCORD_BOT_TOKEN configured — Discord disabled" if defined?(LOG) return end LOG.info "[Discord] Starting #{tokens.size} bot(s): #{tokens.keys.join(", ")}" if defined?(LOG) @bots_mutex.synchronize do tokens.each do |agent_key, token| @bots[agent_key] = { token: token, status: "starting", user_id: nil } end end tokens.each do |agent_key, token| start_gateway_for(agent_key, token) sleep 1 # Stagger connections to avoid rate limits end end |
.start_bot!(agent_key, token) ⇒ Object
Start a single bot gateway connection dynamically (e.g. after agent is added). No-op if the bot is already running.
84 85 86 87 88 89 90 91 |
# File 'lib/brainiac/plugins/discord/gateway.rb', line 84 def start_bot!(agent_key, token) @bots_mutex.synchronize do return if @bots[agent_key] @bots[agent_key] = { token: token, status: "starting", user_id: nil } end start_gateway_for(agent_key, token) end |
.stop_bot!(agent_key) ⇒ Object
Stop a bot gateway connection (e.g. after agent is removed). Removes it from the bots hash so it won't be matched in detect_sender_agent.
95 96 97 98 99 100 101 |
# File 'lib/brainiac/plugins/discord/gateway.rb', line 95 def stop_bot!(agent_key) info = @bots_mutex.synchronize { @bots.delete(agent_key) } return unless info info[:thread]&.kill LOG.info "[Discord] Gateway stopped for #{agent_key}" if defined?(LOG) end |