Laravel+NuxtでLIFFアプリを作ってみた

はじめに

こんにちは、株式会社SCOUTERの開発責任者の小平(@ryotakodaira )です。 業務では、SARDINEという人材紹介会社向けの業務管理システムを開発しています。

日常的な業務とはそこまで関係がありませんが、LINE社が2018年にリリースした LIFF が気になっていたため、普段使っている技術を用いてLIFFを触ってみたので構築内容を紹介していきます。

LIFFとは

LIFFはLINE Front-end Frameworkの略で、LINEのトークルーム内で動作するウェブアプリの実装を可能にするプラットフォームとなっています。

LINEのトークルーム内でLIFFに登録したウェブアプリを開くと、LINEのユーザーIDやユーザー名などを取得することが可能となっています。

そのためウェブアプリでLINEのコンテキストを利用した機能の提供が可能となり、今までのMessagingAPIだけでは出来なかった体験をユーザーに提供することが出来ます。

linecorp.com

流れ

  • LINE Botの準備
  • LIFFで表示するwebページを用意(Nuxt)
  • LINE Botを操作するためのアプリケーションの準備(Laravel)
  • LIFFアプリを登録

Image from Gyazo

LINE Botの準備

LINE Botの作成

  • LINE Developersのアカウントを作成
  • 新規プロバイダーを作成
  • Messaging API で新規チャネルを作成する
    • アプリ名
      • 適当に入力
      • ここでは「サンプルBot」を指定
    • プラン
      • 「Developer Trial」を選択

LINE Botの設定

  • アクセストークン(ロングターム)を発行
    • テストのため失効までの時間を「0時間」で発行する
    • 本番で使うときには失効時間を設定した方が安全です
  • Webhook送信を「利用する」に変更
    • Webhook URL は後ほど設定します
  • 自動応答メッセージを「利用しない」に変更

ここまででLINE Botの基本的な設定は完了となります。

設定画面の一番下にQRコードが表示されていますので、QRコードを読み取って友だち追加を行います。追加後に友だち追加時のメッセージが送られてきていれば成功となります。

LIFFで表示するwebページを用意(Nuxt)

今回はNuxtで作ったwebページをNetlifyで公開することを前提に進めます。

(本来はvue-cliを使ったVueアプリケーションでも良いですが、Nuxtの方が諸々の設定が楽だっったため今回はNuxtを利用しています。)

LIFFのテストを行うためだけで合ってもhttps接続が可能なwebサイトであることをもとられますので、Netlifyやherokuでサクッと静的ファイルをホスティングするのがおすすめです。

JSでLIFFを扱うためのSDKを読み込む

SDKはLINE社がCDNで公開しているため、それを読み込む。

Nuxtは nuxt.config.js でheadタグの設定をすることができるのでNuxtの書き方に従って記述します。

// nuxt.config.js

module.exports = {
  /*
  ** Headers of the page
  */
  head: {
    script: [{ src: 'https://d.line-scdn.net/liff/1.0/sdk.js' }]
  },
}

LIFFで使うページを作成

// pages/index.vue

<template>
  <section class="container">
    <p class="line-id">LINE ID:{{ lineId }}</p>
    <div class="form">
      <div class="control">
        <input class="input" type="text" placeholder="お名前" v-model="formData.name">
      </div>
      <button class="button is-info is-fullwidth" @click="onSubmit()">送信する</button>
      <button class="button is-light is-fullwidth" @click="handleCancel()">キャンセル</button>
    </div>
  </section>
</template>

<script>
export default {
  data() {
    return {
      formData: {
        name: ''
      },
      lineId: null
    }
  },
  mounted() {  
    if (!this.canUseLIFF()) {
      return
    }

    window.liff.init(data => {
      this.lineId = data.context.userId || null
    })
  },
  methods: {
    onSubmit() {
      if (!this.canUseLIFF()) {
        return
      }

      window.liff
        .sendMessages([
          {
            type: 'text',
            text: `お名前:\n${this.formData.name}`
          },
          {
            type: 'text',
            text: '送信が完了しました'
          }
        ])
        .then(() => {
          window.liff.closeWindow()
        })
        .catch(e => {
          window.alert('Error sending message: ' + e)
        })
    },
    handleCancel() {
      if (!this.canUseLIFF()) {
        return
      }
      window.liff.closeWindow()
    },
    canUseLIFF() {
      return navigator.userAgent.indexOf('Line') !== -1 && window.liff
    }
  }
}
</script>

<style>
.container {
  margin: 0 auto;
  padding: 20px;
  min-height: 100vh;
}

.line-id {
  margin-bottom: 30px;
}

.form > * {
  margin-bottom: 10px;
}
</style>
  • mounted()
    • LINEのコンテキストを受け取ってコンポーネントのデータプロパティーに入れています
    • ここではLINEIDをコンテキストから取得してページに表示している
    • 取得できるコンテキストの一覧はこちらを御覧ください
  • onSubmit()
    • でフォームに入力されたテキストをLINEのトークにメッセージを送信している
    • liff.sendMessages() でメッセージを送信することができる
    • 送信が成功したら liff.closeWindow() でLIFFを閉じる
  • canUseLIFF()
    • LIFFを使える状態にあるかをチェックする
    • ユーザーエージェントがLINEか、LIFFのSDKが適切に読み込まれていることを確認している

