mirror of
https://github.com/System-End/slack-morphism-rust.git
synced 2026-04-19 22:05:15 +00:00
Docs and examples updates
This commit is contained in:
parent
3821bad91b
commit
84a3058f63
9 changed files with 334 additions and 212 deletions
|
|
@ -3,6 +3,5 @@
|
|||
members = [
|
||||
"src/models",
|
||||
"src/client",
|
||||
"src/hyper",
|
||||
"src/examples",
|
||||
"src/hyper"
|
||||
]
|
||||
|
|
|
|||
14
README.md
14
README.md
|
|
@ -9,13 +9,19 @@ Slack Morphism is a modern client library for Slack Web/Events API/Sockets Mode
|
|||
Please follow to the official website: https://slack-rust.abdolence.dev
|
||||
|
||||
## Examples
|
||||
https://github.com/abdolence/slack-morphism-rust/tree/master/src/examples/src
|
||||
|
||||
The example bot requires to work the following environment variables (from your Slack bot profile in api.slack.com):
|
||||
- `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET`, `SLACK_BOT_SCOPE`, `SLACK_REDIRECT_HOST` - for OAuth
|
||||
https://github.com/abdolence/slack-morphism-rust/tree/master/src/hyper/examples
|
||||
|
||||
The examples require to work the following environment variables (from your Slack bot profile in api.slack.com):
|
||||
- `SLACK_TEST_TOKEN` - for Slack client example
|
||||
- `SLACK_TEST_APP_TOKEN` - for Slack client with Socket Mode example
|
||||
- `SLACK_SIGNING_SECRET` for all routes
|
||||
- `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET`, `SLACK_BOT_SCOPE`, `SLACK_REDIRECT_HOST` - for OAuth routes for Events API example
|
||||
- `SLACK_SIGNING_SECRET` for all routes for Events API example
|
||||
|
||||
To run example use with environment variables:
|
||||
```
|
||||
# SLACK_... cargo run --example <client|events_api_server|socket_mode>
|
||||
```
|
||||
|
||||
Routes for this example are available on http://<your-host>:8080:
|
||||
|
||||
|
|
|
|||
|
|
@ -27,3 +27,11 @@ use slack_morphism_models::events::*; // Slack Events Models
|
|||
|
||||
use slack_morphism_hyper::*; // Hyper/Tokio client implementation
|
||||
```
|
||||
|
||||
## Ready to use examples
|
||||
-
|
||||
- Slack Web API client
|
||||
- Events API
|
||||
- Slack Web API client with Socket Mode
|
||||
|
||||
You can find them on [github](https://github.com/abdolence/slack-morphism-rust/tree/master/src/hyper/examples)
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
[package]
|
||||
name = "slack-morphism-examples"
|
||||
version = "0.10.0"
|
||||
authors = ["Abdulla Abdurakhmanov <abdulla@latestbit.com>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
slack-morphism-models = { path = "../models", version = "^0.10.0"}
|
||||
slack-morphism-hyper = { path = "../hyper", version = "^0.10.0"}
|
||||
slack-morphism = { path = "../client", version = "^0.10.0"}
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
serde_with = "1.4"
|
||||
futures = "0.3"
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
hyper = { version ="0.14", features = ["full"] }
|
||||
log = "0.4"
|
||||
fern = { version = "0.6", features = ["colored"] }
|
||||
rsb_derive = "0.3"
|
||||
http = "0.2"
|
||||
|
||||
[package.metadata.release]
|
||||
disable-tag=true
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
use chrono::prelude::*;
|
||||
use rsb_derive::Builder;
|
||||
use slack_morphism_models::blocks::*;
|
||||
use slack_morphism_models::*;
|
||||
|
||||
#[derive(Debug, Clone, Builder)]
|
||||
pub struct WelcomeMessageTemplateParams {
|
||||
pub user_id: SlackUserId,
|
||||
}
|
||||
|
||||
impl SlackMessageTemplate for WelcomeMessageTemplateParams {
|
||||
fn render_template(&self) -> SlackMessageContent {
|
||||
SlackMessageContent::new()
|
||||
.with_text(format!("Hey {}", self.user_id.to_slack_format()))
|
||||
.with_blocks(slack_blocks![
|
||||
some_into(
|
||||
SlackSectionBlock::new()
|
||||
.with_text(md!("Hey {}", self.user_id.to_slack_format()))
|
||||
),
|
||||
some_into(SlackDividerBlock::new()),
|
||||
some_into(SlackContextBlock::new(slack_blocks![
|
||||
some(md!("This is an example of block message")),
|
||||
some(md!(
|
||||
"Current time is: {}",
|
||||
fmt_slack_date(
|
||||
Local::now(),
|
||||
SlackDateTimeFormats::DatePretty.to_string().as_str(),
|
||||
None
|
||||
)
|
||||
))
|
||||
])),
|
||||
some_into(SlackDividerBlock::new()),
|
||||
some_into(SlackImageBlock::new(
|
||||
"https://www.gstatic.com/webp/gallery3/2_webp_ll.png".into(),
|
||||
"Test Image".into()
|
||||
)),
|
||||
some_into(SlackActionsBlock::new(slack_blocks![some_into(
|
||||
SlackBlockButtonElement::new(
|
||||
"simple-message-button".into(),
|
||||
pt!("Simple button text")
|
||||
)
|
||||
)]))
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Builder)]
|
||||
pub struct SlackHomeNewsItem {
|
||||
pub title: String,
|
||||
pub body: String,
|
||||
pub published: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Builder)]
|
||||
pub struct SlackHomeTabBlocksTemplateExample {
|
||||
pub latest_news: Vec<SlackHomeNewsItem>,
|
||||
pub user_id: SlackUserId,
|
||||
}
|
||||
|
||||
impl SlackBlocksTemplate for SlackHomeTabBlocksTemplateExample {
|
||||
fn render_template(&self) -> Vec<SlackBlock> {
|
||||
slack_blocks![
|
||||
some_into(
|
||||
SlackSectionBlock::new()
|
||||
.with_text(md!("Home tab for {}", self.user_id.to_slack_format()))
|
||||
),
|
||||
some_into(SlackContextBlock::new(slack_blocks![
|
||||
some(md!("This is an example of home tab")),
|
||||
some(md!(
|
||||
"Current time is: {}",
|
||||
fmt_slack_date(
|
||||
Local::now(),
|
||||
SlackDateTimeFormats::DatePretty.to_string().as_str(),
|
||||
None
|
||||
)
|
||||
))
|
||||
]))
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -45,5 +45,10 @@ http = "0.2"
|
|||
tokio-tungstenite = { version = "0.15.0", features = ["rustls-tls"] }
|
||||
rand = "0.8.4"
|
||||
|
||||
[dev-dependencies]
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
log = "0.4"
|
||||
fern = { version = "0.6", features = ["colored"] }
|
||||
|
||||
[package.metadata.release]
|
||||
disable-tag=true
|
||||
|
|
|
|||
186
src/hyper/examples/client.rs
Normal file
186
src/hyper/examples/client.rs
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
use chrono::prelude::*;
|
||||
use slack_morphism::prelude::*;
|
||||
use slack_morphism_hyper::*;
|
||||
|
||||
use rsb_derive::Builder;
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use futures::stream::BoxStream;
|
||||
use futures::TryStreamExt;
|
||||
|
||||
async fn test_client() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let client = SlackClient::new(SlackClientHyperConnector::new());
|
||||
let token_value: SlackApiTokenValue = config_env_var("SLACK_TEST_TOKEN")?.into();
|
||||
let token: SlackApiToken = SlackApiToken::new(token_value);
|
||||
let session = client.open_session(&token);
|
||||
println!("{:#?}", session);
|
||||
|
||||
let test: SlackApiTestResponse = session
|
||||
.api_test(&SlackApiTestRequest::new().with_foo("Test".into()))
|
||||
.await?;
|
||||
|
||||
println!("{:#?}", test);
|
||||
|
||||
let message = WelcomeMessageTemplateParams::new("".into());
|
||||
|
||||
let post_chat_req =
|
||||
SlackApiChatPostMessageRequest::new("#general".into(), message.render_template());
|
||||
|
||||
let post_chat_resp = session.chat_post_message(&post_chat_req).await?;
|
||||
println!("post chat resp: {:#?}", &post_chat_resp);
|
||||
|
||||
let scroller_req: SlackApiUsersListRequest = SlackApiUsersListRequest::new().with_limit(1);
|
||||
let scroller = scroller_req.scroller();
|
||||
|
||||
let mut resp_stream: BoxStream<ClientResult<SlackApiUsersListResponse>> =
|
||||
scroller.to_stream(&session);
|
||||
|
||||
while let Some(item) = resp_stream.try_next().await? {
|
||||
println!("res: {:#?}", item.members);
|
||||
}
|
||||
|
||||
let collected_members: Vec<SlackUser> = scroller
|
||||
.collect_items_stream(&session, Duration::from_millis(1000))
|
||||
.await?;
|
||||
println!("collected res: {:#?}", collected_members);
|
||||
|
||||
let mut items_stream = scroller.to_items_stream(&session);
|
||||
while let Some(items) = items_stream.try_next().await? {
|
||||
println!("res: {:#?}", items);
|
||||
}
|
||||
|
||||
let mut items_throttled_stream =
|
||||
scroller.to_items_throttled_stream(&session, Duration::from_millis(500));
|
||||
while let Some(items) = items_throttled_stream.try_next().await? {
|
||||
println!("res: {:#?}", items);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Builder)]
|
||||
pub struct WelcomeMessageTemplateParams {
|
||||
pub user_id: SlackUserId,
|
||||
}
|
||||
|
||||
impl SlackMessageTemplate for WelcomeMessageTemplateParams {
|
||||
fn render_template(&self) -> SlackMessageContent {
|
||||
SlackMessageContent::new()
|
||||
.with_text(format!("Hey {}", self.user_id.to_slack_format()))
|
||||
.with_blocks(slack_blocks![
|
||||
some_into(
|
||||
SlackSectionBlock::new()
|
||||
.with_text(md!("Hey {}", self.user_id.to_slack_format()))
|
||||
),
|
||||
some_into(SlackDividerBlock::new()),
|
||||
some_into(SlackContextBlock::new(slack_blocks![
|
||||
some(md!("This is an example of block message")),
|
||||
some(md!(
|
||||
"Current time is: {}",
|
||||
fmt_slack_date(
|
||||
Local::now(),
|
||||
SlackDateTimeFormats::DatePretty.to_string().as_str(),
|
||||
None
|
||||
)
|
||||
))
|
||||
])),
|
||||
some_into(SlackDividerBlock::new()),
|
||||
some_into(SlackImageBlock::new(
|
||||
"https://www.gstatic.com/webp/gallery3/2_webp_ll.png".into(),
|
||||
"Test Image".into()
|
||||
)),
|
||||
some_into(SlackActionsBlock::new(slack_blocks![some_into(
|
||||
SlackBlockButtonElement::new(
|
||||
"simple-message-button".into(),
|
||||
pt!("Simple button text")
|
||||
)
|
||||
)]))
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Builder)]
|
||||
pub struct SlackHomeNewsItem {
|
||||
pub title: String,
|
||||
pub body: String,
|
||||
pub published: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Builder)]
|
||||
pub struct SlackHomeTabBlocksTemplateExample {
|
||||
pub latest_news: Vec<SlackHomeNewsItem>,
|
||||
pub user_id: SlackUserId,
|
||||
}
|
||||
|
||||
impl SlackBlocksTemplate for SlackHomeTabBlocksTemplateExample {
|
||||
fn render_template(&self) -> Vec<SlackBlock> {
|
||||
slack_blocks![
|
||||
some_into(
|
||||
SlackSectionBlock::new()
|
||||
.with_text(md!("Home tab for {}", self.user_id.to_slack_format()))
|
||||
),
|
||||
some_into(SlackContextBlock::new(slack_blocks![
|
||||
some(md!("This is an example of home tab")),
|
||||
some(md!(
|
||||
"Current time is: {}",
|
||||
fmt_slack_date(
|
||||
Local::now(),
|
||||
SlackDateTimeFormats::DatePretty.to_string().as_str(),
|
||||
None
|
||||
)
|
||||
))
|
||||
]))
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn init_log() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
use fern::colors::{Color, ColoredLevelConfig};
|
||||
|
||||
let colors_level = ColoredLevelConfig::new()
|
||||
.info(Color::Green)
|
||||
.warn(Color::Magenta);
|
||||
|
||||
fern::Dispatch::new()
|
||||
// Perform allocation-free log formatting
|
||||
.format(move |out, message, record| {
|
||||
out.finish(format_args!(
|
||||
"{}[{}][{}] {}{}\x1B[0m",
|
||||
chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
|
||||
record.target(),
|
||||
colors_level.color(record.level()),
|
||||
format_args!(
|
||||
"\x1B[{}m",
|
||||
colors_level.get_color(&record.level()).to_fg_str()
|
||||
),
|
||||
message
|
||||
))
|
||||
})
|
||||
// Add blanket level filter -
|
||||
.level(log::LevelFilter::Debug)
|
||||
// - and per-module overrides
|
||||
.level_for("slack_morphism", log::LevelFilter::Trace)
|
||||
.level_for("slack_morphism_hyper", log::LevelFilter::Trace)
|
||||
.level_for("hyper", log::LevelFilter::Info)
|
||||
.level_for("rustls", log::LevelFilter::Info)
|
||||
// Output to stdout, files, and other Dispatch configurations
|
||||
.chain(std::io::stdout())
|
||||
// Apply globally
|
||||
.apply()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn config_env_var(name: &str) -> Result<String, String> {
|
||||
std::env::var(name).map_err(|e| format!("{}: {}", name, e))
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
init_log()?;
|
||||
|
||||
test_client().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -1,70 +1,12 @@
|
|||
use slack_morphism::prelude::*;
|
||||
use slack_morphism_hyper::*;
|
||||
|
||||
use futures::stream::BoxStream;
|
||||
use futures::TryStreamExt;
|
||||
use std::time::Duration;
|
||||
|
||||
use hyper::service::{make_service_fn, service_fn};
|
||||
use hyper::{Body, Request, Response};
|
||||
use log::*;
|
||||
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
mod templates;
|
||||
use templates::*;
|
||||
|
||||
#[allow(dead_code)]
|
||||
async fn test_client() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let client = SlackClient::new(SlackClientHyperConnector::new());
|
||||
let token_value: SlackApiTokenValue = config_env_var("SLACK_TEST_TOKEN")?.into();
|
||||
let token: SlackApiToken = SlackApiToken::new(token_value);
|
||||
let session = client.open_session(&token);
|
||||
println!("{:#?}", session);
|
||||
|
||||
let test: SlackApiTestResponse = session
|
||||
.api_test(&SlackApiTestRequest::new().with_foo("Test".into()))
|
||||
.await?;
|
||||
|
||||
println!("{:#?}", test);
|
||||
|
||||
let message = WelcomeMessageTemplateParams::new("".into());
|
||||
|
||||
let post_chat_req =
|
||||
SlackApiChatPostMessageRequest::new("#general".into(), message.render_template());
|
||||
|
||||
let post_chat_resp = session.chat_post_message(&post_chat_req).await?;
|
||||
println!("post chat resp: {:#?}", &post_chat_resp);
|
||||
|
||||
let scroller_req: SlackApiUsersListRequest = SlackApiUsersListRequest::new().with_limit(1);
|
||||
let scroller = scroller_req.scroller();
|
||||
|
||||
let mut resp_stream: BoxStream<ClientResult<SlackApiUsersListResponse>> =
|
||||
scroller.to_stream(&session);
|
||||
|
||||
while let Some(item) = resp_stream.try_next().await? {
|
||||
println!("res: {:#?}", item.members);
|
||||
}
|
||||
|
||||
let collected_members: Vec<SlackUser> = scroller
|
||||
.collect_items_stream(&session, Duration::from_millis(1000))
|
||||
.await?;
|
||||
println!("collected res: {:#?}", collected_members);
|
||||
|
||||
let mut items_stream = scroller.to_items_stream(&session);
|
||||
while let Some(items) = items_stream.try_next().await? {
|
||||
println!("res: {:#?}", items);
|
||||
}
|
||||
|
||||
let mut items_throttled_stream =
|
||||
scroller.to_items_throttled_stream(&session, Duration::from_millis(500));
|
||||
while let Some(items) = items_throttled_stream.try_next().await? {
|
||||
println!("res: {:#?}", items);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn test_oauth_install_function(
|
||||
resp: SlackOAuthV2AccessTokenResponse,
|
||||
_client: Arc<SlackHyperClient>,
|
||||
|
|
@ -115,14 +57,6 @@ async fn test_command_events_function(
|
|||
))
|
||||
}
|
||||
|
||||
async fn test_push_events_sm_function(
|
||||
event: SlackPushEventCallback,
|
||||
_client: Arc<SlackHyperClient>,
|
||||
_states: Arc<RwLock<SlackClientEventsUserStateStorage>>,
|
||||
) {
|
||||
println!("{:#?}", event);
|
||||
}
|
||||
|
||||
fn test_error_handler(
|
||||
err: Box<dyn std::error::Error + Send + Sync>,
|
||||
_client: Arc<SlackHyperClient>,
|
||||
|
|
@ -137,7 +71,6 @@ fn test_error_handler(
|
|||
#[derive(Debug)]
|
||||
struct UserStateExample(u64);
|
||||
|
||||
#[allow(dead_code)]
|
||||
async fn test_server() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let client: Arc<SlackHyperClient> =
|
||||
Arc::new(SlackClient::new(SlackClientHyperConnector::new()));
|
||||
|
|
@ -219,38 +152,6 @@ async fn test_server() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|||
})
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
async fn test_client_with_socket_mode() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let client = Arc::new(SlackClient::new(SlackClientHyperConnector::new()));
|
||||
|
||||
let socket_mode_callbacks = SlackSocketModeListenerCallbacks::new()
|
||||
.with_command_events(test_command_events_function)
|
||||
.with_interaction_events(test_interaction_events_function)
|
||||
.with_interaction_events(test_interaction_events_function)
|
||||
.with_push_events(test_push_events_sm_function);
|
||||
|
||||
let listener_environment = Arc::new(
|
||||
SlackClientEventsListenerEnvironment::new(client.clone())
|
||||
.with_error_handler(test_error_handler)
|
||||
.with_user_state(UserStateExample(0)),
|
||||
);
|
||||
|
||||
let socket_mode_listener = SlackClientSocketModeListener::new(
|
||||
&SlackClientSocketModeConfig::new(),
|
||||
listener_environment.clone(),
|
||||
socket_mode_callbacks,
|
||||
);
|
||||
|
||||
let app_token_value: SlackApiTokenValue = config_env_var("SLACK_TEST_APP_TOKEN")?.into();
|
||||
let app_token: SlackApiToken = SlackApiToken::new(app_token_value);
|
||||
|
||||
socket_mode_listener.listen_for(&app_token).await?;
|
||||
|
||||
socket_mode_listener.serve().await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn init_log() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
use fern::colors::{Color, ColoredLevelConfig};
|
||||
|
||||
|
|
@ -296,8 +197,7 @@ pub fn config_env_var(name: &str) -> Result<String, String> {
|
|||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
init_log()?;
|
||||
|
||||
//test_server().await?;
|
||||
test_client_with_socket_mode().await?;
|
||||
test_server().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
123
src/hyper/examples/socket_mode.rs
Normal file
123
src/hyper/examples/socket_mode.rs
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
use slack_morphism::prelude::*;
|
||||
use slack_morphism_hyper::*;
|
||||
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
async fn test_interaction_events_function(
|
||||
event: SlackInteractionEvent,
|
||||
_client: Arc<SlackHyperClient>,
|
||||
_states: Arc<RwLock<SlackClientEventsUserStateStorage>>,
|
||||
) {
|
||||
println!("{:#?}", event);
|
||||
}
|
||||
|
||||
async fn test_command_events_function(
|
||||
event: SlackCommandEvent,
|
||||
_client: Arc<SlackHyperClient>,
|
||||
_states: Arc<RwLock<SlackClientEventsUserStateStorage>>,
|
||||
) -> Result<SlackCommandEventResponse, Box<dyn std::error::Error + Send + Sync>> {
|
||||
println!("{:#?}", event);
|
||||
Ok(SlackCommandEventResponse::new(
|
||||
SlackMessageContent::new().with_text("Working on it".into()),
|
||||
))
|
||||
}
|
||||
|
||||
async fn test_push_events_sm_function(
|
||||
event: SlackPushEventCallback,
|
||||
_client: Arc<SlackHyperClient>,
|
||||
_states: Arc<RwLock<SlackClientEventsUserStateStorage>>,
|
||||
) {
|
||||
println!("{:#?}", event);
|
||||
}
|
||||
|
||||
fn test_error_handler(
|
||||
err: Box<dyn std::error::Error + Send + Sync>,
|
||||
_client: Arc<SlackHyperClient>,
|
||||
_states: Arc<RwLock<SlackClientEventsUserStateStorage>>,
|
||||
) -> http::StatusCode {
|
||||
println!("{:#?}", err);
|
||||
|
||||
// Defines what we return Slack server
|
||||
http::StatusCode::BAD_REQUEST
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
async fn test_client_with_socket_mode() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let client = Arc::new(SlackClient::new(SlackClientHyperConnector::new()));
|
||||
|
||||
let socket_mode_callbacks = SlackSocketModeListenerCallbacks::new()
|
||||
.with_command_events(test_command_events_function)
|
||||
.with_interaction_events(test_interaction_events_function)
|
||||
.with_interaction_events(test_interaction_events_function)
|
||||
.with_push_events(test_push_events_sm_function);
|
||||
|
||||
let listener_environment = Arc::new(
|
||||
SlackClientEventsListenerEnvironment::new(client.clone())
|
||||
.with_error_handler(test_error_handler),
|
||||
);
|
||||
|
||||
let socket_mode_listener = SlackClientSocketModeListener::new(
|
||||
&SlackClientSocketModeConfig::new(),
|
||||
listener_environment.clone(),
|
||||
socket_mode_callbacks,
|
||||
);
|
||||
|
||||
let app_token_value: SlackApiTokenValue = config_env_var("SLACK_TEST_APP_TOKEN")?.into();
|
||||
let app_token: SlackApiToken = SlackApiToken::new(app_token_value);
|
||||
|
||||
socket_mode_listener.listen_for(&app_token).await?;
|
||||
|
||||
socket_mode_listener.serve().await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn init_log() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
use fern::colors::{Color, ColoredLevelConfig};
|
||||
|
||||
let colors_level = ColoredLevelConfig::new()
|
||||
.info(Color::Green)
|
||||
.warn(Color::Magenta);
|
||||
|
||||
fern::Dispatch::new()
|
||||
// Perform allocation-free log formatting
|
||||
.format(move |out, message, record| {
|
||||
out.finish(format_args!(
|
||||
"{}[{}][{}] {}{}\x1B[0m",
|
||||
chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
|
||||
record.target(),
|
||||
colors_level.color(record.level()),
|
||||
format_args!(
|
||||
"\x1B[{}m",
|
||||
colors_level.get_color(&record.level()).to_fg_str()
|
||||
),
|
||||
message
|
||||
))
|
||||
})
|
||||
// Add blanket level filter -
|
||||
.level(log::LevelFilter::Debug)
|
||||
// - and per-module overrides
|
||||
.level_for("slack_morphism", log::LevelFilter::Trace)
|
||||
.level_for("slack_morphism_hyper", log::LevelFilter::Trace)
|
||||
.level_for("hyper", log::LevelFilter::Info)
|
||||
.level_for("rustls", log::LevelFilter::Info)
|
||||
// Output to stdout, files, and other Dispatch configurations
|
||||
.chain(std::io::stdout())
|
||||
// Apply globally
|
||||
.apply()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn config_env_var(name: &str) -> Result<String, String> {
|
||||
std::env::var(name).map_err(|e| format!("{}: {}", name, e))
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
init_log()?;
|
||||
|
||||
test_client_with_socket_mode().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue