Skip to content

Commit

Permalink
Merge pull request #41 from guardian/aa/chat-rate-limit
Browse files Browse the repository at this point in the history
fix: Handle 429 responses from Chat API
  • Loading branch information
akash1810 authored Nov 5, 2024
2 parents 3422cbc + 1b3c1e3 commit d89cecf
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 11 deletions.
46 changes: 37 additions & 9 deletions src/google.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use anyhow::{Context, Result};
use log::info;
use serde::{Deserialize, Serialize};
use std::time;
use url::Url;

#[derive(Serialize, Deserialize, Debug)]
Expand Down Expand Up @@ -32,23 +34,49 @@ impl GoogleChatMessage {
Ok(updated_url.as_str().to_string())
}

pub async fn send(self, webhook_url: &str, thread_key: &str) -> Result<GoogleChatMessage> {
pub async fn send(
self,
webhook_url: &str,
thread_key: &str,
attempt: i32,
) -> Result<GoogleChatMessage> {
let max_attempts = 3;
let url = GoogleChatMessage::build_webhook_url(webhook_url, thread_key)?;

let response = reqwest::Client::new()
.post(url.to_string())
.body(serde_json::to_string(&self)?)
.header("User-Agent", "GU-PR-Bot")
.send()
.await?
.text()
.await
.context(format!("Failed to get response from: {}", &webhook_url))?;
.await?;

serde_json::from_str(&response).context(format!(
"Failed to parse JSON when querying {}: {}",
&webhook_url, response
))
if response
.status()
.eq(&reqwest::StatusCode::TOO_MANY_REQUESTS)
&& attempt < max_attempts
{
/*
Sleep for 1.5 seconds to avoid rate limiting, at 60 requests per minute.
See https://developers.google.com/workspace/chat/limits
*/
info!(
"Received {} response. Sleeping for 1.5 seconds before retrying (attempt {})",
response.status(),
attempt
);
tokio::time::sleep(time::Duration::from_millis(1500)).await;
Box::pin(self.send(webhook_url, thread_key, attempt + 1)).await
} else {
let response_text = response.text().await.context(format!(
"Failed to get response from: {} after {} attempts",
&webhook_url, attempt
))?;

serde_json::from_str(&response_text).context(format!(
"Failed to parse JSON when querying {}: {}",
&webhook_url, response_text
))
}
}
}

Expand Down
8 changes: 6 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,16 @@ async fn main() -> Result<(), Error> {
info!("Using thread key {}", thread_key);

GoogleChatMessage::from(message)
.send(&webhook_url, &thread_key)
.send(&webhook_url, &thread_key, 0)
.await?;

for pull_request in pull_requests_to_review {
info!(
"Sending message for PR {} #{}",
pull_request.head.repo.name, pull_request.number
);
GoogleChatMessage::from(make_message(pull_request, show_pr_age))
.send(&webhook_url, &thread_key)
.send(&webhook_url, &thread_key, 0)
.await?;
}
} else {
Expand Down

0 comments on commit d89cecf

Please sign in to comment.