LoginSignup
21
27

More than 5 years have passed since last update.

LINE BOTをJava Servletでお手軽に作る

Last updated at Posted at 2017-03-26

LINE BOTをJavaのServletを利用してお手軽に作る方法を紹介します
紹介したソースコード一式は https://github.com/riversun/line-bot-servlet-examples.git にあります

LINE BOTをつくる準備

Messaging APIを使える状態になっている前提でかきます。
登録方法などは別の記事に委ねます。

登録はこちらから
https://business.line.me/ja/services/bot

ServletでLINE BOTを作る

HttpServletでLINE BOTを作ります。

LINE公式Github(https://github.com/line/line-bot-sdk-java)ではSpring Bootを利用した例が紹介されています(※)。

今回はSpring Bootではなくて、スッピンのHttpServletでLINE BOTを作りたいと思います。

ご存知のとおりSpring Bootを使うとかなりお手軽にLINE BOTをつくれますが、
HttpServletでもSpring Bootの例と同じくらいのお手軽感をめざします。

そのために、ヘルパーライブラリを用意しました。ライブラリといっても、内部で https://github.com/line/line-bot-sdk-java を利用している薄いラッパーですのでソースを自分のServletにとりこんで利用しても良いとおもいます。メソッド名もSpring Bootの例を参考にしました。

ヘルパーライブラリのソースはこちら
https://github.com/riversun/line-bot-helper

  ※公式SDK(現時点でv1.6.0)にもline-bot-servletというものがあり、
   中身をみるとHttpServlet用の簡易ヘルパークラス(署名検証など)は準備してくれているようですが
   SpringBootのようなevent mappingはしてくれない模様。

メッセージへのお返事BOT をつくる

ユーザーがBOTにむかってテキストメッセージを送ると、BOTがテキストでお返事する、というサンプルです。

コードは以下のようになります。

LineBotExample01Servlet.java
@SuppressWarnings("serial")
public class LineBotExample01Servlet extends LineBotServlet {

    // CHANNEL_SECRETとCHANNEL_ACCESS_TOKENはそのまま文字列で指定可能
    private static final String CHANNEL_SECRET ="取得したものをいれる" ;
    private static final String CHANNEL_ACCESS_TOKEN ="取得したものをいれる";
    @Override
    protected ReplyMessage handleTextMessageEvent(MessageEvent<TextMessageContent> event) throws IOException {

        // ユーザーがBOTに送信したメッセージ
        TextMessageContent userMessage = event.getMessage();

        // ユーザーのProfileを取得する
        UserProfileResponse userProfile = getUserProfile(event.getSource().getUserId());

        // BOTからの返信メッセージ
        String botResponseText = userProfile.getDisplayName() + "さん、"
                + "「" + userMessage.getText() + "」って言いましたね";

        TextMessage textMessage = new TextMessage(botResponseText);

        return new ReplyMessage(event.getReplyToken(), Arrays.asList(textMessage));
    }

    @Override
    protected ReplyMessage handleDefaultMessageEvent(Event event) {
        // overrideしていないメッセージを受信した場合は何もしない(nullを返す)
        return null;
    }

    @Override
    public String getChannelSecret() {
        return CHANNEL_SECRET;
    }

    @Override
    public String getChannelAccessToken() {
        return CHANNEL_ACCESS_TOKEN;
    }

動作イメージ

line_bot_small.png

解説

ユーザーからのテキストメッセージを受信すると、

ReplyMessage handleTextMessageEvent(MessageEvent<TextMessageContent> event)

がコールされますので、このメソッドの中で必要な処理を行います。
この例ではユーザーの発言(テキスト)を取得して、少し加工して返事をします。

以下のよう ReplyMessage を返すと、ユーザー側に返信がおくられます。

return new ReplyMessage(event.getReplyToken(), Arrays.asList(textMessage));

ここを

return null;

にすると、返信はしません。

ちなみに、

Arrays.asList(textMessage)

としている理由は、メッセージは同時に複数返すことができるためです。
たとえば、画像とテキストを同時に返したい場合には、

Arrays.asList(imageMessage,textMessage)

のようにします。

今回の例では、handleTextMessageEventをオーバーライドしましたが、他にも以下のメソッドをオーバーライドすれば、各イベントを受信することができます。

protected ReplyMessage handleImageMessageEvent(MessageEvent<ImageMessageContent> event)
protected ReplyMessage handleLocationMessageEvent(MessageEvent<LocationMessageContent> event)  
protected ReplyMessage handleStickerMessageEvent(MessageEvent<StickerMessageContent> event)  
protected ReplyMessage handleAudioMessageEvent(MessageEvent<AudioMessageContent> event)  
protected ReplyMessage handleVideoMessageEvent(MessageEvent<VideoMessageContent> event)  
protected void handleUnfollowEvent(UnfollowEvent event) 
protected ReplyMessage handleFollowEvent(FollowEvent event) 
protected ReplyMessage handleJoinEvent(JoinEvent event) 
protected void handleLeaveEvent(LeaveEvent event) 
protected ReplyMessage handlePostbackEvent(PostbackEvent event) 
protected ReplyMessage handleBeaconEvent(BeaconEvent event) 

最後に、


@Override
    protected ReplyMessage handleDefaultMessageEvent(Event event) {
        // overrideしていないメッセージを受信した場合は何もしない(nullを返す)
        return null;
    }

ですが、オーバーライドしていないイベントを受信した場合にコールされます。

上記LineBotServletが含まれているヘルパーライブラリを取り込むために、Gradle/Mavenでは以下のように指定します。

Gradle

compile 'org.riversun:line-bot-helper:1.0.0'

Maven

<dependency>
    <groupId>org.riversun</groupId>
    <artifactId>line-bot-helper</artifactId>
    <version>1.0.0</version>
</dependency>

ローカルPCでお手軽に試す

Servletをつくるところまでがこの記事の目的ですがおまけで、ローカルPCで試す方法についても書いておきます。

Servletをつくるところまではだいぶお手軽になりましたが、すぐ試せる、というところだとまだ弱いですね。

わざわざTomcat等立ち上げDeployするのはめんどうですので、servletをお手軽にためせるコンテナJettyを利用しましょう。

Jettyの利用はとっても簡単です。

まずGradle/Mavenに以下を追加します。

Gradle

compile 'org.eclipse.jetty:jetty-server:9.4.0.v20161208'
compile 'org.eclipse.jetty:jetty-webapp:9.4.0.v20161208'

Maven


<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-server</artifactId>
    <version>9.4.0.v20161208</version>
</dependency>
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-webapp</artifactId>
    <version>9.4.0.v20161208</version>
</dependency>

Jettyを起動して、servletにアクセスする

Gradle/Mavenに記述したら、以下のようにコードを書いて実行しましょう。

AppMain.java
public class AppMain {

    public static void main(String[] args) throws Exception {

        ServletHandler handler = new ServletHandler();

        handler.addServletWithMapping(LineBotExample01Servlet.class, "/callback");

        // loclahost:3000でJettyを起動
        Server jetty = new Server(3000);

        jetty.setHandler(handler);
        jetty.start();
        jetty.join();

    }

}

handler.addServletWithMapping(LineBotExample01Servlet.class, "/callback");

にあるとおり、先ほど作成したLineBotExample01Servlet/callbackというパスで受け付けます。

ローカルPCで実行すれば http://127.0.0.1:3000/callback でLINE BOT Servletにアクセスすることができるようになります。

つくったLINE BOT Servletに外部からアクセスできるようにする

せっかくローカルで立ち上げても、LINE BOTとして振舞うには、サーバーにDeployして外部に公開する必要があります。
テスト用途でお手軽にためすため、さきほどJettyをつかってつくったサーバーを外部からアクセスできるようにしましょう。

ここでは、こうした用途にぴったりな ngrok というサービスを使います。

以下から ngrok をダウンロードしておきます
https://ngrok.com/download

コマンドラインで
ngrok http -region=ap 127.0.0.1:3000

とすると、ngrokが開始して以下のような画面が表示されます
ngrok.png

たったこれだけで、
https://xxxxx.ap.ngrok.io というurlが https://127.0.0.1:3000 にマップされました!

(xxxxxの部分はngrokを起動するたびにランダムに変わります。sign upすれば固定することも可能です)

LINE BOTのweb hook urlにはhttpsが求められますのでこれは便利ですね。

ここまでくれば、あとは、以下のurlをWeb Hook URLに登録するだけです。
https://xxxxx.ap.ngrok.io/callback

ngrokのTIPS
-region=apと指定するとAsia Pacificリージョンが選択されますので
日本からアクセスする場合はデフォルトのUSリージョンよりもレイテンシーの面で有利です。

実行します

スマホのLINEアプリからメッセージを入れると
line_bot_small.png

うまくいきました

まとめ

  • 今回は、シンプルなLINE BOTをHttpServletで作る例を紹介しました。
  • ServletをJettyでホストして、ngrokをつかって外部からアクセス可能にしたことで、実際にスマホのLINEアプリからBOTにメッセージを送るテストができました
  • 紹介したソースコード一式は https://github.com/riversun/line-bot-servlet-examples.git にあります

次回は、画像の送受信など、もうすこしハンドリングする素材をふやす例を試したいとおもいます。

21
27
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
27