LIFF×Vue×Flask×Cloud Runアプリ実装(LINEアプリ)①

この記事は、こちらの記事で作成したCloud RunにLIFFの設定をしてLINE上で表示します。

LIFFアプリをチャンネルに追加

公式ドキュメントはこちら

LINE Developersコンソールにアクセス

LINEアカウントでログインを選択

メールアドレス、もしくはQRコードでログインします。

LINEビジネスIDを作成を押下

必須項目を入力してアカウントを作成します。

続いてプロバイダーの作成

プロバイダー名を入力して作成を押下

LINEログインを選択

必要な項目を入力して作成ボタンを押下

これでチャンネルが作成されました。

LIFFアプリ追加

LIFFタブを選択して追加ボタンを押下

必要な項目を入力して追加ボタンを押下

今回はサイズはFull、Scopeはopenid、友だち追加オプションはOn(Normal)を選択

オプションはオフのまま

追加ボタンを押下すると以下のように選択した内容でLIFFが追加されます。

LIFFアプリを開く

発行されたLIFF URLをLINEに貼り付けてタップ

許可するをタップ

前の記事でブラウザで開いたのと同じ画面がLINEブラウザで表示されました。

LIFFをデバッグできるようにする

LIFF Inspectorを導入してデバッグできるようにします。

jsのソースコードに以下のようなコードを追加して、インストールします。
(全体のソースは後ほど記載します)

import liff from '@line/liff';
import LIFFInspectorPlugin from '@line/liff-inspector';

liff.use(new LIFFInspectorPlugin());

以下のコマンドを実行します。

$ npx @line/liff-inspector

以下のようなメッセージが出力されます。

Need to install the following packages:
@line/liff-inspector@1.0.2
Ok to proceed? (y) y

npm warn deprecated acorn-import-assertions@1.9.0: package has been renamed to acorn-import-attributes
Debugger listening on ws://192.168.3.10:9222

You need to serve this server over SSL/TLS
For help, see: https://github.com/line/liff-inspector#important-liff-inspector-server-need-to-be-served-over-ssltls

