Skip to content

Commit 4e825af

Browse files
authored
slack formating (#1002)
* tmp * tmp
1 parent 70fd4f4 commit 4e825af

File tree

1 file changed

+41
-8
lines changed

1 file changed

+41
-8
lines changed

app-server/src/notifications/slack.rs

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::collections::HashMap;
22

33
use anyhow::Result;
4+
use regex::Regex;
45
use reqwest::Client;
56
use serde::{Deserialize, Serialize};
67
use serde_json::json;
@@ -73,14 +74,42 @@ pub fn decode_slack_token(
7374
.map_err(|e| anyhow::anyhow!("Failed to convert decrypted bytes to string: {}", e))
7475
}
7576

77+
fn replace_span_tags_with_links(
78+
text: &str,
79+
project_id: &str,
80+
trace_id: &str,
81+
span_ids_map: &HashMap<String, String>,
82+
) -> String {
83+
// Regex to match <span id='X' name='Y' ... />
84+
let re = Regex::new(r#"`<span\s+id='(\d+)'\s+name='([^']+)'[^>]*/?>`"#).unwrap();
85+
86+
re.replace_all(text, |caps: &regex::Captures| {
87+
let index_id = &caps[1];
88+
let name = &caps[2];
89+
90+
// Look up the actual span_id from the map
91+
if let Some(actual_span_id) = span_ids_map.get(index_id) {
92+
// Create Slack link: <url|text>
93+
format!(
94+
"[{}](https://laminar.sh/project/{}/traces/{}?spanId={})",
95+
name, project_id, trace_id, actual_span_id
96+
)
97+
} else {
98+
// If span_id not found in map, just return the name without a link (but don't replace)
99+
name.to_string()
100+
}
101+
})
102+
.to_string()
103+
}
104+
76105
fn format_trace_analysis_blocks(
77106
project_id: &str,
78107
trace_id: &str,
79108
event_name: &str,
80109
status: &str,
81110
summary: &str,
82111
analysis: &str,
83-
_span_ids_map: &HashMap<String, String>,
112+
span_ids_map: &HashMap<String, String>,
84113
) -> serde_json::Value {
85114
let emoji = match status {
86115
"error" => "🚨",
@@ -91,7 +120,7 @@ fn format_trace_analysis_blocks(
91120
let analysis_text = if analysis.is_empty() {
92121
"No analysis available".to_string()
93122
} else {
94-
analysis.to_string()
123+
replace_span_tags_with_links(analysis, project_id, trace_id, span_ids_map)
95124
};
96125

97126
let trace_link = format!(
@@ -108,11 +137,8 @@ fn format_trace_analysis_blocks(
108137
}
109138
},
110139
{
111-
"type": "section",
112-
"text": {
113-
"type": "mrkdwn",
114-
"text": analysis_text
115-
}
140+
"type": "markdown",
141+
"text": analysis_text
116142
},
117143
{
118144
"type": "actions",
@@ -246,11 +272,18 @@ pub async fn send_message(
246272
channel_id: &str,
247273
blocks: serde_json::Value,
248274
) -> Result<()> {
275+
let body = json!({
276+
"channel": channel_id,
277+
"blocks": blocks,
278+
"unfurl_links": false,
279+
"unfurl_media": false
280+
});
281+
249282
let response = slack_client
250283
.post(format!("{}/chat.postMessage", SLACK_API_BASE))
251284
.header("Authorization", format!("Bearer {}", token))
252285
.header("Content-Type", "application/json")
253-
.json(&json!({ "channel": channel_id, "blocks": blocks }))
286+
.json(&body)
254287
.send()
255288
.await?;
256289
let status = response.status();

0 commit comments

Comments
 (0)