Module: Brainiac::Plugins::Zoho::Handler

Defined in:
lib/brainiac/plugins/zoho/handler.rb

Class Method Summary collapse

Class Method Details

.email_excluded?(email, exclude_words) ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
67
68
69
70
# File 'lib/brainiac/plugins/zoho/handler.rb', line 64

def email_excluded?(email, exclude_words)
  return false if exclude_words.nil? || exclude_words.empty?

  searchable = [email["subject"], email["fromAddress"], email["toAddress"],
                email["summary"], email["html"]].join(" ").downcase
  Array(exclude_words).any? { |word| searchable.include?(word.downcase) }
end

.format_notification(email, rule) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/brainiac/plugins/zoho/handler.rb', line 88

def format_notification(email, rule)
  label = rule["label"] || "Zoho Mail"
  emoji = rule["emoji"] || "📧"
  parts = ["#{emoji} **#{label}**"]
  parts << "**Subject:** #{email["subject"]}" if email["subject"]
  parts << "**From:** #{email["fromAddress"]}" if email["fromAddress"]
  parts << "**To:** #{email["toAddress"]}" if email["toAddress"]

  body_text = extract_body_text(email, rule)
  parts << "```\n#{body_text}\n```" if body_text

  parts.join("\n")
end

.handle_webhook(email) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/brainiac/plugins/zoho/handler.rb', line 8

def handle_webhook(email)
  LOG.info "[Zoho] Received email: subject=#{email["subject"]}, from=#{email["fromAddress"]}, to=#{email["toAddress"]}"

  dump_payload(email)
  Config.reload!

  rule = match_rule(email)
  if rule
    LOG.info "[Zoho] Matched rule: #{rule["label"]}"
    if rule["dispatch_agent"]
      Triage.dispatch(email, rule)
      [200, { status: "triage_dispatched", rule: rule["label"], agent: rule["dispatch_agent"] }.to_json]
    else
      notify_match(email, rule)
      [200, { status: "matched", rule: rule["label"] }.to_json]
    end
  else
    LOG.info "[Zoho] No rules matched"
    [200, { status: "no_match" }.to_json]
  end
end

.match_rule(email) ⇒ Object



30
31
32
33
34
35
36
37
38
39
# File 'lib/brainiac/plugins/zoho/handler.rb', line 30

def match_rule(email)
  rules = Config.rules
  matched = rules.find { |rule| rule_matches?(rule, email) }
  return matched if matched

  fallback = fallback_rule
  return nil if fallback && email_excluded?(email, Config.fallback&.dig("exclude_words"))

  fallback
end

.notify_match(email, rule) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/brainiac/plugins/zoho/handler.rb', line 72

def notify_match(email, rule)
  target = rule["notify_target"] || Config.default_notify_target
  channel = rule["notify_channel"] || Config.notify_channel

  unless target
    LOG.warn "[Zoho] No notify_target configured for rule '#{rule["label"]}' and no default set"
    return
  end

  message = format_notification(email, rule)
  agent = rule["notify_as"] || Config.notify_as

  LOG.info "[Zoho] Sending notification via #{channel} to #{target}"
  send_notification(:zoho_email, message, channel: channel, target: target, agent: agent)
end

.rule_matches?(rule, email) ⇒ Boolean

Returns:

  • (Boolean)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/brainiac/plugins/zoho/handler.rb', line 41

def rule_matches?(rule, email)
  return false if rule["enabled"] == false

  %w[from_contains to_contains subject_contains].each do |field|
    pattern = rule[field]
    next if pattern.nil? || pattern.empty?

    email_field = case field
                  when "from_contains" then email["fromAddress"]
                  when "to_contains" then email["toAddress"]
                  when "subject_contains" then email["subject"]
                  end
    return false unless email_field.to_s.downcase.include?(pattern.downcase)
  end

  if rule["body_contains"] && !rule["body_contains"].empty?
    body = "#{email["summary"]}#{email["html"]}"
    return false unless body.downcase.include?(rule["body_contains"].downcase)
  end

  !email_excluded?(email, rule["exclude_words"])
end