はじめに
LIFFをJavaのWebアプリ上で動かす手段が投稿されていない様だったので、やってみました。
line/line-bot-sdk-java を使う場合、Bot側はWebhookできるように、Spring Boot等でサーバにホストされた状態で利用しているはずなので、その中でLIFF用の画面を作ればいいじゃんね?
ということで、Spring Boot上のThymeleafでLIFFアプリ用の画面を作れることを試しました。
手順
すでに line/line-bot-sdk-java がSpring Boot等で動作している状態を前提とする。URLは ngrok で発行している。
(宣伝:前提までの進め方もふくめて、Javaユーザグループ北海道のハンズオン資料で公開しています)
- ライブラリにThymeleafを追加する
- Spring BootでThymeleafのWebページを表示する
- LIFFのサンプルを表示する
の手順で進める。
1. ライブラリにThymeleafを追加する
プロジェクトファイル(ルートフォルダ)の pom.xml の <properties>〜</properties>
の中に、Thymeleafの記述を追加する。
<properties>
(中略)
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.3.0</thymeleaf-layout-dialect.version>
</properties>
プロジェクトファイル(ルートフォルダ)の pom.xml の <dependencies>〜</dependencies>
の中に、Thymeleafの記述を追加する。(spring-boot-starter-webの下あたり)
<dependencies>
(中略)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
(中略)
</dependencies>
その他のソース(src/main/resources)の application.properties の末尾に、Thymeleafの設定を追加する
## thymeleaf
spring.thymeleaf.mode=HTML
2. Spring BootでThymeleafのWebページを表示する
ファイルの作成
その他のソース(src/main/resources)の templates フォルダの中に liff.html を作成する
(フォルダがない場合は作成する)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>Hello Thymeleaf</title>
</head>
<body>
<h1>[[${test}]]</h1>
</body>
</html>
ソース・パッケージ(src/main/java)に com.example.linebot.web パッケージを作成し、その中に LIFFController クラスを作成する
package com.example.linebot.web;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class LIFFController {
@GetMapping("/liff")
public String hello(Model model) {
// [[${test}]] の部分を Hello... で書き換えて、liff.htmlを表示する
model.addAttribute("test", "Hello Tymeleaf!");
return "liff";
}
}
Thymeleafの動作確認
- LineBotApplication を一度停止して、再起動する
- http://localhost:m8080/liff にアクセスする
- ブラウザに下のように表示されることを確認する
( liff.html の[[${test}]]
の部分を、 LIFFController でセットしたModelの情報で書き換えている)
3. LIFFのサンプルを表示する
ファイルの作成
line/line-liff-starter のサンプルコードを(少し変更して)動作させる。
上記のサイトの liff-starter.js と style.css をコピーして、その他のソース(src/main/resources)の static フォルダの中に複製する
(フォルダがない場合は作成する)
上記のサイトの index.html の内容をもとに、その他のソース(src/main/resources)の templates/liff.html を書き換える。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<!-- The html based on https://github.com/line/line-liff-starter/blob/master/index.html -->
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFF Starter</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>[[${test}]]</h1>
<div class="buttongroup">
<div class="buttonrow">
<button id="openwindowbutton">Open Window</button>
<button id="closewindowbutton">Close Window</button>
</div>
<div class="buttonrow">
<button id="getprofilebutton">Get Profile</button>
<button id="sendmessagebutton">Send Message</button>
</div>
</div>
<div id="profileinfo">
<h2>Profile</h2>
<a href="#" onclick="toggleProfileData()">Close Profile</a>
<div id="profilepicturediv">
</div>
<table border="1">
<tr>
<th>userId</th>
<td id="useridprofilefield"></td>
</tr>
<tr>
<th>displayName</th>
<td id="displaynamefield"></td>
</tr>
<tr>
<th>statusMessage</th>
<td id="statusmessagefield"></td>
</tr>
</table>
</div>
<div id="liffdata">
<h2>LIFF Data</h2>
<table border="1">
<tr>
<th>language</th>
<td id="languagefield"></td>
</tr>
<tr>
<th>context.viewType</th>
<td id="viewtypefield"></td>
</tr>
<tr>
<th>context.userId</th>
<td id="useridfield"></td>
</tr>
<tr>
<th>context.utouId</th>
<td id="utouidfield"></td>
</tr>
<tr>
<th>context.roomId</th>
<td id="roomidfield"></td>
</tr>
<tr>
<th>context.groupId</th>
<td id="groupidfield"></td>
</tr>
</table>
</div>
<script src="https://d.line-scdn.net/liff/1.0/sdk.js"></script>
<script src="liff-starter.js"></script>
</body>
</html>
LIFFアプリとして追加する
LIFFアプリを追加するために、下のコマンドを端末(ターミナル)から実行する。
Windowsの場合はcurlをインストールするか、同等のパラメータでHTTPリクエストが行えるツール(ARCなど)を利用する。
また、line/line-bot-sdk-java には、Javaで動作するLIFF/リッチメニュー登録用のコマンドラインツール(line-bot-cli)も用意されている。
コマンドを実行する場合、以下の部分は個別に編集が必要。
-
"Authorization: Bearer xxxxxx..."
のxxxxxx...
には、Botのアクセストークン(ロングターム)の値を改行なしで貼り付ける(ので、コマンドがとても長くなる) -
"https://xxx.ngrok.io/liff"
のxxx.ngrok.io
は、ngrokで取得したURLにする -
Type
にはcompact
,tall
,full
の三種類があり、LIFFアプリのウィンドウの高さを決める -
url
は https のURLを指定する
curl -XPOST \
-H "Authorization: Bearer xxxxxx..." \
-H "Content-Type: application/json" \
-d '{
"view": {
"type": "tall",
"url": "https://xxx.ngrok.io/liff"
}
}' \
https://api.line.me/liff/v1/apps
成功すれば、liffIdが返信される。
{"liffId":"0000000000-nnnnnnnn"}%
LIFFアプリの動作確認
上記の手順で取得した liffId をもとに、アプリにアクセスするURLを作成する。
URLは、 line://app/
と liffId を結合した line://app/0000000000-nnnnnnnn
となる。
本来はトリガとなる行動にあわせてBotがユーザにURLを発話すれば良いが、ここでは簡易的な動作確認のため、自分でURLを投稿する。
自分が投稿したURL(もしくはBotが発話したURL)をクリックすると、下のようにLIFFアプリが表示される。
特に、Thymeleafにより Hello Thymeleaf!
を表示していること、LIFF APIにより表の中のlanguage
, context.viewType
, context.userId
, context.utouId
などの項目に値が表示されていることを確認する。
Open window
ボタンを押すと、アプリ内ブラウザでlineのホームページが表示される。
Get profile
ボタンを押すと、自分のLINEに設定しているアイコンとプロフィールが表示される。
Send Message
ボタンを押すと、メッセージを送信した旨のダイアログが表示され、自分に You've successfully sent a message! Hooray!
というメッセージと、スタンプが表示される。
このように、LIFFアプリを用いると、LINEのWebサイトにLINEの情報を連携させたり、Webサイト側からLINEのクライアントにイベントを発生させることができる。
LIFFアプリの削除
追加したLIFFアプリを削除するには、下のコマンドを端末(ターミナル)から実行する。
-
0000000000-nnnnnnnn
の部分は、 liffId と置き換える -
"Authorization: Bearer xxxxxx..."
のxxxxxx...
の部分には、Botのアクセストークン(ロングターム)の値を改行なしで貼り付ける
curl -X DELETE https://api.line.me/liff/v1/apps/0000000000-nnnnnnnn \
-H "Authorization: Bearer xxxxxx..."
成功すれば何も表示されない。(失敗時にはエラーメッセージが表示される)
おわりに
Spring Boot上のThymeleafでLINE Appを作れることが確認できた。
Thymeleaf側でFormとかを用意して、フォームで投稿した情報を使うようなLIFFアプリや、ThymeleafとLIFF APIをうまく連携させたLIFFアプリも作れそうですね(作りたい)。