Skip to content

fix(cron): cronjob replies go to channel instead of creating a thread #612

@chaodu-agent

Description

@chaodu-agent

Description

Cronjob-triggered messages reply directly to the channel instead of creating a Discord thread. The normal Discord flow creates a thread from the trigger message via get_or_create_thread() in discord.rs before calling handle_message(). However, fire_cronjob() in cron.rs sends a trigger message to the channel, then calls router.handle_message() directly — bypassing thread creation entirely.

The result is that the agent reply is posted as a flat message in the channel, not in a thread.

Normal Discord flow:
  discord.rs event handler
    → get_or_create_thread()   ← creates thread from trigger msg
    → router.handle_message()  ← replies go into thread

Cron flow (current):
  cron.rs fire_cronjob()
    → adapter.send_message()   ← sends trigger msg to channel
    → router.handle_message()  ← replies go to channel (no thread!)

Affected code:

openab/src/cron.rs

Lines 155 to 185 in 3680a65

channel = %job.channel,
platform = %job.platform,
message = %job.message,
sender = %job.sender_name,
"🔔 cronjob fired"
);
in_flight.lock().await.insert(idx);
// Spawn the entire fire_cronjob so send_message doesn't block the loop
let job = job.clone();
let router = router.clone();
let adapters = adapters.clone();
let in_flight = in_flight.clone();
tasks.spawn(async move {
fire_cronjob(idx, &job, &router, &adapters, in_flight).await;
});
}
// Reap completed tasks to avoid unbounded growth
while tasks.try_join_next().is_some() {}
}
_ = shutdown_rx.changed() => {
if *shutdown_rx.borrow() {
info!("cron scheduler shutting down, waiting for in-flight tasks");
// Wait for all in-flight tasks with a timeout
let drain = async { while tasks.join_next().await.is_some() {} };
let _ = tokio::time::timeout(std::time::Duration::from_secs(30), drain).await;
return;
}
}
}
}

Steps to Reproduce

  1. Configure a cronjob in config.toml:
[[cronjobs]]
schedule = "*/5 * * * *"
channel = "1498701710212726885"
message = "find one to triage"
sender_name = "TriageBot"
  1. Wait for the cron to fire
  2. Observe the agent reply goes directly to the channel, not in a thread

Expected Behavior

fire_cronjob() should call adapter.create_thread() using the trigger message as the anchor, then pass the resulting ChannelRef (with the thread ID) to router.handle_message(). This would match the normal Discord flow where every conversation starts in its own thread.

// Proposed fix in fire_cronjob():
let trigger_msg = adapter.send_message(&thread_channel, &format!("🕐 ...")).await?;
let thread_channel = adapter.create_thread(&thread_channel, &trigger_msg, &thread_name).await?;
router.handle_message(&adapter, &thread_channel, ...).await;

Filed by chaodu-agent

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions