1use crate::contracts::WebhookConfig;
11
12use super::types::{WebhookContext, WebhookEventType, WebhookPayload};
13use super::worker::send_webhook_payload_internal;
14
15#[allow(clippy::too_many_arguments)]
20pub fn send_webhook(
21 event_type: WebhookEventType,
22 task_id: &str,
23 task_title: &str,
24 previous_status: Option<&str>,
25 current_status: Option<&str>,
26 note: Option<&str>,
27 config: &WebhookConfig,
28 timestamp_rfc3339: &str,
29) {
30 let payload = WebhookPayload {
31 event: event_type.as_str().to_string(),
32 timestamp: timestamp_rfc3339.to_string(),
33 task_id: Some(task_id.to_string()),
34 task_title: Some(task_title.to_string()),
35 previous_status: previous_status.map(|s| s.to_string()),
36 current_status: current_status.map(|s| s.to_string()),
37 note: note.map(|n| n.to_string()),
38 context: WebhookContext::default(),
39 };
40 send_webhook_payload_internal(payload, config, false);
41}
42
43pub fn send_webhook_payload(payload: WebhookPayload, config: &WebhookConfig) {
48 if !send_webhook_payload_internal(payload, config, false) {
49 log::debug!("Webhook enqueue failed (see warning above for details)");
51 }
52}
53
54pub fn notify_task_created(
56 task_id: &str,
57 task_title: &str,
58 config: &WebhookConfig,
59 timestamp_rfc3339: &str,
60) {
61 send_webhook(
62 WebhookEventType::TaskCreated,
63 task_id,
64 task_title,
65 None,
66 None,
67 None,
68 config,
69 timestamp_rfc3339,
70 );
71}
72
73pub fn notify_task_created_with_context(
75 task_id: &str,
76 task_title: &str,
77 config: &WebhookConfig,
78 timestamp_rfc3339: &str,
79 context: WebhookContext,
80) {
81 let payload = WebhookPayload {
82 event: WebhookEventType::TaskCreated.as_str().to_string(),
83 timestamp: timestamp_rfc3339.to_string(),
84 task_id: Some(task_id.to_string()),
85 task_title: Some(task_title.to_string()),
86 previous_status: None,
87 current_status: None,
88 note: None,
89 context,
90 };
91 send_webhook_payload_internal(payload, config, false);
92}
93
94pub fn notify_task_started(
96 task_id: &str,
97 task_title: &str,
98 config: &WebhookConfig,
99 timestamp_rfc3339: &str,
100) {
101 send_webhook(
102 WebhookEventType::TaskStarted,
103 task_id,
104 task_title,
105 Some("todo"),
106 Some("doing"),
107 None,
108 config,
109 timestamp_rfc3339,
110 );
111}
112
113pub fn notify_task_started_with_context(
115 task_id: &str,
116 task_title: &str,
117 config: &WebhookConfig,
118 timestamp_rfc3339: &str,
119 context: WebhookContext,
120) {
121 let payload = WebhookPayload {
122 event: WebhookEventType::TaskStarted.as_str().to_string(),
123 timestamp: timestamp_rfc3339.to_string(),
124 task_id: Some(task_id.to_string()),
125 task_title: Some(task_title.to_string()),
126 previous_status: Some("todo".to_string()),
127 current_status: Some("doing".to_string()),
128 note: None,
129 context,
130 };
131 send_webhook_payload_internal(payload, config, false);
132}
133
134pub fn notify_task_completed(
136 task_id: &str,
137 task_title: &str,
138 config: &WebhookConfig,
139 timestamp_rfc3339: &str,
140) {
141 send_webhook(
142 WebhookEventType::TaskCompleted,
143 task_id,
144 task_title,
145 Some("doing"),
146 Some("done"),
147 None,
148 config,
149 timestamp_rfc3339,
150 );
151}
152
153pub fn notify_task_completed_with_context(
155 task_id: &str,
156 task_title: &str,
157 config: &WebhookConfig,
158 timestamp_rfc3339: &str,
159 context: WebhookContext,
160) {
161 let payload = WebhookPayload {
162 event: WebhookEventType::TaskCompleted.as_str().to_string(),
163 timestamp: timestamp_rfc3339.to_string(),
164 task_id: Some(task_id.to_string()),
165 task_title: Some(task_title.to_string()),
166 previous_status: Some("doing".to_string()),
167 current_status: Some("done".to_string()),
168 note: None,
169 context,
170 };
171 send_webhook_payload_internal(payload, config, false);
172}
173
174pub fn notify_task_failed(
176 task_id: &str,
177 task_title: &str,
178 note: Option<&str>,
179 config: &WebhookConfig,
180 timestamp_rfc3339: &str,
181) {
182 send_webhook(
183 WebhookEventType::TaskFailed,
184 task_id,
185 task_title,
186 Some("doing"),
187 Some("rejected"),
188 note,
189 config,
190 timestamp_rfc3339,
191 );
192}
193
194pub fn notify_task_failed_with_context(
196 task_id: &str,
197 task_title: &str,
198 note: Option<&str>,
199 config: &WebhookConfig,
200 timestamp_rfc3339: &str,
201 context: WebhookContext,
202) {
203 let payload = WebhookPayload {
204 event: WebhookEventType::TaskFailed.as_str().to_string(),
205 timestamp: timestamp_rfc3339.to_string(),
206 task_id: Some(task_id.to_string()),
207 task_title: Some(task_title.to_string()),
208 previous_status: Some("doing".to_string()),
209 current_status: Some("rejected".to_string()),
210 note: note.map(|n| n.to_string()),
211 context,
212 };
213 send_webhook_payload_internal(payload, config, false);
214}
215
216pub fn notify_status_changed(
218 task_id: &str,
219 task_title: &str,
220 previous_status: &str,
221 current_status: &str,
222 config: &WebhookConfig,
223 timestamp_rfc3339: &str,
224) {
225 send_webhook(
226 WebhookEventType::TaskStatusChanged,
227 task_id,
228 task_title,
229 Some(previous_status),
230 Some(current_status),
231 None,
232 config,
233 timestamp_rfc3339,
234 );
235}
236
237pub fn notify_loop_started(
240 config: &WebhookConfig,
241 timestamp_rfc3339: &str,
242 context: WebhookContext,
243) {
244 let payload = WebhookPayload {
245 event: WebhookEventType::LoopStarted.as_str().to_string(),
246 timestamp: timestamp_rfc3339.to_string(),
247 task_id: None,
248 task_title: None,
249 previous_status: None,
250 current_status: None,
251 note: None,
252 context,
253 };
254 send_webhook_payload_internal(payload, config, false);
255}
256
257pub fn notify_loop_stopped(
260 config: &WebhookConfig,
261 timestamp_rfc3339: &str,
262 context: WebhookContext,
263 note: Option<&str>,
264) {
265 let payload = WebhookPayload {
266 event: WebhookEventType::LoopStopped.as_str().to_string(),
267 timestamp: timestamp_rfc3339.to_string(),
268 task_id: None,
269 task_title: None,
270 previous_status: None,
271 current_status: None,
272 note: note.map(|n| n.to_string()),
273 context,
274 };
275 send_webhook_payload_internal(payload, config, false);
276}
277
278pub fn notify_phase_started(
280 task_id: &str,
281 task_title: &str,
282 config: &WebhookConfig,
283 timestamp_rfc3339: &str,
284 context: WebhookContext,
285) {
286 let payload = WebhookPayload {
287 event: WebhookEventType::PhaseStarted.as_str().to_string(),
288 timestamp: timestamp_rfc3339.to_string(),
289 task_id: Some(task_id.to_string()),
290 task_title: Some(task_title.to_string()),
291 previous_status: None,
292 current_status: None,
293 note: None,
294 context,
295 };
296 send_webhook_payload_internal(payload, config, false);
297}
298
299pub fn notify_phase_completed(
301 task_id: &str,
302 task_title: &str,
303 config: &WebhookConfig,
304 timestamp_rfc3339: &str,
305 context: WebhookContext,
306) {
307 let payload = WebhookPayload {
308 event: WebhookEventType::PhaseCompleted.as_str().to_string(),
309 timestamp: timestamp_rfc3339.to_string(),
310 task_id: Some(task_id.to_string()),
311 task_title: Some(task_title.to_string()),
312 previous_status: None,
313 current_status: None,
314 note: None,
315 context,
316 };
317 send_webhook_payload_internal(payload, config, false);
318}
319
320pub fn notify_queue_unblocked(
323 config: &WebhookConfig,
324 timestamp_rfc3339: &str,
325 context: WebhookContext,
326 note: Option<&str>,
327) {
328 let payload = WebhookPayload {
329 event: WebhookEventType::QueueUnblocked.as_str().to_string(),
330 timestamp: timestamp_rfc3339.to_string(),
331 task_id: None,
332 task_title: None,
333 previous_status: Some("blocked".to_string()),
334 current_status: Some("runnable".to_string()),
335 note: note.map(|n| n.to_string()),
336 context,
337 };
338 send_webhook_payload_internal(payload, config, false);
339}