このドキュメントは、Swift製のウェブアプリケーションフレームワークであるSlimaneを利用した開発の流れを体験することを目的としたチュートリアルです。
このチュートリアルでは、受け取ったメッセージをそのまま返信するだけの簡単なLINE Botを作成し、Dockerを利用してHerokuへデプロイします。
事前準備
下記のアカウントが必要です。
- Heroku
- LINE developers (あらかじめチャンネルを作成しておく)
下記のものをあらかじめインストールしておきます。
- Heroku toolbelt (あらかじめログインしておく)
- Docker
- swiftenv
- npm
また、Swift 3.0の開発版を利用するため、下記のようにしてあらかじめインストールしておいてください。
swiftenv install swift-DEVELOPMENT-SNAPSHOT-2016-05-31-a
Slimane CLIのインストール
下記のようにしてSlimane CLIをインストールします。
npm install -g slimane-cli
##プロジェクトの作成
下記を実行することで、空のSlimaneプロジェクトを生成できます。ここではslimane-tutorial-linebot
というプロジェクト名で生成します。
slimane new slimane-tutorial-linebot
slimane-tutorial-linebot
というディレクトリが生成され、最低限必要なファイルが同時に生成されています。以降の作業は全てこのディレクトリの中で行います。
プロジェクトのビルドと実行
まだ何もコードを書いていませんが、一旦この空のプロジェクトをビルドしてみましょう。下記のようにすることで、Slimaneプロジェクトをビルドできます。
slimane build
しばらく待つとビルドが完了するので、下記のようにして実行します。
slimane run
無事に起動すると3000番ポートを待ち受けるようになっているため、試しにHTTPリクエストを投げてみましょう。
curl 'http://localhost:3000/'
Welcome to Slimane!
というメッセージが返ってくれば成功です。
Dockerイメージのビルド
せっかくなので、このSlimaneアプリケーションをDockerで動かせるようにしてみましょう。下記の内容でDockerfile
と.dockerignore
を作成します。
FROM takebayashi/slimane
.build
.git
Packages
下記のようにしてビルドと実行をしてみます。
docker build -t slimane-tutorial-linebot .
docker run -i -p 3000:3000 -t slimane-tutorial-linebot
さきほどと同じように3000番ポートにリクエストを投げてみて、正常にレスポンスが返ってくれば成功です。
依存パッケージの追加
このチュートリアルでは下記のパッケージを利用することにします。
SwiftLineBot
はLINE Bot APIで利用されるJSONデータのシリアライズおよびデシリアライズを行うライブラリです。Botがコールバックリクエストを受ける際にはJSONデータを一緒に受け取りますが、そのデータのパースなどにこのライブラリを利用します。
HTTPSClient
は、HTTPSリクエストを発行するためのライブラリです。受け取ったメッセージに対して返信を行う際にはHTTP APIをコールする必要があるため、その際にこのライブラリを利用します。
この2つのライブラリを利用できるようにするため、Package.swift
を下記のように変更します。
--- a/Package.swift
+++ b/Package.swift
@@ -3,6 +3,8 @@ import PackageDescription
let package = Package(
name: "slimane-tutorial-linebot",
dependencies: [
- .Package(url: "https://github.com/noppoMan/Slimane.git", majorVersion: 0, minor: 6)
+ .Package(url: "https://github.com/noppoMan/Slimane.git", majorVersion: 0, minor: 6),
+ .Package(url: "https://github.com/takebayashi/SwiftLineBot.git", majorVersion: 0, minor: 0),
+ .Package(url: "https://github.com/VeniceX/HTTPSClient.git", majorVersion: 0, minor: 8)
]
)
設定項目の追加
LINE Botを動かすには、Channel ID、Channel Secret、MIDの3項目が必要となるため、これらを設定値として環境変数から取得できるようにします。
main.swift
にはもともと環境変数から値を取得するコードが含まれているため、その下に上記の設定値を取得するコードを追加します。
--- a/Sources/main.swift
+++ b/Sources/main.swift
@@ -12,6 +12,9 @@ var PORT: Int {
}
let HOST = Process.env["HOST"] ?? "0.0.0.0"
let SLIMANE_ENV = Process.env["SLIMANE_ENV"] ?? "development"
+let LINE_CHANNEL_ID = Process.env["LINE_CHANNEL_ID"]!
+let LINE_CHANNEL_SECRET = Process.env["LINE_CHANNEL_SECRET"]!
+let LINE_CHANNEL_MID = Process.env["LINE_CHANNEL_MID"]!
do {
try launchApp()
Botの実装
実際にLINEメッセージを受け取り返信する部分を実装します。
--- a/Sources/app.swift
+++ b/Sources/app.swift
@@ -1,4 +1,6 @@
import Slimane
+import SwiftLineBot
+import HTTPSClient
func launchApp() throws {
let app = Slimane()
@@ -17,6 +19,58 @@ func launchApp() throws {
}
}
+ app.post("/") { req, responder in
+ switch req.body {
+ case let .buffer(d):
+ for message in ReceivedMessage.parseAll(json: d) {
+ switch message.content {
+ case let textMessage as ReceivedTextMessageContent:
+ // create a message for replying
+ let sendingMessage = SendingMessage(
+ toUsers: [textMessage.fromUser],
+ toChannel: 1383378250, // fixed value
+ eventType: .sendingMessage,
+ content: SendingTextMessageContent(
+ contentType: .text,
+ toType: 1, // fixed value
+ text: "Re: " + textMessage.text
+ )
+ )
+ let serialized = sendingMessage.toJSONString()
+
+ // send the message
+ let uri = URI(scheme: "https", host: "trialbot-api.line.me", port: 443)
+ do {
+ let client = try HTTPSClient.Client(uri: uri)
+ let headers: Headers = [
+ "X-Line-ChannelID": LINE_CHANNEL_ID,
+ "X-Line-ChannelSecret": LINE_CHANNEL_SECRET,
+ "X-Line-Trusted-User-With-ACL": LINE_CHANNEL_MID,
+ "Content-Type": "application/json; charset=UTF-8"
+ ]
+ let response = try client.send(
+ method: .post,
+ uri: "/v1/events",
+ headers: headers,
+ body: Data(serialized)
+ )
+ }
+ catch {
+ print("some errors occured")
+ }
+ break
+ default:
+ print("received unsupported message")
+ break
+ }
+ }
+ default:
+ print("received unsupported request")
+ }
+ responder {
+ Response(body: "OK")
+ }
+ }
print("The server is listening at \(HOST):\(PORT)")
try app.listen(host: HOST, port: PORT)
このコードでは主に以下の処理を行っています。
-
/
へのPOSTリクエストを受け付ける - 受け取ったJSONデータをパースし、受信メッセージ
ReceivedMessage
の配列として受け取る - メッセージコンテントが
ReceivedTextMessageContent
であった場合、返信用メッセージSendingMessage
を作成する
- メッセージ本文は"Re: {受信メッセージ本文}"とする
- 3.で作成したメッセージをJSONデータとしてシリアライズする
-
https://trialbot-api.line.me/v1/events
に対して返信のためのリクエストを送信する
Herokuへのデプロイ
下記のようにしてHeroku上のアプリケーションを作成します。
heroku create
次に、環境変数を設定します。${LINE_CHANNEL_ID}
、${LINE_CHANNEL_SECRET}
、${LINE_CHANNEL_MID}
には実際にはLINE developersで確認した値を入れてください。
heroku config:set LINE_CHANNEL_ID=${LINE_CHANNEL_ID}
heroku config:set LINE_CHANNEL_SECRET=${LINE_CHANNEL_SECRET}
heroku config:set LINE_CHANNEL_MID=${LINE_CHANNEL_MID}
最後に下記のコマンドを実行するとDockerイメージのビルドとHerokuへのpushが行われます(数分かかります)。
heroku container:push web
これでデプロイは完了です。heroku open
を実行するとデプロイしたアプリケーションがウェブブラウザで開きます。Welcome to Slimane!
と表示されていればデプロイ成功です。
Botの設定と動作確認
LINE developersのチャンネル設定画面を開き、Callback URLにheroku open
で開いたURIを入力します。この時、https://xxxxxxxx.herokuapp.com:443/
のようにポート番号をつけた形にします。設定後、Verifyボタンを押してSuccess.
と表示されれば設定完了です。
実際にLINEでチャンネルに対してメッセージを送ってみて、返信メッセージが返ってくれば成功です。
このチュートリアルでは、Slimaneプロジェクトの作成、ビルド、Dockerイメージのビルド、Herokuへのデプロイを学びました。