Skip to content

Commit

Permalink
Allow the provided webhook url to include or omit the threadKey param…
Browse files Browse the repository at this point in the history
…eter

This parameter used to require a `{threadKey}` placeholder, which is
sometimes forgotten. We now support Webhook URLs that do not include
this placeholder, and strip the placeholder if it was present.
  • Loading branch information
adamnfish committed Jan 12, 2024
1 parent 165c68c commit 34836e6
Showing 1 changed file with 62 additions and 3 deletions.
65 changes: 62 additions & 3 deletions src/google.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,34 @@ impl GoogleChatMessage {
GoogleChatMessage { text: text }
}

/// Build a webhook URL with threadKey set to the provided value, and messageReplyOption set to allow threading.
pub fn build_webhook_url(webhook_url: &String, thread_key: &String) -> Result<String> {
let url = Url::parse(webhook_url)?;
// strip any existing threadKey / messageReplyOption parameters
let other_params = url
.query_pairs()
.filter(|(name, _)| name.ne("threadKey") && name.ne("messageReplyOption"));
// rebuild URL with the provided threadKey value, and our desired messageReplyOption
let mut updated_url = url.clone();
updated_url.query_pairs_mut()
.clear()
.extend_pairs(other_params)
.extend_pairs(&[
(&"messageReplyOption".to_string(), &"REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD".to_string()),
(&"threadKey".to_string(), thread_key)
]);
Ok(updated_url.as_str().to_string())
}

pub async fn send(
self,
webhook_url: &String,
thread_key: &String,
) -> Result<GoogleChatMessage> {
let webhook_url = Url::parse_with_params(webhook_url,
&[("messageReplyOption", "REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD"), ("threadKey", thread_key)])?;
let url = GoogleChatMessage::build_webhook_url(&webhook_url, &thread_key)?;

let response = reqwest::Client::new()
.post(webhook_url.as_str())
.post(url.to_string())
.body(serde_json::to_string(&self)?)
.header("User-Agent", "GU-PR-Bot")
.send()
Expand All @@ -36,3 +54,44 @@ impl GoogleChatMessage {
))
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_build_threaded_webhook_with_placeholder() {
let result = GoogleChatMessage::build_webhook_url(&String::from("https://example.com/ABCDEF?threadKey={threadKey}"), &String::from("1234"));
match result {
Ok(url) => assert_eq!(url, String::from("https://example.com/ABCDEF?messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD&threadKey=1234")),
Err(_) => assert!(false),
}
}

#[test]
fn test_build_threaded_webhook_without_placeholder() {
let result = GoogleChatMessage::build_webhook_url(&String::from("https://example.com/ABCDEF"), &String::from("1234"));
match result {
Ok(url) => assert_eq!(url, String::from("https://example.com/ABCDEF?messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD&threadKey=1234")),
Err(_) => assert!(false),
}
}

#[test]
fn test_preserves_other_existing_params() {
let result = GoogleChatMessage::build_webhook_url(&String::from("https://example.com/ABCDEF?foo=bar"), &String::from("1234"));
match result {
Ok(url) => assert_eq!(url, String::from("https://example.com/ABCDEF?foo=bar&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD&threadKey=1234")),
Err(_) => assert!(false),
}
}

#[test]
fn test_overrides_existing_messagereplyoption_parameter() {
let result = GoogleChatMessage::build_webhook_url(&String::from("https://example.com/ABCDEF?messageReplyOption=REPLY_MESSAGE"), &String::from("1234"));
match result {
Ok(url) => assert_eq!(url, String::from("https://example.com/ABCDEF?messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD&threadKey=1234")),
Err(_) => assert!(false),
}
}
}

0 comments on commit 34836e6

Please sign in to comment.