HTTPSでアクセスできるようにする必要があるっぽいので対応します。(ドキュメントはこちら

mkcertの設定をこの記事のときに対応してるので、今回もそちらを使用します。
以下のコマンドを実行

$ mkcert localhost

実行すると以下のようなメッセージが表示されます。

Note: the local CA is not installed in the Firefox trust store.
Run "mkcert -install" for certificates to be trusted automatically ⚠️

Created a new certificate valid for the following names 📜
 - "localhost"

The certificate is at "./localhost.pem" and the key at "./localhost-key.pem" ✅

It will expire on 30 April 2027 🗓

続いて、以下のコマンドを実行(上記メッセージのcertificate、keyを使用

$ http-server -S -C ./localhost.pem -K ./localhost-key.pem
em -K ./liff.line.me-key.pem
zsh: command not found: http-server

エラーになったので、http-serverをインストール(公式はこちら

$ brew install http-server

再度サーバ起動

$ http-server -S -C ./localhost.pem -K ./localhost-key.pem
Starting up http-server, serving ./ through https

http-server version: 14.1.1

http-server settings: 
CORS: disabled
Cache: 3600 seconds
Connection Timeout: 120 seconds
Directory Listings: visible
AutoIndex: visible
Serve GZIP Files: false
Serve Brotli Files: false
Default File Extension: none

Available on:
  https://127.0.0.1:8080
  https://192.168.3.10:8080
  https://192.168.64.1:8080
Hit CTRL-C to stop the server

とりあえずサーバが起動するところまでは確認できました。

LIFF Cliのインストール

$ npm install -g @line/liff-cli

以下のメッセージが出力されます。

npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE   package: '@line/liff-cli@0.2.0',
npm warn EBADENGINE   required: { npm: '10.7.0', node: '22.2.0' },
npm warn EBADENGINE   current: { node: 'v23.6.1', npm: '10.9.2' }
npm warn EBADENGINE }

added 94 packages in 7s

32 packages are looking for funding
  run `npm fund` for details

warningは出てますが、インストールされました。

LIFF チャネルの追加

liff-cli channel add <作成したチャネル名>

成功のメッセージが出たので、接続確認

$ liff-cli app list --channel-id <作成したチャネル名>

これでリストが参照できたので接続確認完了

LIFF Inspectorを使用して起動

$ liff-cli serve --liff-id <liff-id> --url http://localhost:3000/ --inspect

以下のようなエラーが表示

file:///usr/local/lib/node_modules/@line/liff-cli/dist/serve/serveAction.js:11
        throw new Error(`Access token not found.
              ^

Error: Access token not found.
        Please set the current channel first.
        
    at serveAction (file:///usr/local/lib/node_modules/@line/liff-cli/dist/serve/serveAction.js:11:15)
    at async Command.<anonymous> (file:///usr/local/lib/node_modules/@line/liff-cli/dist/serve/index.js:21:9)

Node.js v23.6.1

チャンネルIDを指定していないのが原因っぽいので指定

$ liff-cli channel use <作成したチャネルID>

再びサーバ起動

$ liff-cli serve --liff-id <liff-id> --url http://localhost:3000/ --inspect

無事、サーバが起動しました。

Successfully updated endpoint url for LIFF ID: <liff-id>

→  LIFF URL:     <url>
→  Proxy server: https://localhost:9000/?li.origin=wss%3A%2F%2Flocalhost%3A9222
Debugger listening on wss://192.168.3.10:9222

You need to serve this server over SSL/TLS
For help, see: https://github.com/line/liff-inspector#important-liff-inspector-server-need-to-be-served-over-ssltls

上記のLIFF URLにアクセスしてみます。

ブラウザは↑のようなエラーになり、ターミナルには以下のメッセージが表示されました。
起動時に指定したポート番号が違ってた様です。

(node:79606) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
/usr/local/lib/node_modules/@line/liff-cli/node_modules/http-proxy/lib/http-proxy/index.js:120
    throw err;
    ^

AggregateError [ECONNREFUSED]: 
    at internalConnectMultiple (node:net:1139:18)
    at afterConnectMultiple (node:net:1712:7) {
  code: 'ECONNREFUSED',
  [errors]: [
    Error: connect ECONNREFUSED ::1:3000
        at createConnectionError (node:net:1675:14)
        at afterConnectMultiple (node:net:1705:16) {
      errno: -61,
      code: 'ECONNREFUSED',
      syscall: 'connect',
      address: '::1',
      port: 3000
    },
    Error: connect ECONNREFUSED 127.0.0.1:3000
        at createConnectionError (node:net:1675:14)
        at afterConnectMultiple (node:net:1705:16) {
      errno: -61,
      code: 'ECONNREFUSED',
      syscall: 'connect',
      address: '127.0.0.1',
      port: 3000
    }
  ]
}

Node.js v23.6.1

単純に、起動したプロキシサーバ(?)https対応するために起動したlocalhostのポートと、
LIFFコンソールで指定したポート番号が違ってただけでした。

$ http-server -S -C ./localhost.pem -K ./localhost-key.pem

上記コマンドを実行したときのメッセージ(上記コマンドは別ウィンドウで実行すること)

Starting up http-server, serving ./ through https

http-server version: 14.1.1

http-server settings: 
CORS: disabled
Cache: 3600 seconds
Connection Timeout: 120 seconds
Directory Listings: visible
AutoIndex: visible
Serve GZIP Files: false
Serve Brotli Files: false
Default File Extension: none

Available on:
  https://127.0.0.1:8080
  https://192.168.3.10:8080
  https://192.168.64.1:8080
  https://192.168.11.107:8080
Hit CTRL-C to stop the server

↑のように8080でポート番号が設定されてるみたいなので、LIFFのコンソールでの設定を変更します。

「liff-cli serve〜」でのURLを以下のように変更します。

$ liff-cli serve --liff-id 2006831755-QxVm4KvW --url http://localhost:9000/templates/index.html --inspect --local-proxy-port 8080

ついでに「liff-cli serve〜」コマンドを実行するとコンソール画面で設定したエンドポイントURLが変わっちゃうみたいなので、ローカルテスト用のLIFFを追加して検証します。

そうすると、jsのエラーは出ているがとりあえずページは開けたっぽい。

LIFFアプリ作成

いろいろ調べたが、これだけじゃ全然足りずこちらの手順が必要みたい。

まずは

$ npx @line/create-liff-app

実行するといろいろ聞かれます。

Welcome to the Create LIFF App
? Enter your project name:  liff-test
? Which template do you want to use? vue
? JavaScript or TypeScript? JavaScript
? Please enter your LIFF ID: 
 Don't you have LIFF ID? Check out https://developers.line.biz/ja/docs/liff/getting-started/ (liffId) 

↑プロジェクト名、使用したいテンプレート、言語、LIFF IDなどが聞かれるので入力

そうすると指定したプロジェクト名のディレクトリができて、その中にLIFF用のファイルが格納されています。

作成されたディレクトリに移動して、LIFFアプリを起動します。

$ cd <ディレクトリ名>
$ yarn dev

表示されるメッセージ

  VITE v6.0.11  ready in 923 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

表示されている「http://localhost:5173/」をブラウザで表示

liffが起動できた。

Python(Flask)とVueの連携

FlaskからVueを起動するには、以下の手順が必要になります。

  1. Vueをビルド
  2. Flaskのtemplateフォルダを1.のビルドされたファイルに変更

1.Vueビルド

vueのルートディレクトリで以下のコマンドを実行

$ npm run build

すると、distというディレクトリが生成されてビルドファイルが格納されます。

これはpublicフォルダに格納されていた静的ファイルと、Vueルート直下のindex.html、Vueファイルなどで生成されたindex.htmlが格納されています。

2.Flaskのtemplateフォルダ変更

Flaskルートフォルダにあるapp.pyの↓を

app = Flask(__name__)

↓変更後

app = Flask(__name__, template_folder=<1.のdistフォルダ>)

公式ドキュメントはこちら

あと、これをcloudbuild.yamlに追加してCloud Runにデプロイしたときに自動実行されるようにします。

steps:
- name: 'node'
  entrypoint: 'npm'
  args: [
    'install',
    '--prefix',
    'templates/liff-test',
    'templates/liff-test'
    ]
- name: 'node'
  entrypoint: 'npm'
  args: [
    'run',
    'build',
    '--prefix',
    'templates/liff-test'
  ]
- name: 'gcr.io/cloud-builders/docker'
  args: [
    'build', 
    '-t', 
    'asia-northeast1-docker.pkg.dev/$_PROJECT_ID/cloud-run-source-deploy/$_SERVICE_NAME:latest', 
    '--cache-from',
    'asia-northeast1-docker.pkg.dev/$_PROJECT_ID/cloud-run-source-deploy/$_SERVICE_NAME:latest', 
    '-f',
    'Dockerfile',
    '--build-arg',
    'PORT=8080',
    '.'
    ]
- name: 'gcr.io/cloud-builders/docker'
  args: [
    'push',
    'asia-northeast1-docker.pkg.dev/$_PROJECT_ID/cloud-run-source-deploy/$_SERVICE_NAME:latest', 
    ]
- name: 'gcr.io/cloud-builders/gcloud'
  args: [
    'run', 
    'deploy', 
    '--project',
    '$_PROJECT_ID',
    '$_SERVICE_NAME', 
    '--image', 
    'asia-northeast1-docker.pkg.dev/$_PROJECT_ID/cloud-run-source-deploy/$_SERVICE_NAME:latest', 
    '--region', 
    'asia-northeast1', 
    '--platform', 
    'managed', 
    '--max-instances',
    '100',
    '--min-instances',
    '0',
    '--memory',
    '256Mi',
    '--timeout',
    '1m',
    '--cpu',
    '1',
    '--concurrency',
    '40',
    '--port',
    '8080',
    '--allow-unauthenticated',
    '--ingress',
    'all',
    ]
images:
- 'asia-northeast1-docker.pkg.dev/$_PROJECT_ID/cloud-run-source-deploy/$_SERVICE_NAME:latest'
options:
  logging: CLOUD_LOGGING_ONLY

npm install〜と、npm run buildコマンドを追加しました。

デプロイして、LINEからアクセスすると↑のようなエラーが出ます。(画面はタイトルのみで真っ白)

先ほど変更したFlaskルートフォルダにあるapp.pyを更に変更します。

app = Flask(__name__, template_folder=<1.のdistフォルダ>, static_folder=<1.のdistフォルダ>, static_url_path='')

LINEで表示

Errorは発生してますが、ようやくVueが動作してる画面まできました。

エラーが発生してたのは、liffのApp.vueの中のliff.init()で以下のようになっていたのですが、
環境変数に設定していないのが原因でした。

  mounted() {
    liff
      .init({
        liffId: import.meta.env.VITE_LIFF_ID
      })

一旦、固定値で直接liffIdを指定すると正常に動作しました。

LIFFが正常に動作することを確認できたところで、
ユーザにメッセージを送信してみます。

    liff
      .init({
        liffId: import.meta.env.VITE_LIFF_ID
      })
      .then(() => {
        this.message = "LIFF init succeeded.";

        liff
          .sendMessages([
            {
              type: "text",
              text: "Hello, World!",
            },
          ])
          .then(() => {
            alert("message sent");
          })
          .catch((err) => {
            alert("error", err);
          });
      })

これが、Keepメモで試してエラーになっていてハマってたんですが、
どうやらKeepメモでは使用できないっぽいです。

そこで自分一人のグループLINEを作成してリンクを貼って試してみます。

リンクをタップして画面を表示すると「Hellow, World!」がメッセージとして送信されていることを確認できました。

sendMessage()のドキュメントはこちら

長くなったので続きはこちらに書きます。

「LIFF×Vue×Flask×Cloud Runアプリ実装(LINEアプリ)①」への4件のフィードバック

コメントする