LIFF アプリでカメラを起動してQRコードを読み取る機能を作って動かしてみた

2022.02.17

みなさん、こんにちは!LINE事業部のたにもんです!

QRコードを読み取る LIFF アプリを React で作成し、CloudFront + S3 にデプロイして実際に動かしてみたので、その手順を紹介していきます! 実際に動かしてみると以下のようになりました。 今回は https://classmethod.jp/ のQRコードを読み取ったのですが、ボタンの下に読み取った文字列が表示されているのが分かるかと思います!

今回開発したソースコードはこちらのリポジトリで公開しているので、実装が気になる方は参考にしてください!

環境

  • node: 16.14.0
  • npm: 8.3.1
  • AWS CDK: 2.12.0 (build c9786db)
  • iOS: 15.2.1
  • LINE: 12.1.0

React アプリを CloudFront + S3 にデプロイする

npm workspace を初期化する

今回はフロントエンドとバックエンドを個別の npm パッケージとして開発するために、npm workspace を利用しました。 まずは、以下のコマンドを実行して、package.json ファイルを生成してください。

npm init

次に、以下のように package.jsonworkspaces プロパティを追加します。

{
  // ...略
  "workspaces": [
    "app",
    "backend"
  ]
}

さらに、以下のように npm script を追加しておきましょう。

{
  // ...略
  "scripts": {
    "app:start": "npm start -w app",
    "app:build": "npm run build -w app",
    "backend:build": "npm run build -w backend",
    "test": "npm test --workspaces",
    "predeploy": "npm run app:build && npm run backend:build",
    "deploy": "npm run deploy -w backend"
  },
  // ...略
}

React アプリを作成する

Create React App で React アプリの雛形を作成します。 以下のコマンドを実行してください。

npx create-react-app app --template typescript

CDK で CloudFront + S3 のリソースを定義する

今回は AWS リソースの作成に CDK を利用しました。 CDK での React 用のリソース作成に関しては、以下の記事を参考にしました。 ただし、以下の記事では CDK v1 を利用したコードになっているため、今回は CDK v2 で少し書き直しています。 また、ディレクトリ構成も少し変えています。

AWS CDKでReactアプリをデプロイしてみた

まずは、CDK プロジェクトを作成します。

mkdir backend
cd backend
cdk init --language typescript

すると、lib ディレクトリ下に backend-stack.ts というファイルが作成されるので、以下の内容に書き換えます。

// backend/lib/backend-stack.ts

import * as cdk from 'aws-cdk-lib';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as s3deploy from 'aws-cdk-lib/aws-s3-deployment';
import * as iam from 'aws-cdk-lib/aws-iam';
import { Construct } from 'constructs';

export class BackendStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const websiteBucket = new s3.Bucket(this, 'WebsiteBucket', {
      websiteErrorDocument: 'index.html',
      websiteIndexDocument: 'index.html',
    });

    const websiteIdentity = new cloudfront.OriginAccessIdentity(
      this,
      'WebsiteIdentity'
    );

    const webSiteBucketPolicyStatement = new iam.PolicyStatement({
      actions: ['s3:GetObject'],
      effect: iam.Effect.ALLOW,
      principals: [websiteIdentity.grantPrincipal],
      resources: [`${websiteBucket.bucketArn}/*`],
    });

    websiteBucket.addToResourcePolicy(webSiteBucketPolicyStatement);

    const websiteDistribution = new cloudfront.CloudFrontWebDistribution(
      this,
      'WebsiteDistribution',
      {
        errorConfigurations: [
          {
            errorCachingMinTtl: 300,
            errorCode: 403,
            responseCode: 200,
            responsePagePath: '/index.html',
          },
          {
            errorCachingMinTtl: 300,
            errorCode: 404,
            responseCode: 200,
            responsePagePath: '/index.html',
          },
        ],
        originConfigs: [
          {
            s3OriginSource: {
              s3BucketSource: websiteBucket,
              originAccessIdentity: websiteIdentity,
            },
            behaviors: [
              {
                isDefaultBehavior: true,
              },
            ],
          },
        ],
        priceClass: cloudfront.PriceClass.PRICE_CLASS_ALL,
      }
    );

    new s3deploy.BucketDeployment(this, 'WebsiteDeploy', {
      sources: [s3deploy.Source.asset('../app/build')],
      destinationBucket: websiteBucket,
      distribution: websiteDistribution,
      distributionPaths: ['/*'],
    });
  }
}

