2023.12.04 追記

line-openapi の公開により、OpenAPIベースのライブラリに更新しました。

 

はじめに

Rustに入門し、早1週間。

Rustの色々な機能やシステムが有能すぎることに気付く。
そして、LINEBotの公式SDKにRustがないことに気付く。

ということで、練習がてらに line-bot-sdk-rust 作りました。

GitHub

 

Crate

 

Documentation

 

LINEBotを動かすための準備

基本的に、rocket や actix-web といったFWを用いて動かします。

LINEBotのためのアカウントの作成方法はこちら
【初心者向け】LINEBOTを作るためのLINE公式アカウント作成・設定

Channel secret と Channel access token (long-lived) の値を保存してください。

動かしてみよう

Rustのフレームワーク rocket を使用して行きます。

とりあえず、cargo new

$ cargo new rust-linebot

Cargo.toml に以下を追記。

[dependencies]
line-bot-sdk-rust = { version = "0.1", features = ["rocket_support"] }
rocket = "0.4"
dotenv = "0.15.0"

.env ファイルを作成

LINE_CHANNEL_RECRET="取得した Channel secret"
LINE_CHANNEL_ACCESS_TOKEN="取得した Channel access token (long-lived)"

main.rs にコードを書いてく。( EchoBot )
送られた文字をそのまま返すBotです。

#![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();
}

そして実行。

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.55s
     Running `target/debug/rust-linebot`
? Configured for development.
    => address: localhost
    => port: 8000
    => log: normal
    => workers: 16
    => secret key: generated
    => limits: forms = 32KiB
    => keep-alive: 5s
    => read timeout: 5s
    => write timeout: 5s
    => tls: disabled
?  Mounting /:
    => POST /callback (callback)
? Rocket has launched from http://localhost:8000

ローカルサーバーが起動したので、LINEBotのWebhookに設定する。

ローカルで建てたサーバーを一時的に外部に公開できる ngrok を使用します。
(ngrok の設定は調べてください。)

8000 ポートを指定して起動します(一応、リージョンは ap )。

$ ngrok http 8000 --region=ap
ngrok by @inconshreveable                                               (Ctrl+C to quit)
                                                                                                               
Session Status                online
Account                       ななといつ (Plan: Free)
Version                       2.3.35
Region                        Asia Pacific (ap)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://cc41bcab451d.ap.ngrok.io -> http://localhost:8000
Forwarding                    https://cc41bcab451d.ap.ngrok.io -> http://localhost:8000
Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00                  

https のURLをwebhookに設定します。

エンドポイントは /callback なので、
https://cc41bcab451d.ap.ngrok.io/callback を設定します。

LINE

メッセージを送信してみる。

LINE

返ってきた。

rocket と ngrok はこんな感じ。

    rocket
POST /callback application/json; charset=utf-8:
    => Matched: POST /callback (callback)
    => Outcome: Success
    => Response succeeded.
    ngrok

HTTP Requests
-------------

POST /callback                 200 OK

ちゃんと、200 のレスポンスを返してる。
おっけい。

書いたコードは一応、ここに置いてあります。
https://github.com/nanato12/rust-linebot

最後に

正直、実装できてない部分があります。
issue 建ててあるので、もし良かったら実装してみてください。

 

あと、Rust初心者なので、

    • ここの書き方きめえよ!

 

    • ここもっといい書き方がある!

 

    Rustの良いところ活かせてない!

とかあればPRください。。。

广告
将在 10 秒后关闭
bannerAds