yarn dev で開発環境を立ち上げると以下の画像のような表示になります。 ここでは、LINEのコンテキストを取得出来ませんので、LINEIDは表示されておらず、「送信する」ボタンをクリックしても何も表示されません。

LIFFアプリを登録

Image from Gyazo

  • LIFFアプリの設定画面より新規作成をします
    • エンドポイント URL に上で作ったNuxtアプリをNetlifyなどで公開したときのURLを入力してください
  • LIFF URL が発行されればLIFFアプリの作成は完了です
    • エンドポイント URLサイズ は後から編集可能です

LINE Botを操作するためのアプリケーションの準備(Laravel)

Laravelアプリケーションを用意

普段からLaravelを使っており、慣れている分素早くアプリケーションを作れるためLaravelを使用しました。 Laravelのインストール方法や初期設定は今回は割愛します。

以下のURLを御覧ください。

qiita.com

ENVの設定

.env ファイルに以下のLINEの情報を追加します。

# .env

LINE_ACCESS_TOKEN={アクセストークン(ロングターム)}
LINE_CHANNEL_SECRET={Channel Secret}

webhookを受けるエンドポイントを用意

// routes/api.php

<?php
/** @var Illuminate\Routing\Router $router */
$router = app('Illuminate\Routing\Router');

$router->post('/line/webhook', 'LineWebHookController@webHook')->name('line.webhook');

飛んでくるリクエスト処理してBotを動作させる処理の作成

// app/Http/Controllers/Api/LineWebHookController.php

<?php
/**
 * Class LineWebHookController
 * @package App\Http\Controllers\Api
 */
class LineWebHookController extends Controller
{

    /**
     * @param Request $request
     * @throws LINEBot\Exception\InvalidSignatureException
     */
    public function webHook(Request $request)
    {
        // Botの印象情報をENVから受け取る
        $lineAccessToken = config('line.access_token');
        $lineChannelSecret = config('line.channel_secret');

        // 署名をチェックする
        // 署名が正しくなければ不正なアクセスとみなして何も行わない
        $signature = $request->headers->get(HTTPHeader::LINE_SIGNATURE);
        if (!SignatureValidator::validateSignature($request->getContent(), $lineChannelSecret, $signature)) {
            return;
        }

        $lineBot = new LINEBot(new CurlHTTPClient ($lineAccessToken), ['channelSecret' => $lineChannelSecret]);

        try {
            // イベントをパースする
            /** @var LINEBot\Event\BaseEvent[]|LINEBot\Event\MessageEvent\TextMessage[] $events */
            $events = $lineBot->parseEventRequest($request->getContent(), $signature);

            foreach ($events as $event) {
                // LINEから送られてきたメッセージの内容を抽出
                $receiveText = '';
                if ($event->getType() === ActionType::MESSAGE && $event->getMessageType() === MessageType::TEXT) {
                    $receiveText = $event->getText();
                }

                // 「liff」と投稿されたら、LIFFアプリを開く
                if ($receiveText === 'liff') {
                    $message = new TextMessageBuilder('line://app/1554604976-anxJ8ogY');
                } else {
                    $message = new TextMessageBuilder('送信ありがとうございます!🙇<200d>');
                }

                // メッセージを送信
                $replyToken = $event->getReplyToken();
                $lineBot->replyMessage($replyToken, $message);
            }
        } catch (Exception $e) {
            logger($e->getMessage());
            return;
        }

        return;
    }
}

webhookURLをLINE Developersの設定画面で設定

LINE Developersで設定を行う前にwebhookURLを公開する必要があります。

今回はサンプルの開発のため、ngrokというサービスを使ってwebhookURLを公開しました。

ngrokの導入についてはこちらの記事を御覧ください。

qiita.com

webhookURLが公開出来たら、Developersの設定画面の「webhook URL」欄に公開したエンドポイントのURL文字列を入力します。

URLの設定後に「接続確認」をクリックして成功すれば設定は完了です。

完成物

LINEのトークルームで「liff」と入力すると、LIFFアプリのURLがBotから送られて来ます。

そのURLをクリックしてLIFFアプリを起動するとLINEユーザーIDが表示されています。

「お名前」フォームにテキストを入力して、送信後、LINEトークルームに入力した内容が投稿されていれば成功です!

Image from Gyazo

まとめ

LIFFという新しい技術を初めて試してみましたが、想像よりも簡単にLIFFアプリを作成することが出来ました。ただ、当然普通のウェブアプリと比べると開発中のデバックが大変でした。LINE上だとコンソールが確認できないため、ウェブアプリ上にプリントしてデバックを行うしかなさそうでした。

LIFFアプリを使えばウェブアプリでLINEのコンテキストを扱うことができるため、LINEBotの可能性が一気に広がったのではないかという印象を受けたため、様々なサービスがLIFFを利用してより良いユーザー体験を提供してくれるのではないでしょうか。

今後、弊社のプロダクトでも機会があれば取り入れたいなと思える機能でした。

最後に

弊社では最新技術のキャッチアップ、プロダクション導入を積極的に行っています!

そして、事業・サービスが成長していくにあたって、これからもメンバーを増やしていきたいと思っています。

興味のある方は下記からご応募いただくか、@ryotakodairaにご連絡ください!!

www.wantedly.com

www.wantedly.com

www.wantedly.com