LIFF アプリでカメラを起動してQRコードを読み取る機能を作って動かしてみた
みなさん、こんにちは!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.json
に workspaces
プロパティを追加します。
{ // ...略 "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 で少し書き直しています。 また、ディレクトリ構成も少し変えています。
まずは、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 アプリを追加する際に、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コードは株式会社デンソーウェーブの登録商標です。