Skip to content

Commit 0cfa95a

Browse files
Merge pull request #1705 from ehuss/docs-update-zulip-background
Process docs-update Zulip trigger in the background.
2 parents 9f16d2d + 14e9842 commit 0cfa95a

File tree

1 file changed

+57
-14
lines changed

1 file changed

+57
-14
lines changed

src/zulip.rs

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,50 @@ pub struct Request {
2121
token: String,
2222
}
2323

24-
#[derive(Debug, serde::Deserialize)]
24+
#[derive(Clone, Debug, serde::Deserialize)]
2525
struct Message {
2626
sender_id: u64,
27+
/// A unique ID for the set of users receiving the message (either a
28+
/// stream or group of users). Useful primarily for hashing.
2729
#[allow(unused)]
2830
recipient_id: u64,
2931
sender_short_name: Option<String>,
3032
sender_full_name: String,
33+
sender_email: String,
34+
/// The ID of the stream.
35+
///
36+
/// `None` if it is a private message.
3137
stream_id: Option<u64>,
32-
// The topic of the incoming message. Not the stream name.
38+
/// The topic of the incoming message. Not the stream name.
39+
///
40+
/// Not currently set for private messages (though Zulip may change this in
41+
/// the future if it adds topics to private messages).
3342
subject: Option<String>,
43+
/// The type of the message: stream or private.
3444
#[allow(unused)]
3545
#[serde(rename = "type")]
3646
type_: String,
3747
}
3848

49+
impl Message {
50+
/// Creates a `Recipient` that will be addressed to the sender of this message.
51+
fn sender_to_recipient(&self) -> Recipient<'_> {
52+
match self.stream_id {
53+
Some(id) => Recipient::Stream {
54+
id,
55+
topic: self
56+
.subject
57+
.as_ref()
58+
.expect("stream messages should have a topic"),
59+
},
60+
None => Recipient::Private {
61+
id: self.sender_id,
62+
email: &self.sender_email,
63+
},
64+
}
65+
}
66+
}
67+
3968
#[derive(serde::Serialize, serde::Deserialize)]
4069
struct Response {
4170
content: String,
@@ -158,7 +187,7 @@ fn handle_command<'a>(
158187
.await
159188
.map_err(|e| format_err!("Failed to await at this time: {e:?}"))
160189
}
161-
Some("docs-update") => return trigger_docs_update().await,
190+
Some("docs-update") => return trigger_docs_update(message_data),
162191
_ => {}
163192
}
164193
}
@@ -710,16 +739,30 @@ async fn post_waiter(
710739
Ok(None)
711740
}
712741

713-
async fn trigger_docs_update() -> anyhow::Result<Option<String>> {
714-
match docs_update().await {
715-
Ok(None) => Ok(Some("No updates found.".to_string())),
716-
Ok(Some(pr)) => Ok(Some(format!("Created docs update PR <{}>", pr.html_url))),
717-
Err(e) => {
718-
// Don't send errors to Zulip since they may contain sensitive data.
719-
log::error!("Docs update via Zulip failed: {e:?}");
720-
Err(format_err!(
721-
"Docs update failed, please check the logs for more details."
722-
))
742+
fn trigger_docs_update(message: &Message) -> anyhow::Result<Option<String>> {
743+
let message = message.clone();
744+
// The default Zulip timeout of 10 seconds can be too short, so process in
745+
// the background.
746+
tokio::task::spawn(async move {
747+
let response = match docs_update().await {
748+
Ok(None) => "No updates found.".to_string(),
749+
Ok(Some(pr)) => format!("Created docs update PR <{}>", pr.html_url),
750+
Err(e) => {
751+
// Don't send errors to Zulip since they may contain sensitive data.
752+
log::error!("Docs update via Zulip failed: {e:?}");
753+
"Docs update failed, please check the logs for more details.".to_string()
754+
}
755+
};
756+
let recipient = message.sender_to_recipient();
757+
let message = MessageApiRequest {
758+
recipient,
759+
content: &response,
760+
};
761+
if let Err(e) = message.send(&reqwest::Client::new()).await {
762+
log::error!("failed to send Zulip response: {e:?}\nresponse was:\n{response}");
723763
}
724-
}
764+
});
765+
Ok(Some(
766+
"Docs update in progress, I'll let you know when I'm finished.".to_string(),
767+
))
725768
}

0 commit comments

Comments
 (0)