Last active
February 11, 2019 16:13
-
-
Save kornysietsma/63f68258d45080a35af3518d5e06cbbc to your computer and use it in GitHub Desktop.
Slack actions and buttons in rust
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate actix; | |
extern crate actix_web; | |
extern crate bytes; | |
extern crate env_logger; | |
extern crate futures; | |
#[macro_use] | |
extern crate json; | |
#[macro_use] | |
extern crate serde_derive; | |
extern crate serde_json; | |
use actix_web::{ | |
client, error, http, middleware, server, App, AsyncResponder, Error, Form, HttpMessage, | |
HttpRequest, HttpResponse, Json, Result, | |
}; | |
use bytes::BytesMut; | |
use futures::{Future, Stream}; | |
use json::JsonValue; | |
#[derive(Debug, Deserialize)] | |
struct SlackPayload { | |
payload: String, | |
} | |
fn index_slack(params: Form<SlackPayload>) -> Result<HttpResponse> { | |
println!("payload: {:?}", params.payload); | |
// I'm lazy - parsing using json-rust for now rather than creating the types needed for serde | |
let result = json::parse(¶ms.payload); // return Result | |
let response: HttpResponse = match result { | |
Ok(message) => { | |
match message["type"].as_str() { | |
Some("interactive_message") => { | |
// the button | |
HttpResponse::Ok().content_type("application/json").body( | |
object! {"response_type" => "in_channel", | |
"replace_original" => false, | |
"text" => "Ow!" | |
} | |
.dump(), | |
) | |
} | |
Some("message_action") => { | |
// the action | |
let response_url = message["response_url"].as_str().expect("No response url!"); | |
client::ClientRequest::post(response_url) // <- Create request builder | |
.content_type("application/json") | |
.body( | |
object! {"response_type" => "in_channel", "replace_original" => false, "text" => "Pong!"} | |
.dump(), | |
) | |
.unwrap() | |
.send() // <- Send http request | |
.map_err(|_| ()) | |
.and_then(|response| { | |
// <- server http response | |
println!("Slack responded with: {:?}", response); | |
Ok(()) | |
}); // Fails!!! - needs a future here. | |
HttpResponse::Ok().finish() | |
} | |
_ => HttpResponse::BadRequest() | |
.body(format!("Unknown type: {}", message["type"].to_string())), | |
} | |
} | |
Err(e) => HttpResponse::BadRequest().body(e.to_string()), | |
}; | |
Ok(response) | |
} | |
fn main() { | |
::std::env::set_var("RUST_LOG", "actix_web=debug"); | |
env_logger::init(); | |
let sys = actix::System::new("json-example"); | |
server::new(|| { | |
App::new() | |
// enable logger | |
.middleware(middleware::Logger::default()) | |
.resource("/slack", |r| r.method(http::Method::POST).with(index_slack)) | |
}) | |
.bind("127.0.0.1:8080") | |
.unwrap() | |
.shutdown_timeout(1) | |
.start(); | |
println!("Started http server: 127.0.0.1:8080"); | |
let _ = sys.run(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::env; | |
use slack_hook::SlackTextContent::{self, Link, Text, User}; | |
use slack_hook::{ | |
Action, AttachmentBuilder, Field, PayloadBuilder, Slack, SlackLink, SlackText, SlackUserLink, | |
}; | |
pub fn env_hook_url() -> String { | |
env::var("SLACK_HOOK_URL").expect("No SLACK_HOOK_URL found") | |
} | |
pub fn env_channel() -> String { | |
env::var("SLACK_CHANNEL").expect("no SLACK_CHANNEL found") | |
} | |
fn env_username() -> String { | |
env::var("SLACK_NAME").expect("no SLACK_NAME found") | |
} | |
fn main() { | |
let slack = Slack::new(&env_hook_url() as &str).unwrap(); | |
let a = vec![ | |
AttachmentBuilder::new("The one with the action <&>") | |
.text("Ping me!") | |
.callback_id("ping") | |
.color("#6800e8") | |
.fields(vec![Field::new( | |
"Ping please", | |
"(use the \"...\" button to show the action ", | |
None, | |
)]) | |
.build() | |
.unwrap(), | |
AttachmentBuilder::new("The one with the button") | |
.text("Poke me!") | |
.callback_id("poke") | |
.color("#FF50A8") | |
.fields(vec![Field::new( | |
"Poke please", | |
"(with the button below)", | |
None, | |
)]) | |
.actions(vec![Action::new( | |
"button", | |
"poke poke poke", | |
"buttonname", | |
None, | |
Some("value".to_owned()), | |
)]) | |
.build() | |
.unwrap(), | |
]; | |
let p = PayloadBuilder::new() | |
.text("This should have a button and an action!") | |
.channel(env_channel()) | |
.username(env_username()) | |
.icon_emoji(":bubblebobble:") | |
.attachments(a) | |
.build() | |
.unwrap(); | |
let res = slack.send(&p); | |
match res { | |
Ok(()) => println!("ok"), | |
Err(x) => println!("ERR: {:?}", x), | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment