brainiac-discord 0.0.20 → 0.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/brainiac/plugins/discord/gateway.rb +39 -1
- data/lib/brainiac/plugins/discord/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '0867d7c12ec729c881db2a3a8dd9f02da284f677b3f7226a8771958b97da07b5'
|
|
4
|
+
data.tar.gz: 073f0bbceca7c578ea06cd888c2e333b113efeede5ebde4b02b257247df15c9d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5c103f0b92d230a5789424e41d9ea9881636a7ede849278db072c93b42c18ac42266ea264abb7128086e92e0639a042ff894460d9ee1405aabb5348d71918bda
|
|
7
|
+
data.tar.gz: 2a236d41ec8676a4e3459bcd26bf5d47019a3f4cc5e67bfa4b1d2b8027c00e0803680c5ca37166285449d4a0f2ccffd7a0b81fde785a4ea977f476994aa158d3
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "websocket-client-simple"
|
|
4
4
|
require "websocket"
|
|
5
|
+
require "time"
|
|
5
6
|
|
|
6
7
|
module Brainiac
|
|
7
8
|
module Plugins
|
|
@@ -23,6 +24,12 @@ module Brainiac
|
|
|
23
24
|
BACKOFF_HANDSHAKE_BASE = 30
|
|
24
25
|
BACKOFF_CAP = 300
|
|
25
26
|
|
|
27
|
+
# How long after a message is posted an edit still counts as a real,
|
|
28
|
+
# conversational edit worth re-dispatching on. Edits that land outside
|
|
29
|
+
# this window are treated as server-side embed refreshes (Discord
|
|
30
|
+
# restamping edited_timestamp when it unfurls a link), not human intent.
|
|
31
|
+
EDIT_FRESHNESS_WINDOW = 300 # seconds (5 minutes)
|
|
32
|
+
|
|
26
33
|
# Per-bot state: { agent_key => { token:, user_id:, status:, thread: } }
|
|
27
34
|
@bots = {}
|
|
28
35
|
@bots_mutex = Mutex.new
|
|
@@ -376,7 +383,16 @@ module Brainiac
|
|
|
376
383
|
LOG.error "[Discord:#{agent_display}] Error handling message: #{e.message}\n#{e.backtrace.first(3).join("\n")}" if defined?(LOG)
|
|
377
384
|
end
|
|
378
385
|
when "MESSAGE_UPDATE"
|
|
379
|
-
|
|
386
|
+
# Discord emits MESSAGE_UPDATE for genuine human edits AND for
|
|
387
|
+
# server-side embed (un)furls on existing messages — e.g. lazily
|
|
388
|
+
# generating a link preview days after the message was posted. Both
|
|
389
|
+
# stamp edited_timestamp, so re-dispatching on every update means a
|
|
390
|
+
# bare URL in an old agent-mentioning message can silently wake the
|
|
391
|
+
# agent long after the fact. Only treat an update as actionable when
|
|
392
|
+
# the edit happened close to the message's own creation time, which
|
|
393
|
+
# is what a real conversational edit (typo fix, afterthought) looks
|
|
394
|
+
# like. See message.rb for the shared dispatch path.
|
|
395
|
+
if data["edited_timestamp"] && !stale_edit?(data["timestamp"], data["edited_timestamp"])
|
|
380
396
|
Thread.new do
|
|
381
397
|
Message.handle(data, agent_key, bot_token, bot_user_id)
|
|
382
398
|
rescue StandardError => e
|
|
@@ -384,6 +400,9 @@ module Brainiac
|
|
|
384
400
|
LOG.error "[Discord:#{agent_display}] Error handling message update: #{e.message}\n#{e.backtrace.first(3).join("\n")}"
|
|
385
401
|
end
|
|
386
402
|
end
|
|
403
|
+
elsif data["edited_timestamp"] && defined?(LOG)
|
|
404
|
+
LOG.info "[Discord:#{agent_display}] Ignoring stale MESSAGE_UPDATE " \
|
|
405
|
+
"(likely embed refresh) on message #{data["id"]}"
|
|
387
406
|
end
|
|
388
407
|
when "MESSAGE_REACTION_ADD"
|
|
389
408
|
Thread.new do
|
|
@@ -416,6 +435,25 @@ module Brainiac
|
|
|
416
435
|
bot_user_id
|
|
417
436
|
end
|
|
418
437
|
|
|
438
|
+
# True when a MESSAGE_UPDATE's edit happened long enough after the
|
|
439
|
+
# message was created that it's almost certainly a server-side embed
|
|
440
|
+
# refresh rather than a human edit. Guards against spurious agent
|
|
441
|
+
# dispatches from Discord lazily unfurling link previews on old
|
|
442
|
+
# messages that mention the bot.
|
|
443
|
+
#
|
|
444
|
+
# Fails open (returns false → treat as a real edit) when either
|
|
445
|
+
# timestamp is missing or unparseable, so a parsing hiccup never
|
|
446
|
+
# silently swallows a genuine edit.
|
|
447
|
+
def stale_edit?(created_at, edited_at)
|
|
448
|
+
return false if created_at.nil? || edited_at.nil?
|
|
449
|
+
|
|
450
|
+
created = Time.iso8601(created_at.to_s)
|
|
451
|
+
edited = Time.iso8601(edited_at.to_s)
|
|
452
|
+
(edited - created) > EDIT_FRESHNESS_WINDOW
|
|
453
|
+
rescue ArgumentError
|
|
454
|
+
false
|
|
455
|
+
end
|
|
456
|
+
|
|
419
457
|
def mark_bot_ready(agent_key, agent_display, bot_user_id, data)
|
|
420
458
|
@bots_mutex.synchronize do
|
|
421
459
|
@bots[agent_key][:user_id] = bot_user_id
|