Module: Brainiac::Plugins::Discord::Delivery

Defined in:
lib/brainiac/plugins/discord/delivery.rb

Overview

Discord draft delivery system.

Response files land in draft/ with a .meta.json sidecar containing delivery info. After successful posting, both files move to posted/. A poller thread recovers orphaned drafts (e.g. after a server restart).

Constant Summary collapse

BRAINIAC_DIR_PATH =
ENV.fetch("BRAINIAC_DIR", File.join(Dir.home, ".brainiac"))
DRAFT_DIR =
File.join(BRAINIAC_DIR_PATH, "tmp", "discord", "draft")
POSTED_DIR =
File.join(BRAINIAC_DIR_PATH, "tmp", "discord", "posted")
POLLER_INTERVAL =

seconds

5
DRAFT_MIN_AGE =

seconds — don't race the monitoring thread

30

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.shared_threadsObject (readonly)

Returns the value of attribute shared_threads.



28
29
30
# File 'lib/brainiac/plugins/discord/delivery.rb', line 28

def shared_threads
  @shared_threads
end

.shared_threads_mutexObject (readonly)

Returns the value of attribute shared_threads_mutex.



28
29
30
# File 'lib/brainiac/plugins/discord/delivery.rb', line 28

def shared_threads_mutex
  @shared_threads_mutex
end

Class Method Details

.deliver_draft(response_file, meta_file) ⇒ Object

Shared logic for posting a draft response file to Discord and moving it to posted/.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/brainiac/plugins/discord/delivery.rb', line 49

def deliver_draft(response_file, meta_file)
  return false unless File.exist?(meta_file)

  lock_file = "#{meta_file}.lock"
  begin
    File.open(lock_file, File::CREAT | File::EXCL | File::WRONLY) {} # rubocop:disable Lint/EmptyBlock
  rescue Errno::EEXIST
    return false
  end

  meta = JSON.parse(File.read(meta_file))
  bot_token = resolve_bot_token(meta["agent_key"], meta["agent_name"])

  unless bot_token
    FileUtils.rm_f(lock_file)
    return false
  end

  unless File.exist?(response_file)
    FileUtils.rm_f(lock_file)
    return false
  end

  deliver_response_content(response_file, meta, bot_token)
  archive_delivered(response_file, meta_file, lock_file, meta["agent_name"])
  true
rescue StandardError => e
  LOG.error "[Discord] Failed to deliver draft #{meta_file}: #{e.message}" if defined?(LOG)
  File.delete(lock_file) if lock_file && File.exist?(lock_file)
  false
end

.ensure_dirs!Object



30
31
32
33
# File 'lib/brainiac/plugins/discord/delivery.rb', line 30

def ensure_dirs!
  FileUtils.mkdir_p(DRAFT_DIR)
  FileUtils.mkdir_p(POSTED_DIR)
end

.start_poller!Object



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/brainiac/plugins/discord/delivery.rb', line 35

def start_poller!
  ensure_dirs!
  Thread.new do
    LOG.info "[Discord] Draft poller started, checking #{DRAFT_DIR} every #{POLLER_INTERVAL}s" if defined?(LOG)
    loop do
      sleep POLLER_INTERVAL
      poll_drafts
    rescue StandardError => e
      LOG.error "[Discord] Draft poller error: #{e.message}" if defined?(LOG)
    end
  end
end