use crate::cap::{Auth, Cap};
use crate::error::{BotError, unbound_domain};
use crate::verb::{self, Observe};
#[derive(PartialEq, Debug, Clone)]
#[non_exhaustive]
pub struct ChatMessage {
channel: String,
sender: String,
text: String,
ts: String,
}
impl ChatMessage {
#[must_use]
pub fn new(
channel: impl Into<String>,
sender: impl Into<String>,
text: impl Into<String>,
ts: impl Into<String>,
) -> Self {
Self {
channel: channel.into(),
sender: sender.into(),
text: text.into(),
ts: ts.into(),
}
}
#[must_use]
pub fn channel(&self) -> &str {
&self.channel
}
#[must_use]
pub fn sender(&self) -> &str {
&self.sender
}
#[must_use]
pub fn text(&self) -> &str {
&self.text
}
#[must_use]
pub fn ts(&self) -> &str {
&self.ts
}
#[must_use]
pub fn contains(&self, pattern: &str) -> bool {
self.text.contains(pattern)
}
}
#[derive(Debug)]
pub struct SlackChannel {
channel: String,
caps: Vec<Cap>,
}
impl SlackChannel {
pub fn new(channel: impl Into<String>) -> Self {
Self {
channel: channel.into(),
caps: vec![Cap::net()],
}
}
fn unbound<T>(&self, auth: &Auth, verb: &str) -> Result<T, BotError> {
unbound_domain(
auth,
self.required_caps(),
self.domain_id(),
verb,
&self.channel,
)
}
}
impl verb::Observe for SlackChannel {
type Output = ChatMessage;
fn required_caps(&self) -> &[Cap] {
&self.caps
}
async fn poll(&self, call: (Auth, ())) -> Result<ChatMessage, BotError> {
self.unbound(&call.0, "polling")
}
fn domain_id(&self) -> &str {
"chat::slack_message"
}
}
impl verb::Query for SlackChannel {
type Input = ();
type Output = Vec<ChatMessage>;
fn required_caps(&self) -> &[Cap] {
&self.caps
}
async fn query(&self, call: (Auth, &())) -> Result<Vec<ChatMessage>, BotError> {
self.unbound(&call.0, "querying")
}
fn domain_id(&self) -> &str {
"chat::slack_message"
}
}
pub fn slack_message(channel: impl Into<String>) -> SlackChannel {
SlackChannel::new(channel)
}
#[derive(Debug)]
pub struct HttpWebhook {
path: String,
caps: Vec<Cap>,
}
impl HttpWebhook {
pub fn new(path: impl Into<String>) -> Self {
Self {
path: path.into(),
caps: vec![Cap::net()],
}
}
fn unbound<T>(&self, auth: &Auth, verb: &str) -> Result<T, BotError> {
unbound_domain(
auth,
self.required_caps(),
self.domain_id(),
verb,
&self.path,
)
}
}
impl verb::Observe for HttpWebhook {
type Output = ChatMessage;
fn required_caps(&self) -> &[Cap] {
&self.caps
}
async fn poll(&self, call: (Auth, ())) -> Result<ChatMessage, BotError> {
self.unbound(&call.0, "polling")
}
fn domain_id(&self) -> &str {
"chat::http_webhook"
}
}
pub fn http_webhook(path: impl Into<String>) -> HttpWebhook {
HttpWebhook::new(path)
}