huskies: merge 669_story_migrate_slack_transport_to_status_broadcaster
This commit is contained in:
@@ -56,6 +56,13 @@ pub struct ProjectConfig {
|
||||
/// Default: `true`.
|
||||
#[serde(default = "default_matrix_status_consumer")]
|
||||
pub matrix_status_consumer: bool,
|
||||
/// Whether the Slack bot subscribes to the status broadcaster and forwards
|
||||
/// pipeline events to its configured channels.
|
||||
/// Set to `false` to silence Slack status notifications without affecting
|
||||
/// other consumers (web UI, Matrix, Discord, WhatsApp, agent context).
|
||||
/// Default: `true`.
|
||||
#[serde(default = "default_slack_status_consumer")]
|
||||
pub slack_status_consumer: bool,
|
||||
/// IANA timezone name (e.g. `"Europe/London"`, `"America/New_York"`).
|
||||
/// When set, timer HH:MM inputs are interpreted in this timezone instead
|
||||
/// of the container/host local time. Falls back to `chrono::Local` when absent.
|
||||
@@ -144,6 +151,10 @@ fn default_matrix_status_consumer() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_slack_status_consumer() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn default_max_mesh_peers() -> usize {
|
||||
3
|
||||
}
|
||||
@@ -275,6 +286,7 @@ impl Default for ProjectConfig {
|
||||
rate_limit_notifications: default_rate_limit_notifications(),
|
||||
web_ui_status_consumer: default_web_ui_status_consumer(),
|
||||
matrix_status_consumer: default_matrix_status_consumer(),
|
||||
slack_status_consumer: default_slack_status_consumer(),
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -358,6 +370,7 @@ impl ProjectConfig {
|
||||
rate_limit_notifications: legacy.rate_limit_notifications,
|
||||
web_ui_status_consumer: default_web_ui_status_consumer(),
|
||||
matrix_status_consumer: default_matrix_status_consumer(),
|
||||
slack_status_consumer: default_slack_status_consumer(),
|
||||
timezone: legacy.timezone,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -392,6 +405,7 @@ impl ProjectConfig {
|
||||
rate_limit_notifications: legacy.rate_limit_notifications,
|
||||
web_ui_status_consumer: default_web_ui_status_consumer(),
|
||||
matrix_status_consumer: default_matrix_status_consumer(),
|
||||
slack_status_consumer: default_slack_status_consumer(),
|
||||
timezone: legacy.timezone,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -414,6 +428,7 @@ impl ProjectConfig {
|
||||
rate_limit_notifications: legacy.rate_limit_notifications,
|
||||
web_ui_status_consumer: default_web_ui_status_consumer(),
|
||||
matrix_status_consumer: default_matrix_status_consumer(),
|
||||
slack_status_consumer: default_slack_status_consumer(),
|
||||
timezone: legacy.timezone,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
|
||||
@@ -763,6 +763,37 @@ async fn main() -> Result<(), std::io::Error> {
|
||||
watcher_rx_for_slack,
|
||||
root.clone(),
|
||||
);
|
||||
|
||||
// Subscribe to the status broadcaster if the slack_status_consumer toggle
|
||||
// is enabled (default: true). Formats each StatusEvent via the common
|
||||
// formatter and sends the resulting text to all configured Slack channels.
|
||||
// The task exits automatically when the broadcaster is dropped on shutdown.
|
||||
{
|
||||
use crate::service::status::format::format_status_event;
|
||||
|
||||
let status_enabled = config::ProjectConfig::load(root)
|
||||
.map(|c| c.slack_status_consumer)
|
||||
.unwrap_or(true);
|
||||
|
||||
if status_enabled {
|
||||
let mut sub = ctx.services.status.subscribe();
|
||||
let transport = Arc::clone(&ctx.transport) as Arc<dyn crate::chat::ChatTransport>;
|
||||
let channels: Vec<String> = ctx.channel_ids.iter().cloned().collect();
|
||||
tokio::spawn(async move {
|
||||
while let Some(event) = sub.recv().await {
|
||||
let plain = format_status_event(&event);
|
||||
for channel in &channels {
|
||||
if let Err(e) = transport.send_message(channel, &plain, "").await {
|
||||
crate::slog!(
|
||||
"[slack] Failed to send status event to {channel}: {e}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
crate::slog!("[slack] Status subscriber task exiting — broadcaster dropped");
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
drop(watcher_rx_for_slack);
|
||||
}
|
||||
|
||||
@@ -530,6 +530,7 @@ mod tests {
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -561,6 +562,7 @@ mod tests {
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -592,6 +594,7 @@ mod tests {
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -623,6 +626,7 @@ mod tests {
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -653,6 +657,7 @@ mod tests {
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -690,6 +695,7 @@ mod tests {
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -768,6 +774,7 @@ mod tests {
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -804,6 +811,7 @@ mod tests {
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -887,6 +895,7 @@ mod tests {
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -926,6 +935,7 @@ mod tests {
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -955,6 +965,7 @@ mod tests {
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
@@ -990,6 +1001,7 @@ mod tests {
|
||||
rate_limit_notifications: true,
|
||||
web_ui_status_consumer: true,
|
||||
matrix_status_consumer: true,
|
||||
slack_status_consumer: true,
|
||||
timezone: None,
|
||||
rendezvous: None,
|
||||
trusted_keys: Vec::new(),
|
||||
|
||||
Reference in New Issue
Block a user