Skip to content

Commit d754fd3

Browse files
authored
Merge pull request #11 from nanato12/feature/sample
Add sample files
2 parents edfb3b9 + 60288e1 commit d754fd3

File tree

7 files changed

+368
-0
lines changed

7 files changed

+368
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ Cargo.lock
88

99
# These are backup files generated by rustfmt
1010
**/*.rs.bk
11+
12+
# enviroment value
13+
.env

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,8 @@ bytes = "0.4"
1717
base64 = "0.9.2"
1818
hmac = "0.6.2"
1919
sha2 = "0.7.1"
20+
21+
[dev-dependencies]
22+
dotenv = "0.15.0"
23+
actix-web = "3.3"
24+
actix-rt = "1.0"

examples/create_signature.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
extern crate line_bot_sdk_rust as line;
2+
3+
use line::webhook::validate_signature;
4+
5+
use base64::encode;
6+
use hmac::{Hmac, Mac};
7+
use sha2::Sha256;
8+
9+
// Signature confirmation
10+
pub fn create_signature(channel_secret: &str, body: &str) -> String {
11+
type HmacSha256 = Hmac<Sha256>;
12+
13+
let mut mac =
14+
HmacSha256::new_varkey(channel_secret.as_bytes()).expect("HMAC can take key of any size");
15+
mac.input(body.as_bytes());
16+
return encode(&mac.result().code().to_vec());
17+
}
18+
19+
fn main() {
20+
let channel_secret: &str = "channel_secret";
21+
let request_body: &str = r#"
22+
{
23+
"destination": "xxxxxxxxxx",
24+
"events": [
25+
{
26+
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
27+
"type": "message",
28+
"mode": "active",
29+
"timestamp": 1462629479859,
30+
"source": {
31+
"type": "user",
32+
"userId": "U4af4980629..."
33+
},
34+
"message": {
35+
"id": "325708",
36+
"type": "text",
37+
"text": "@example Hello, world! (love)",
38+
"emojis": [
39+
{
40+
"index": 14,
41+
"length": 6,
42+
"productId": "5ac1bfd5040ab15980c9b435",
43+
"emojiId": "001"
44+
}
45+
],
46+
"mention": {
47+
"mentionees": [
48+
{
49+
"index": 0,
50+
"length": 8,
51+
"userId": "U850014438e..."
52+
}
53+
]
54+
}
55+
}
56+
}
57+
]
58+
}
59+
"#;
60+
let signature: String = create_signature(channel_secret, request_body);
61+
62+
if validate_signature(channel_secret, &signature, request_body) {
63+
println!("Success: {}", signature);
64+
} else {
65+
println!("NG");
66+
}
67+
}

examples/echobot_actix_web.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
extern crate line_bot_sdk_rust as line;
2+
3+
use dotenv::dotenv;
4+
use std::env;
5+
6+
use line::bot::LineBot;
7+
use line::events::messages::MessageType as EventMessageType;
8+
use line::events::{EventType, Events};
9+
use line::messages::{SendMessageType, TextMessage};
10+
11+
use actix_web::web::Bytes;
12+
use actix_web::{post, App, HttpRequest, HttpResponse, HttpServer, Responder};
13+
14+
#[post("/callback")]
15+
async fn callback(req: HttpRequest, bytes: Bytes) -> impl Responder {
16+
let body: &str = &String::from_utf8(bytes.to_vec()).unwrap();
17+
let signature: &str = req
18+
.headers()
19+
.get("x-line-signature")
20+
.unwrap()
21+
.to_str()
22+
.unwrap();
23+
24+
// Get channel secret and access token by environment variable
25+
let channel_secret: &str =
26+
&env::var("LINE_CHANNEL_RECRET").expect("Failed getting LINE_CHANNEL_RECRET");
27+
let access_token: &str =
28+
&env::var("LINE_CHANNEL_ACCESS_TOKEN").expect("Failed getting LINE_CHANNEL_ACCESS_TOKEN");
29+
30+
// LineBot
31+
let bot = LineBot::new(channel_secret, access_token);
32+
33+
// Request body parse
34+
let result: Result<Events, &'static str> = bot.parse_event_request(signature, body);
35+
36+
// Success parsing
37+
if let Ok(res) = result {
38+
for event in res.events {
39+
// MessageEvent only
40+
if let EventType::MessageEvent(message_event) = event.r#type {
41+
// TextMessageEvent only
42+
if let EventMessageType::TextMessage(text_message) = message_event.message.r#type {
43+
// Create TextMessage
44+
let message = SendMessageType::TextMessage(TextMessage {
45+
text: text_message.text,
46+
emojis: None,
47+
});
48+
// Reply message with reply_token
49+
let _res = bot.reply_message(&message_event.reply_token, vec![message]);
50+
}
51+
}
52+
}
53+
return HttpResponse::Ok().body("OK");
54+
}
55+
// Failed parsing
56+
else if let Err(msg) = result {
57+
return HttpResponse::BadRequest().body(msg);
58+
}
59+
HttpResponse::BadRequest().body("Internal Server Error")
60+
}
61+
62+
#[actix_rt::main]
63+
async fn main() -> std::io::Result<()> {
64+
dotenv().ok();
65+
HttpServer::new(|| App::new().service(callback))
66+
.bind("127.0.0.1:8000")?
67+
.run()
68+
.await
69+
}

examples/echobot_rocket.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#![feature(proc_macro_hygiene, decl_macro)]
2+
3+
#[macro_use]
4+
extern crate rocket;
5+
6+
extern crate line_bot_sdk_rust as line;
7+
8+
use dotenv::dotenv;
9+
use std::env;
10+
11+
use rocket::http::Status;
12+
13+
use line::bot::LineBot;
14+
use line::events::messages::MessageType as EventMessageType;
15+
use line::events::{EventType, Events};
16+
use line::messages::{SendMessageType, TextMessage};
17+
use line::support::rocket_support::{Body, Signature};
18+
19+
#[post("/callback", data = "<body>")]
20+
fn callback(signature: Signature, body: Body) -> Status {
21+
// Get channel secret and access token by environment variable
22+
let channel_secret: &str =
23+
&env::var("LINE_CHANNEL_RECRET").expect("Failed getting LINE_CHANNEL_RECRET");
24+
let access_token: &str =
25+
&env::var("LINE_CHANNEL_ACCESS_TOKEN").expect("Failed getting LINE_CHANNEL_ACCESS_TOKEN");
26+
27+
// LineBot
28+
let bot = LineBot::new(channel_secret, access_token);
29+
30+
// Request body parse
31+
let result: Result<Events, &'static str> =
32+
bot.parse_event_request(&signature.key, &body.string);
33+
34+
// Success parsing
35+
if let Ok(res) = result {
36+
for event in res.events {
37+
// MessageEvent only
38+
if let EventType::MessageEvent(message_event) = event.r#type {
39+
// TextMessageEvent only
40+
if let EventMessageType::TextMessage(text_message) = message_event.message.r#type {
41+
// Create TextMessage
42+
let message = SendMessageType::TextMessage(TextMessage {
43+
text: text_message.text,
44+
emojis: None,
45+
});
46+
// Reply message with reply_token
47+
let _res = bot.reply_message(&message_event.reply_token, vec![message]);
48+
}
49+
}
50+
}
51+
return Status::new(200, "OK");
52+
}
53+
// Failed parsing
54+
else if let Err(msg) = result {
55+
return Status::new(500, msg);
56+
}
57+
Status::new(500, "Internal Server Error")
58+
}
59+
60+
fn main() {
61+
dotenv().ok();
62+
rocket::ignite().mount("/", routes![callback]).launch();
63+
}

examples/source_rocket.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#![feature(proc_macro_hygiene)]
2+
#![feature(decl_macro)]
3+
4+
#[macro_use]
5+
extern crate rocket;
6+
7+
extern crate line_bot_sdk_rust as line;
8+
9+
use dotenv::dotenv;
10+
use std::env;
11+
12+
use rocket::http::Status;
13+
14+
use line::bot::LineBot;
15+
use line::events::source::SouceType;
16+
use line::events::{EventType, Events};
17+
use line::messages::{SendMessageType, TextMessage};
18+
use line::support::rocket_support::{Body, Signature};
19+
20+
#[post("/callback", data = "<body>")]
21+
fn callback(signature: Signature, body: Body) -> Status {
22+
// Get channel secret and access token by environment variable
23+
let channel_secret: &str =
24+
&env::var("LINE_CHANNEL_RECRET").expect("Failed getting LINE_CHANNEL_RECRET");
25+
let access_token: &str =
26+
&env::var("LINE_CHANNEL_ACCESS_TOKEN").expect("Failed getting LINE_CHANNEL_ACCESS_TOKEN");
27+
28+
// LineBot
29+
let bot = LineBot::new(channel_secret, access_token);
30+
31+
// Request body parse
32+
let result: Result<Events, &'static str> =
33+
bot.parse_event_request(&signature.key, &body.string);
34+
35+
// Success parsing
36+
if let Ok(res) = result {
37+
for event in res.events {
38+
// MessageEvent only
39+
if let EventType::MessageEvent(message_event) = event.r#type {
40+
// Reply message with reply_token
41+
match message_event.source.r#type {
42+
// By Group
43+
SouceType::Group(source) => {
44+
// Create TextMessage
45+
let message = SendMessageType::TextMessage(TextMessage {
46+
text: format!("Group Id: {}", source.group_id),
47+
emojis: None,
48+
});
49+
let _res = bot.reply_message(&message_event.reply_token, vec![message]);
50+
}
51+
// By Room
52+
SouceType::Room(source) => {
53+
// Create TextMessage
54+
let message = SendMessageType::TextMessage(TextMessage {
55+
text: format!("Room Id: {}", source.room_id),
56+
emojis: None,
57+
});
58+
let _res = bot.reply_message(&message_event.reply_token, vec![message]);
59+
}
60+
// By User
61+
SouceType::User(source) => {
62+
// Create TextMessage
63+
let message = SendMessageType::TextMessage(TextMessage {
64+
text: format!("User Id: {}", source.user_id),
65+
emojis: None,
66+
});
67+
let _res = bot.reply_message(&message_event.reply_token, vec![message]);
68+
}
69+
}
70+
}
71+
}
72+
return Status::new(200, "OK");
73+
}
74+
// Failed parsing
75+
else if let Err(msg) = result {
76+
return Status::new(500, msg);
77+
}
78+
Status::new(500, "Internal Server Error")
79+
}
80+
81+
fn main() {
82+
dotenv().ok();
83+
rocket::ignite().mount("/", routes![callback]).launch();
84+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#![feature(proc_macro_hygiene, decl_macro)]
2+
3+
#[macro_use]
4+
extern crate rocket;
5+
6+
extern crate line_bot_sdk_rust as line;
7+
8+
use dotenv::dotenv;
9+
use std::env;
10+
11+
use rocket::http::Status;
12+
13+
use line::bot::LineBot;
14+
use line::events::{EventType, Events};
15+
use line::messages::Emoji;
16+
use line::messages::{SendMessageType, StickerMessage, TextMessage};
17+
use line::support::rocket_support::{Body, Signature};
18+
19+
#[post("/callback", data = "<body>")]
20+
fn callback(signature: Signature, body: Body) -> Status {
21+
// Get channel secret and access token by environment variable
22+
let channel_secret: &str =
23+
&env::var("LINE_CHANNEL_RECRET").expect("Failed getting LINE_CHANNEL_RECRET");
24+
let access_token: &str =
25+
&env::var("LINE_CHANNEL_ACCESS_TOKEN").expect("Failed getting LINE_CHANNEL_ACCESS_TOKEN");
26+
27+
// LineBot
28+
let bot = LineBot::new(channel_secret, access_token);
29+
30+
// Request body parse
31+
let result: Result<Events, &'static str> =
32+
bot.parse_event_request(&signature.key, &body.string);
33+
34+
// Success parsing
35+
if let Ok(res) = result {
36+
for event in res.events {
37+
// MessageEvent only
38+
if let EventType::MessageEvent(message_event) = event.r#type {
39+
// Create Vec of messages to be sent
40+
let mut messages: Vec<SendMessageType> = Vec::new();
41+
// Add TextMessage
42+
messages.push(SendMessageType::TextMessage(TextMessage {
43+
text: String::from("text message"),
44+
emojis: None,
45+
}));
46+
// Add TextMessage with Emoji
47+
messages.push(SendMessageType::TextMessage(TextMessage {
48+
text: String::from("$ EMOJI!"),
49+
emojis: Some(vec![Emoji {
50+
index: 0,
51+
product_id: String::from("5ac1bfd5040ab15980c9b435"),
52+
emoji_id: String::from("001"),
53+
}]),
54+
}));
55+
// Add StickerMessage
56+
messages.push(SendMessageType::StickerMessage(StickerMessage {
57+
package_id: String::from("1"),
58+
sticker_id: String::from("1"),
59+
}));
60+
println!("{:?}", messages);
61+
// Reply message with reply_token
62+
let _res = bot.reply_message(&message_event.reply_token, messages);
63+
}
64+
}
65+
return Status::new(200, "OK");
66+
}
67+
// Failed parsing
68+
else if let Err(msg) = result {
69+
return Status::new(500, msg);
70+
}
71+
Status::new(500, "Internal Server Error")
72+
}
73+
74+
fn main() {
75+
dotenv().ok();
76+
rocket::ignite().mount("/", routes![callback]).launch();
77+
}

0 commit comments

Comments
 (0)