fix(automations): guard reply-chase reschedule and re-validate delayed conditions on event change

This commit is contained in:
Tanmay Deep Sharma
2026-07-20 12:05:12 +05:30
parent 7ef91bee53
commit 68feaf99f6
2 changed files with 11 additions and 5 deletions
@@ -311,10 +311,12 @@ const resetToSupportedCondition = () => {
];
};
// Turning on a delay narrows the condition options; reset only the conditions a delayed rule
// can't use (e.g. a mutable attribute) to a supported default. Actions are kept.
watch(isDelayed, delayed => {
if (!delayed || !automation.value) return;
// A delay narrows the condition options, so whenever the rule becomes unsupported while the
// wait is on — toggling it on, or switching to an event whose default condition isn't allowed
// (e.g. conversation_opened defaults to browser_language) — reset to a supported default.
// Actions are kept. Resetting makes the rule supported again, so this can't loop.
watch([isDelayed, isDelaySupported], () => {
if (!isDelayed.value || !automation.value) return;
if (!isDelaySupported.value) resetToSupportedCondition();
});
@@ -62,7 +62,11 @@ class AutomationRulePendingExecution < ApplicationRecord
return unless message && !message.incoming?
row = find_by!(automation_rule_id: rule.id, conversation_id: conversation.id, episode_key: key)
row.update!(due_at: rule.execution_delay.minutes.since(anchor), message_id: message.id) if row.pending?
# Jobs can arrive out of order; only a newer reply moves the clock, so a late older reply
# can't pull due_at backwards and fire before the delay elapses since the latest reply.
return unless row.pending? && message.id > row.message_id
row.update!(due_at: rule.execution_delay.minutes.since(anchor), message_id: message.id)
end
# The wait is measured from when the qualifying event happened, not when this (possibly