use sfr_core as sc;
use sfr_server as ss;
use sfr_slack_api as ssa;
use sfr_types as st;
use derive_new::new;
use sc::{OauthV2AccessResponse, Slack, SlashCommandBody};
use ss::{
HomeHandlerTrait, OauthHandlerTrait, OauthRedirectResponse, ResponseError, Server,
SlashCommandHandlerTrait,
};
use ssa::Client;
use std::env;
#[tokio::main]
async fn main() -> Result<(), st::Error> {
let args: Vec<String> = env::args().collect();
let sock = args.get(1).unwrap();
let id = env::var("SSCT_SLACK_ID").unwrap();
let secret = env::var("SSCT_SLACK_SECRET").unwrap();
let signing_secret = env::var("SSCT_SLACK_SIGNING_SECRET").unwrap();
let verification_token = env::var("SSCT_SLACK_VERIFICATION_TOKEN").unwrap();
let oauth_token = env::var("SSCT_SLACK_OAUTH_TOKEN").unwrap();
let log = env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string());
let server_config = ss::Config::builder()
.sock(sock.parse().unwrap())
.log(Some(log))
.build();
let slack_creds = sc::AppCredentials {
id,
secret,
signing_secret,
verification_token,
};
let slack_config = sc::Config {
timestamp_range: 300,
};
let slack = Slack::new(slack_creds, slack_config);
let client = reqwest::Client::new();
let oauth_handler = OauthHandler::new(oauth_token);
let server = Server::new(
server_config,
slack,
client,
Handler,
Handler,
oauth_handler,
);
server.serve().await
}
struct Handler;
#[derive(new)]
struct OauthHandler {
token: String,
}
impl SlashCommandHandlerTrait for Handler {
async fn handle_slash_command(
&self,
client: &Client,
body: SlashCommandBody,
) -> Result<st::SlashCommandResponse, ResponseError> {
let client = client.clone();
tokio::spawn(async move {
let request_body = ssa::RequestBuilder::files_upload()
.channels(vec![body.channel_id.clone()])
.file("./assets/remote/loop1.wav".to_string())
.filename("loop1.wav".to_string())
.build()
.inspect_err(|e| tracing::error!("failed to build api object: {e}"));
tracing::debug!("request_body: {:?}", request_body);
if let Ok(request_body) = request_body {
let response_body = client
.request(request_body)
.await
.inspect_err(|e| tracing::error!("failed to request: {e}"));
tracing::info!("requested: {:?}", response_body);
}
});
Ok(st::SlashCommandResponse::empty().into())
}
}
impl OauthHandlerTrait for OauthHandler {
async fn handle_oauth(
&self,
_client: reqwest::Client,
body: OauthV2AccessResponse,
) -> Result<Option<OauthRedirectResponse>, ResponseError> {
tracing::info!("body: {body:?}");
Ok(None)
}
async fn take_oauth_token_from_team_id(&self, _team_id: &str) -> Result<String, ResponseError> {
Ok(self.token.clone())
}
fn redirect_uri(&self) -> &str {
unimplemented!()
}
}
impl HomeHandlerTrait for Handler {
async fn handle_home(&self) -> Result<Vec<u8>, ResponseError> {
const RESPONSE: &str = r#"<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title></title></head><body>ok</body></html>"#;
Ok(RESPONSE.into())
}
}