Skip to content

Commit a5d96e2

Browse files
committed
feat: send slack message to test everything is working as expected
1 parent 52ef8d5 commit a5d96e2

File tree

6 files changed

+114
-3
lines changed

6 files changed

+114
-3
lines changed

charts/issue-bot/templates/deployment.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ spec:
5858
value: "{{ .Values.issueBot.modelApi.authToken }}"
5959
- name: ISSUE_BOT__MODEL_API__URL
6060
value: "{{ .Values.issueBot.modelApi.url }}"
61+
- name: ISSUE_BOT__SLACK__AUTH_TOKEN
62+
value: "{{ .Values.issueBot.slack.authToken }}"
63+
- name: ISSUE_BOT__SLACK__CHANNEL
64+
value: "{{ .Values.issueBot.slack.channel }}"
6165
- name: ISSUE_BOT__DATABASE__CONNECTION_STRING
6266
value: "{{ .Values.issueBot.databaseConnectionString }}"
6367
ports:

charts/issue-bot/values.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ issueBot:
1515
modelApi:
1616
url: ""
1717
authToken: ""
18+
slack:
19+
authToken: ""
20+
channel: ""
1821
pathPrefix: /
1922
ingress:
2023
annotations: {}

issue-bot/configuration/base.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,8 @@ server:
3030
ip: 0.0.0.0
3131
metrics_port: 4243
3232
port: 4242
33+
34+
slack:
35+
auth_token: ""
36+
channel: ""
37+
chat_write_url: https://slack.com/api/chat.postMessage

issue-bot/src/config.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ pub struct MessageConfig {
7373
pub post: String,
7474
}
7575

