fix(captain/hermes): auto-react idempotente — bloqueia retry duplicate
OutgoingJob faz retry no DispatchError (até 3x ActiveJob + Sidekiq). Cada retry chamava AutoReactService.maybe_react! e criava uma reaction nova — observado em prod 02/05 quando o env var CAPTAIN_HERMES_SUBSCRIPTION_SECRET_INBOX_5 estava faltando, gerando 401 → 6 reações duplicadas no inbox EXPRESS. Adiciona guard already_reacted? que checa se já existe Message outgoing com external_source='hermes_auto_react' e in_reply_to=msg.id antes de criar uma nova. Defesa contra futuro 5xx/timeout do Hermes daemon. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3182002bd9
commit
e662913b21
@ -33,6 +33,7 @@ class Captain::Hermes::AutoReactService
|
|||||||
|
|
||||||
def maybe_react!
|
def maybe_react!
|
||||||
return unless eligible?
|
return unless eligible?
|
||||||
|
return if already_reacted?
|
||||||
|
|
||||||
emoji = decide_emoji
|
emoji = decide_emoji
|
||||||
return if emoji.blank?
|
return if emoji.blank?
|
||||||
@ -53,6 +54,16 @@ class Captain::Hermes::AutoReactService
|
|||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Evita reaction duplicada quando OutgoingJob retentar (ex: dispatch
|
||||||
|
# retornou 401/5xx e Sidekiq reenfileirou). Sem essa guarda, cada retry
|
||||||
|
# cria uma reaction nova e cliente vê N emojis seguidos.
|
||||||
|
def already_reacted?
|
||||||
|
@conversation.messages
|
||||||
|
.where(message_type: :outgoing)
|
||||||
|
.where("content_attributes ->> 'external_source' = ?", 'hermes_auto_react')
|
||||||
|
.exists?(["(content_attributes ->> 'in_reply_to')::int = ?", @message.id])
|
||||||
|
end
|
||||||
|
|
||||||
def decide_emoji
|
def decide_emoji
|
||||||
text = @message.content.to_s.strip
|
text = @message.content.to_s.strip
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user