AWS にデプロイしてみる

これで、フロントエンドとバックエンドのソースコードの下準備ができたので、AWS にデプロイしてみましょう。 以下のコマンドを実行してください。

npm run deploy

デプロイ完了後、CloudFront のドメインにアクセスすると、以下のような画面が表示されます。

QRコードを読み取る LIFF アプリを作成する

React アプリに LIFF SDK を組み込む

まずは、必要なパッケージをインストールしましょう。 以下のコマンドを実行してください。

npm i @line/liff -w app

次に、app/src/index.tsx を以下のように変更して LIFF の初期化処理を追加します。

// app/src/index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import liff from '@line/liff';

const liffId = process.env.REACT_APP_LIFF_ID!;

liff.init({ liffId }).then(() => {
  ReactDOM.render(
    <React.StrictMode>
      <App />
    </React.StrictMode>,
    document.getElementById('root')
  );
});

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

QRコード読み取り機能を追加する

QRコードの読み取りには、LIFF SDK v2 の scanCodeV2 関数を利用しました。 app/src/index.tsx を以下のように変更してください。 Scan QR Code というボタンをタップするとスキャナが開き、QRコードのスキャンが完了すると、ボタンの下に読み取った文字列を表示するようになっています。

// app/src/index.tsx

import { useState } from 'react';
import logo from './logo.svg';
import './App.css';
import liff from '@line/liff';

function App() {
  const [qrCodeData, setQrCodeData] = useState('');
  const handleScan = () => {
    liff.scanCodeV2().then((result) => {
      setQrCodeData(result.value ?? '');
    });
  };

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <button onClick={handleScan}>Scan QR Code</button>
        <p>{qrCodeData}</p>
      </header>
    </div>
  );
}

export default App;

デプロイして実際に動かしてみる

LINE ログイン / LIFF アプリの登録

LIFF アプリを動かすには、LINE Developers コンソール から、LINE ログインの作成と LIFF アプリの追加を行う必要があります。 これらの手順に関しては以下の記事が参考になると思います。

LIFFアプリを開発メンバーの端末から動作確認できる環境を作る

React と CDK で LIFF アプリを作ってみよう

LIFF アプリを追加する際に、scanCodeV2 を利用するには以下の設定が必要なので注意してください。

設定項目
サイズ Full
Scan QR ON

また、「エンドポイントURL」には CloudFront のドメインを指定してください。

LIFF アプリをデプロイする

今回作成した LIFF アプリは、LIFF ID を環境変数として読み込んでいるため、REACT_APP_LIFF_ID に LIFF ID を設定してください。 LIFF ID は LINE Developers コンソールの「LIFF」タブから確認できます。

環境変数を設定した状態で、以下のコマンドを実行すると、フロントエンドおよびバックエンドのビルドと LIFF アプリのデプロイを行うことができます。

npm run deploy

実際に動かしてみる

デプロイが完了できたら、スマートフォンから「LIFF URL」にアクセスして実際に動かしてみましょう! LIFF URL は LINE Developers コンソールの「LIFF」タブから確認できます。

冒頭でもお見せしたとおり、実際に動かしてみると以下のようになりました。 https://classmethod.jp/ のQRコードを読み取ったのですが、ボタンの下に読み取った文字列が表示されていますね!

QRコードは株式会社デンソーウェーブの登録商標です。