76+
#[derive(Clone, Debug, Deserialize)]
77+
pub struct SlackConfig {
78+
pub auth_token: String,
79+
pub channel: String,
80+
pub chat_write_url: String,
81+
}
82+
7683
#[derive(Debug, Deserialize)]
7784
pub struct IssueBotConfig {
7885
pub auth_token: String,
@@ -82,6 +89,7 @@ pub struct IssueBotConfig {
8289
pub message_config: MessageConfig,
8390
pub model_api: ModelApiConfig,
8491
pub server: ServerConfig,
92+
pub slack: SlackConfig,
8593
}
8694

8795
pub fn load_config<'de, T: Deserialize<'de>>(prefix: &str) -> Result<T, ConfigError> {

issue-bot/src/main.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use middlewares::RequestSpan;
2626
use pgvector::Vector;
2727
use routes::{health, index_repository};
2828
use serde::{Deserialize, Deserializer};
29+
use slack::Slack;
2930
use sqlx::{
3031
postgres::{PgConnectOptions, PgPoolOptions},
3132
prelude::FromRow,
@@ -50,6 +51,7 @@ mod huggingface;
5051
mod metrics;
5152
mod middlewares;
5253
mod routes;
54+
mod slack;
5355

5456
#[derive(Clone)]
5557
pub struct AppState {
@@ -251,10 +253,11 @@ async fn handle_webhooks_wrapper(
251253
embedding_api: EmbeddingApi,
252254
github_api: GithubApi,
253255
huggingface_api: HuggingfaceApi,
256+
slack: Slack,
254257
pool: Pool<Postgres>,
255258
) -> anyhow::Result<()> {
256259
select! {
257-
res = handle_webhooks(rx, embedding_api, github_api, huggingface_api, pool) => { res },
260+
res = handle_webhooks(rx, embedding_api, github_api, huggingface_api, slack, pool) => { res },
258261
_ = shutdown_signal() => { Ok(()) },
259262
}
260263
}
@@ -264,6 +267,7 @@ async fn handle_webhooks(
264267
embedding_api: EmbeddingApi,
265268
github_api: GithubApi,
266269
huggingface_api: HuggingfaceApi,
270+
slack: Slack,
267271
pool: Pool<Postgres>,
268272
) -> anyhow::Result<()> {
269273
while let Some(webhook_data) = rx.recv().await {
@@ -283,6 +287,15 @@ async fn handle_webhooks(
283287
.fetch_all(&pool)
284288
.await?;
285289

290+
slack
291+
.closest_issues(
292+
&issue.title,
293+
issue.number,
294+
&issue.html_url,
295+
&closest_issues,
296+
)
297+
.await?;
298+
286299
match (issue.is_pull_request, &issue.source) {
287300
(false, Source::Github) => {
288301
github_api
@@ -296,7 +309,6 @@ async fn handle_webhooks(
296309
}
297310
_ => (),
298311
}
299-
// TODO: send slack message
300312

301313
sqlx::query(
302314
r#"insert into issues (source_id, source, title, body, is_pull_request, number, html_url, url, embedding)
@@ -569,6 +581,7 @@ async fn main() -> anyhow::Result<()> {
569581
let embedding_api = EmbeddingApi::new(config.model_api).await?;
570582
let github_api = GithubApi::new(config.github_api, config.message_config.clone())?;
571583
let huggingface_api = HuggingfaceApi::new(config.huggingface_api, config.message_config)?;
584+
let slack = Slack::new(&config.slack)?;
572585

573586
let (tx, rx) = mpsc::channel(4_096);
574587

@@ -588,7 +601,7 @@ async fn main() -> anyhow::Result<()> {
588601
false,
589602
setup_metrics_recorder()
590603
))),
591-
handle_webhooks_wrapper(rx, embedding_api, github_api, huggingface_api, pool)
604+
handle_webhooks_wrapper(rx, embedding_api, github_api, huggingface_api, slack, pool)
592605
)?;
593606

594607
Ok(())

issue-bot/src/slack.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION};
2+
use serde::Serialize;
3+
use thiserror::Error;
4+
5+
use crate::{config::SlackConfig, ClosestIssue};
6+
7+
#[derive(Debug, Error)]
8+
pub enum SlackError {
9+
#[error("http client error: {0}")]
10+
HttpClient(#[from] reqwest::Error),
11+
#[error("invalid auth token value: {0}")]
12+
InvalidHeader(#[from] reqwest::header::InvalidHeaderValue),
13+
}
14+
15+
#[derive(Serialize)]
16+
struct SlackBody {
17+
channel: String,
18+
text: String,
19+
}
20+
21+
impl SlackBody {
22+
pub fn new(channel: &str, text: String) -> Self {
23+
Self {
24+
channel: channel.to_owned(),
25+
text,
26+
}
27+
}
28+
}
29+
30+
#[derive(Clone)]
31+
pub struct Slack {
32+
channel: String,
33+
chat_write_url: String,
34+
client: reqwest::Client,
35+
}
36+
37+
impl Slack {
38+
pub fn new(config: &SlackConfig) -> Result<Self, SlackError> {
39+
let mut headers = HeaderMap::new();
40+
41+
let mut auth_value = HeaderValue::from_str(&format!("Bearer {}", config.auth_token))?;
42+
auth_value.set_sensitive(true);
43+
headers.insert(AUTHORIZATION, auth_value);
44+
45+
let client = reqwest::Client::builder()
46+
.default_headers(headers)
47+
.build()?;
48+
49+
Ok(Self {
50+
channel: config.channel.to_owned(),
51+
chat_write_url: config.chat_write_url.to_owned(),
52+
client,
53+
})
54+
}
55+
56+
pub async fn closest_issues(
57+
&self,
58+
issue_title: &str,
59+
issue_number: i32,
60+
issue_html_url: &str,
61+
closest_issues: &[ClosestIssue],
62+
) -> Result<(), SlackError> {
63+
let mut msg = vec![format!(
64+
"Closest issues for {} <{}|#{}>",
65+
issue_title, issue_number, issue_html_url
66+
)];
67+
for ci in closest_issues {
68+
msg.push(format!("- {} (<{}|#{}>)", ci.title, ci.html_url, ci.number));
69+
}
70+
let body = SlackBody::new(&self.channel, msg.join("\n"));
71+
self.client
72+
.post(self.chat_write_url.to_owned())
73+
.json(&body)
74+
.send()
75+
.await?;
76+
Ok(())
77+
}
78+
}

0 commit comments

Comments
 (0)