Forráskód Böngészése

Post waiting messages with emoji reactions

Zulip lacks "X is typing" in topics, so during meetings it can be difficult to
determine whether to move on or not. This should be a solution!
Mark Rousskov 4 éve
szülő
commit
7489986e6a
1 módosított fájl, 86 hozzáadás és 1 törlés
  1. 86 1
      src/zulip.rs

+ 86 - 1
src/zulip.rs

@@ -156,6 +156,16 @@ fn handle_command<'a>(
                 })
                 .unwrap(),
             },
+            Some("await") => match post_waiter(&ctx, message_data).await {
+                Ok(r) => r,
+                Err(e) => serde_json::to_string(&Response {
+                    content: &format!(
+                        "Failed to await at this time: {:?}",
+                        e
+                    ),
+                })
+                .unwrap(),
+            },
             _ => serde_json::to_string(&Response {
                 content: "Unknown command.",
             })
@@ -430,7 +440,13 @@ impl<'a> MessageApiRequest<'a> {
                     Recipient::Private { email, .. } => email.to_string(),
                 },
                 topic: match self.recipient {
-                    Recipient::Stream { topic, .. } => Some(topic),
+                    Recipient::Stream { topic, .. } => {
+                        if topic.is_empty() {
+                            None
+                        } else {
+                            Some(topic)
+                        }
+                    }
                     Recipient::Private { .. } => None,
                 },
                 content: self.content,
@@ -604,3 +620,72 @@ async fn move_notification(
         .unwrap()),
     }
 }
+
+#[derive(serde::Serialize, Debug)]
+struct ResponseNotRequired {
+    response_not_required: bool,
+}
+
+#[derive(serde::Deserialize, Debug)]
+struct SentMessage {
+    id: u64,
+}
+
+#[derive(serde::Serialize, Debug, Copy, Clone)]
+struct AddReaction<'a> {
+    message_id: u64,
+    emoji_name: &'a str,
+}
+
+impl<'a> AddReaction<'a> {
+    pub async fn send(self, client: &reqwest::Client) -> anyhow::Result<reqwest::Response> {
+        let bot_api_token = env::var("ZULIP_API_TOKEN").expect("ZULIP_API_TOKEN");
+
+        Ok(client
+            .post(&format!(
+                "https://rust-lang.zulipchat.com/api/v1/messages/{}/reactions",
+                self.message_id
+            ))
+            .basic_auth(BOT_EMAIL, Some(&bot_api_token))
+            .form(&self)
+            .send()
+            .await?)
+    }
+}
+
+async fn post_waiter(ctx: &Context, message: &Message) -> anyhow::Result<String> {
+    let posted = MessageApiRequest {
+        recipient: Recipient::Stream {
+            id: message
+                .stream_id
+                .ok_or_else(|| anyhow::format_err!("private waiting not supported"))?,
+            topic: "",
+        },
+        content: "Does anyone has something to add on this topic, or should we move on?\n\
+                  React with :working_on_it: if you have something to say.\n\
+                  React with :all_good: if we should move on.",
+    }
+    .send(ctx.github.raw())
+    .await?;
+    let body = posted.text().await?;
+    let message_id = serde_json::from_str::<SentMessage>(&body)
+        .with_context(|| format!("{:?} did not deserialize as SentMessage", body))?
+        .id;
+
+    let reaction_a = AddReaction {
+        message_id,
+        emoji_name: "working_on_it",
+    }
+    .send(&ctx.github.raw());
+    let reaction_b = AddReaction {
+        message_id,
+        emoji_name: "all_good",
+    }
+    .send(&ctx.github.raw());
+    futures::try_join!(reaction_a, reaction_b,)?;
+
+    Ok(serde_json::to_string(&ResponseNotRequired {
+        response_not_required: true,
+    })
+    .unwrap())
+}