use anyhow::*;
use reqwest::blocking::Response;
use serde::Serialize;
#[derive(Debug)]
pub struct RocketChat {
webhook_url: String,
channel: String,
}
impl RocketChat {
pub fn new<S: Into<String>>(webhook_url: S, channel: S) -> Self {
Self {
webhook_url: webhook_url.into(),
channel: channel.into(),
}
}
pub fn set_channel<S: Into<String>>(mut self, channel: S) -> Self {
self.channel = channel.into();
self
}
pub async fn send_text<S: Into<String>>(&self, msg: S) -> Result<reqwest::Response, Error> {
let msg = RocketChatMessage::new().set_text(msg.into());
self.send_message(msg).await
}
pub fn send_text_sync<S: Into<String>>(&self, msg: S) -> Result<Response, Error> {
let msg = RocketChatMessage::new().set_text(msg.into());
self.send_message_sync(msg)
}
pub async fn send_message(&self, msg: RocketChatMessage) -> Result<reqwest::Response, Error> {
let client = reqwest::Client::new();
let msg = RocketChatMessagePayload::from((msg, self.channel.clone()));
let res = client
.post(&self.webhook_url)
.json(&msg)
.send()
.await
.map_err(|e| anyhow!("Request error: {:?}", e.status()))?;
if res.status() == 200 {
Ok(res)
} else {
Err(anyhow!("Response error: {}", res.status())) }
}
pub fn send_message_sync(&self, msg: RocketChatMessage) -> Result<Response, Error> {
let client = reqwest::blocking::Client::new();
let msg = RocketChatMessagePayload::from((msg, self.channel.clone()));
let res = client
.post(&self.webhook_url)
.json(&msg)
.send()
.map_err(|e| anyhow!("Request error: {:?}", e.status()))?;
if res.status() == 200 {
Ok(res)
} else {
Err(anyhow!("Response error: {}", res.status())) }
}
pub async fn send_messages(&self, msgs: Vec<RocketChatMessage>) -> Result<(), Error> {
for msg in msgs {
self.send_message(msg).await?;
}
Ok(())
}
pub fn send_messages_sync(&self, msgs: Vec<RocketChatMessage>) -> Result<(), Error> {
for msg in msgs {
self.send_message_sync(msg)?;
}
Ok(())
}
}
#[derive(Serialize, Default)]
pub struct Field {
pub short: Option<bool>,
pub title: String,
pub value: String,
}
impl Field {
pub fn new() -> Self {
Field::default()
}
pub fn set_title<S: Into<String>>(mut self, title: S) -> Self {
self.title = title.into();
self
}
pub fn set_value<S: Into<String>>(mut self, value: S) -> Self {
self.value = value.into();
self
}
pub fn set_short(mut self, value: bool) -> Self {
self.short = Some(value);
self
}
}
#[derive(Serialize, Default)]
pub struct RocketChatAttachment {
pub title: Option<String>,
pub title_link: Option<String>,
pub color: Option<String>,
pub author_name: Option<String>,
pub author_icon: Option<String>,
pub text: Option<String>,
pub image_url: Option<String>,
pub fields: Vec<Field>,
}
impl RocketChatAttachment {
pub fn new() -> Self {
RocketChatAttachment::default()
}
pub fn set_title<S: Into<String>>(mut self, title: S) -> Self {
self.title = Some(title.into());
self
}
pub fn set_title_link<S: Into<String>>(mut self, title_link: S) -> Self {
self.title_link = Some(title_link.into());
self
}
pub fn set_color<S: Into<String>>(mut self, color: S) -> Self {
self.color = Some(color.into());
self
}
pub fn set_author<S: Into<String>>(mut self, name: S, icon: Option<S>) -> Self {
self.author_name = Some(name.into());
if let Some(icon) = icon {
self.author_icon = Some(icon.into());
}
self
}
pub fn set_text<S: Into<String>>(mut self, text: S) -> Self {
self.text = Some(text.into());
self
}
pub fn set_image<S: Into<String>>(mut self, url: S) -> Self {
self.image_url = Some(url.into());
self
}
pub fn set_fields(mut self, fields: Vec<Field>) -> Self {
self.fields = fields;
self
}
}
#[derive(Serialize, Default)]
struct RocketChatMessagePayload {
text: Option<String>,
channel: Option<String>,
attachments: Vec<RocketChatAttachment>,
}
impl From<(RocketChatMessage, String)> for RocketChatMessagePayload {
fn from(message: (RocketChatMessage, String)) -> Self {
Self {
text: message.0.text,
channel: Some(message.1),
attachments: message.0.attachments,
}
}
}
#[derive(Serialize, Default)]
pub struct RocketChatMessage {
pub text: Option<String>,
pub attachments: Vec<RocketChatAttachment>,
}
impl RocketChatMessage {
pub fn new() -> Self {
RocketChatMessage::default()
}
pub fn set_text<S: Into<String>>(mut self, text: S) -> Self {
self.text = Some(text.into());
self
}
pub fn set_attachments(mut self, attachments: Vec<RocketChatAttachment>) -> Self {
self.attachments = attachments;
self
}
}