-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from nanato12/develop
Release v0.1.0
- Loading branch information
Showing
74 changed files
with
3,540 additions
and
2 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
name: Rust | ||
|
||
on: [pull_request, push] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v1 | ||
- name: Build | ||
run: cargo build --verbose | ||
- name: Run tests | ||
run: cargo test --verbose --tests |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,6 @@ Cargo.lock | |
|
||
# These are backup files generated by rustfmt | ||
**/*.rs.bk | ||
|
||
# enviroment value | ||
.env |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
[package] | ||
name = "line-bot-sdk-rust" | ||
version = "0.1.0" | ||
authors = ["nanato12 <admin@nanato12.info>"] | ||
edition = "2018" | ||
description = "LINE Messaging API SDK for Rust" | ||
readme = "README.md" | ||
repository = "https://github.com/nanato12/line-bot-sdk-rust/" | ||
license = "Apache-2.0" | ||
license-file = "LICENSE" | ||
keywords = ["line", "linebot", "line-bot-sdk", "line-messaging-api"] | ||
categories = ["api-bindings"] | ||
|
||
[features] | ||
default = [] | ||
rocket_support = ["rocket"] | ||
|
||
[dependencies] | ||
rocket = { version = "0.4", optional = true } | ||
reqwest = { version = "0.11.0", features = ["blocking", "json"] } | ||
serde = { version = "1.0", features = ["derive"] } | ||
serde_json = "1.0" | ||
serde_derive = "1.0.97" | ||
chrono = "0.4" | ||
bytes = "0.4" | ||
base64 = "0.9.2" | ||
hmac = "0.6.2" | ||
sha2 = "0.7.1" | ||
|
||
[dev-dependencies] | ||
dotenv = "0.15.0" | ||
actix-web = "3.3" | ||
actix-rt = "1.0" |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,66 @@ | ||
# line-bot-sdk-rust | ||
rust製 linebot sdk | ||
# LINE Messaging API SDK for Rust | ||
## Introduction | ||
The LINE Messaging API SDK for Rust makes it easy to develop bots using LINE Messaging API, and you can create a sample bot within minutes. | ||
## Documentation | ||
See the official API documentation for more information. | ||
- English: <https://developers.line.biz/en/docs/messaging-api/overview/> | ||
- Japanese: <https://developers.line.biz/ja/docs/messaging-api/overview/> | ||
## Requirements | ||
This library requires Rust nightly. | ||
## Installation | ||
``` | ||
[dependencies] | ||
line-bot-sdk-rust = "0.1" | ||
``` | ||
If you use `rocket support`. | ||
``` | ||
[dependencies] | ||
line-bot-sdk-rust = { version = "0.1", features = ["rocket_support"] } | ||
``` | ||
## Configuration | ||
``` | ||
extern crate line_bot_sdk_rust as line; | ||
use line::bot::LineBot; | ||
fn main() { | ||
let bot = LineBot::new("<channel secret>", "<channel access token>"); | ||
} | ||
``` | ||
## How to use | ||
The LINE Messaging API uses the JSON data format. | ||
parse_event_request() will help you to parse the HttpRequest content and return a Result<[Events](`events::Events`) , &'static str> Object. | ||
``` | ||
let result: Result<Events, &'static str> = | ||
bot.parse_event_request(signature, body); | ||
``` | ||
|
||
``` | ||
match result { | ||
Ok(events) => { | ||
for event in events.events { | ||
... | ||
} | ||
} | ||
Err(msg) => {} | ||
} | ||
``` | ||
|
||
## Contributing | ||
Please make a contribution 😆 | ||
|
||
## License | ||
``` | ||
Copyright 2021 nanato12 | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
``` |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
extern crate line_bot_sdk_rust as line; | ||
|
||
use line::webhook::validate_signature; | ||
|
||
use base64::encode; | ||
use hmac::{Hmac, Mac}; | ||
use sha2::Sha256; | ||
|
||
// Signature confirmation | ||
pub fn create_signature(channel_secret: &str, body: &str) -> String { | ||
type HmacSha256 = Hmac<Sha256>; | ||
|
||
let mut mac = | ||
HmacSha256::new_varkey(channel_secret.as_bytes()).expect("HMAC can take key of any size"); | ||
mac.input(body.as_bytes()); | ||
return encode(&mac.result().code().to_vec()); | ||
} | ||
|
||
fn main() { | ||
let channel_secret: &str = "channel_secret"; | ||
let request_body: &str = r#" | ||
{ | ||
"destination": "xxxxxxxxxx", | ||
"events": [ | ||
{ | ||
"replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA", | ||
"type": "message", | ||
"mode": "active", | ||
"timestamp": 1462629479859, | ||
"source": { | ||
"type": "user", | ||
"userId": "U4af4980629..." | ||
}, | ||
"message": { | ||
"id": "325708", | ||
"type": "text", | ||
"text": "@example Hello, world! (love)", | ||
"emojis": [ | ||
{ | ||
"index": 14, | ||
"length": 6, | ||
"productId": "5ac1bfd5040ab15980c9b435", | ||
"emojiId": "001" | ||
} | ||
], | ||
"mention": { | ||
"mentionees": [ | ||
{ | ||
"index": 0, | ||
"length": 8, | ||
"userId": "U850014438e..." | ||
} | ||
] | ||
} | ||
} | ||
} | ||
] | ||
} | ||
"#; | ||
let signature: String = create_signature(channel_secret, request_body); | ||
|
||
if validate_signature(channel_secret, &signature, request_body) { | ||
println!("Success: {}", signature); | ||
} else { | ||
println!("NG"); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
extern crate line_bot_sdk_rust as line; | ||
|
||
use dotenv::dotenv; | ||
use std::env; | ||
|
||
use line::bot::LineBot; | ||
use line::events::messages::MessageType as EventMessageType; | ||
use line::events::{EventType, Events}; | ||
use line::messages::{SendMessageType, TextMessage}; | ||
|
||
use actix_web::web::Bytes; | ||
use actix_web::{post, App, HttpRequest, HttpResponse, HttpServer, Responder}; | ||
|
||
#[post("/callback")] | ||
async fn callback(req: HttpRequest, bytes: Bytes) -> impl Responder { | ||
let body: &str = &String::from_utf8(bytes.to_vec()).unwrap(); | ||
let signature: &str = req | ||
.headers() | ||
.get("x-line-signature") | ||
.unwrap() | ||
.to_str() | ||
.unwrap(); | ||
|
||
// Get channel secret and access token by environment variable | ||
let channel_secret: &str = | ||
&env::var("LINE_CHANNEL_RECRET").expect("Failed getting LINE_CHANNEL_RECRET"); | ||
let access_token: &str = | ||
&env::var("LINE_CHANNEL_ACCESS_TOKEN").expect("Failed getting LINE_CHANNEL_ACCESS_TOKEN"); | ||
|
||
// LineBot | ||
let bot = LineBot::new(channel_secret, access_token); | ||
|
||
// Request body parse | ||
let result: Result<Events, &'static str> = bot.parse_event_request(signature, body); | ||
|
||
// Success parsing | ||
if let Ok(res) = result { | ||
for event in res.events { | ||
// MessageEvent only | ||
if let EventType::MessageEvent(message_event) = event.r#type { | ||
// TextMessageEvent only | ||
if let EventMessageType::TextMessage(text_message) = message_event.message.r#type { | ||
// Create TextMessage | ||
let message = SendMessageType::TextMessage(TextMessage { | ||
text: text_message.text, | ||
emojis: None, | ||
}); | ||
// Reply message with reply_token | ||
let _res = bot.reply_message(&message_event.reply_token, vec![message]); | ||
} | ||
} | ||
} | ||
return HttpResponse::Ok().body("OK"); | ||
} | ||
// Failed parsing | ||
else if let Err(msg) = result { | ||
return HttpResponse::BadRequest().body(msg); | ||
} | ||
HttpResponse::BadRequest().body("Internal Server Error") | ||
} | ||
|
||
#[actix_rt::main] | ||
async fn main() -> std::io::Result<()> { | ||
dotenv().ok(); | ||
HttpServer::new(|| App::new().service(callback)) | ||
.bind("127.0.0.1:8000")? | ||
.run() | ||
.await | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#![feature(proc_macro_hygiene, decl_macro)] | ||
|
||
#[macro_use] | ||
extern crate rocket; | ||
|
||
extern crate line_bot_sdk_rust as line; | ||
|
||
use dotenv::dotenv; | ||
use std::env; | ||
|
||
use rocket::http::Status; | ||
|
||
use line::bot::LineBot; | ||
use line::events::messages::MessageType as EventMessageType; | ||
use line::events::{EventType, Events}; | ||
use line::messages::{SendMessageType, TextMessage}; | ||
use line::support::rocket_support::{Body, Signature}; | ||
|
||
#[post("/callback", data = "<body>")] | ||
fn callback(signature: Signature, body: Body) -> Status { | ||
// Get channel secret and access token by environment variable | ||
let channel_secret: &str = | ||
&env::var("LINE_CHANNEL_RECRET").expect("Failed getting LINE_CHANNEL_RECRET"); | ||
let access_token: &str = | ||
&env::var("LINE_CHANNEL_ACCESS_TOKEN").expect("Failed getting LINE_CHANNEL_ACCESS_TOKEN"); | ||
|
||
// LineBot | ||
let bot = LineBot::new(channel_secret, access_token); | ||
|
||
// Request body parse | ||
let result: Result<Events, &'static str> = | ||
bot.parse_event_request(&signature.key, &body.string); | ||
|
||
// Success parsing | ||
if let Ok(res) = result { | ||
for event in res.events { | ||
// MessageEvent only | ||
if let EventType::MessageEvent(message_event) = event.r#type { | ||
// TextMessageEvent only | ||
if let EventMessageType::TextMessage(text_message) = message_event.message.r#type { | ||
// Create TextMessage | ||
let message = SendMessageType::TextMessage(TextMessage { | ||
text: text_message.text, | ||
emojis: None, | ||
}); | ||
// Reply message with reply_token | ||
let _res = bot.reply_message(&message_event.reply_token, vec![message]); | ||
} | ||
} | ||
} | ||
return Status::new(200, "OK"); | ||
} | ||
// Failed parsing | ||
else if let Err(msg) = result { | ||
return Status::new(500, msg); | ||
} | ||
Status::new(500, "Internal Server Error") | ||
} | ||
|
||
fn main() { | ||
dotenv().ok(); | ||
rocket::ignite().mount("/", routes![callback]).launch(); | ||
} |
Oops, something went wrong.