Upgrade to Pro — share decks privately, control downloads, hide ads and more …

飲食業イベント向けLIFFアプリを開発した話

sumihiro3
December 03, 2022

 飲食業イベント向けLIFFアプリを開発した話

LINE Developer Community忘年LT大会 での発表資料

sumihiro3

December 03, 2022
Tweet

More Decks by sumihiro3

Other Decks in Technology

Transcript

  1. ҿ৯ۀΠϕϯτ޲͚
    -*''ΞϓϦΛ։ൃͨ͠࿩
    -*/&%FWFMPQFS$PNNVOJUZ
    ๨೥-5େձ 2022.12.02
    Sumihiro Kagawa

    View Slide


  2. オフライン会場
    イベント再開︕
    🎉 🎉
    2

    View Slide

  3. ⾃⼰紹介

    View Slide

  4. ⾃⼰紹介
    n 加川 澄廣(かがわ すみひろ)
    l 関⻄在住
    l LINE API Expert (2019.04〜)
    l 所属
    Ø 株式会社ブレイブテクノロジー
    - LINE ミニアプリを利⽤したサービスの開発・運⽤をしています
    - LINE DC での活動が縁で、趣味が仕事に繋がっちゃいました
    l 趣味
    Ø 開発コンテストへの参加
    Ø e-bike でゆるゆる⾛る
    - 時には 100km 超えの⻑距離(アワイチ、かすいち など)も⾛ります
    sumihiro3
    sumihiro.kagawa
    4

    View Slide

  5. 本⽇のテーマ

    View Slide

  6. 飲⾷業イベント向け
    LIFFアプリを開発した話
    6

    View Slide

  7. 開発した LIFF アプリの概要
    nイベント対象飲⾷店で利⽤できるチケットの販売と消費
    - チケットを⼀つ購⼊すると5ポイント付与される
    • 決済⽅法︓クレジットカード、コンビニ決済
    - ポイントを消費して飲⾷店のイベントメニューと引き換え

    View Slide

  8. 開発した LIFF アプリの概要
    n⼀定ポイント数を消費すると抽選権獲得
    - 1チケット分(5ポイント)消費で、抽選を1回できる
    - 抽選には当選(特賞〜3等賞)とハズレがある

    View Slide

  9. システム構成・利⽤技術
    %FWFMPQFS$PNNVOJUZ
    ͳͷͰɺ͔͜͜Β͕ϝΠϯ

    View Slide

  10. システム構成図を⼊れる

    View Slide

  11. 主な利⽤技術(バックエンド)
    利⽤技術 ⽤途など
    CloudRun GCP が提供するサーバーレスのコンテナ実⾏環境
    Ø CI でビルドしたコンテナをデプロイ
    Firestore GCP (Firebase) が提供する NoSQL データベース
    Ø クライアントからも DB にアクセス可能だが、今回はサーバーからのみアクセ

    NestJS バックエンドフレームワーク(Node.js, TypeScript)
    Ø フロント向けの REST API を提供するサーバーアプリケーションを開発
    Ø Open API を活⽤し、API のスキーマ定義からフロントで利⽤する API クライ
    アントを⾃動⽣成
    Ø LINE ログイン認証は Guards を利⽤して共通化

    View Slide

  12. 主な利⽤技術(フロントエンド)
    利⽤技術 ⽤途など
    Nuxt3 Vue.js ⽤フレームワーク
    Ø 2022.11 に stable 版がリリースされたばかり
    Ø 各種レンダリング(SSR, SPA, SSG など)をサポート(今回は SPA を利⽤)
    Ø TypeScript をフルサポート
    OpenAPI
    Generator
    API 定義ファイルから各種⾔語の API クライアントを⽣成
    Ø `TypeScript Axios` で型付きのリクエスト・レスポンス等を⽣成

    View Slide

  13. 主な利⽤技術(SaaS)
    利⽤技術 ⽤途など
    Stripe 決済処理プラットフォーム
    Ø 多様な決済⼿段を⼿軽に利⽤できる(今回はクレジットカード・コンビニ決
    済を利⽤)
    Ø SDK、開発ドキュメントが充実している
    Ø LINE Messaging API と同じ様に、決済イベントを Webhook 受信して処理可

    Ø ダッシュボードが⾒やすい・情報豊富(⾒習いたい)

    View Slide

  14. 今回のアプリ実装での
    ポイント

    View Slide

  15. 1. LINE ログイン認証は NestJS の Guard に⼀任
    n認証処理は⼤事だけど毎回書きたくない︕
    この処理
    https://developers.line.biz/ja/docs/liff/using-user-profile/#sending-id-token

    View Slide

  16. 1. LINE ログイン認証は NestJS の Guard に⼀任
    n ビジネスロジック実⾏前にリクエストを検証できる
    `Guard` で認証処理を実⾏
    l ビジネスロジック⾃体に集中して実装できる
    認証処理は、ここ (Guard) に任せる
    https://docs.nestjs.com/guards
    ビジネスロジックから認証処理を除去で
    きる

    View Slide

  17. 1. LINE ログイン認証は NestJS の Guard に⼀任
    @Get()
    @UseGuards(LiffAuthGuard)
    @ApiOperation({
    operationId: 'Lotteries_findAllʼ,
    summary: '抽選履歴を取得するʼ,
    })
    // <<中略>>
    async findAll(@Req() request: Request): Promise {
    this.logger.debug(`LotteriesController.findAll called`);
    //注⽂履歴取得処理
    // <<後略>>
    }
    各エンドポイントには LINE 認証⽤ Guards の
    利⽤宣⾔のみ
    LINE 認証が成功した場合のみビジネスロジック
    が実⾏される

    View Slide

  18. 1. LINE ログイン認証は NestJS の Guard に⼀任
    export class LiffAuthGuard implements CanActivate {
    private readonly logger = new Logger(LiffAuthGuard.name);
    constructor(
    @Inject(LineService) private readonly lineService: LineService) {}
    async canActivate(context: ExecutionContext): Promise {
    this.logger.debug(`AuthGuard.canActivate called!`);
    const request = context.switchToHttp().getRequest();
    // Get LIFF access token
    const token: string = request.headers.authorization;
    // Verify LIFF access token
    const verifyResult = await this.lineService.verifyLiffToken(token);
    return verifyResult;
    }
    }
    リクエストヘッダーから LIFF アクセストークン
    を取得して検証

    View Slide

  19. 2. クエリパラメーターを保持するために⼀⼯夫いる
    n Nuxt3 では LIFF URL に付けたパラメーターを保持でき
    ない︕︖
    Ø Nuxt3 でパラメーターを付けた LIFF URL からアプリを起動する場合
    に`liff.init()` するとクエリパラメーターが消えてしまった
    https://liff.line.me/12345678-XXXXXX?shop=101&mode=order https://example.com/?shop
    23ίʔυΛಡΈࠐΜͰ
    -*'' ΞϓϦ΁ભҠ
    何故か1つ⽬のパラメーター
    キーだけが残る…

    View Slide

  20. 2. クエリパラメーターを保持するために⼀⼯夫いる
    nLIFF の1次リダイレクト〜2次リダイレクトと、
    VueRouter の挙動に問題がありそう
    2次リダイレクト先
    URL の時点でパラ
    メーターが⽋落してい
    る…
    https://developers.line.biz/ja/docs/liff/opening-liff-app/#redirect-flow

    View Slide

  21. 2. クエリパラメーターを保持するために⼀⼯夫いる
    n【参考】LIFF の1次リダイレクトと2次リダイレクト
    https://developers.line.biz/ja/docs/liff/opening-liff-app/#setting-second-redirect
    URL 種別 URL
    元の URL https://liff.line.me/12345678-XXXXXX?shop=101&mode=order
    1次リダイレクト先 URL
    (LIFF Server で変換)
    https://example.com/?liff.state=urlencoded(shop=101&mode=order)
    2次リダイレクト先 URL
    (`liff.init()` 時に変換)
    https://example.com/?shop=101&mode=order
    https://developers.line.biz/ja/docs/liff/opening-liff-app/#create-a-primary-redirect-url

    View Slide

  22. 2. クエリパラメーターを保持するために⼀⼯夫いる
    nLIFF の2次リダイレクト先 URL への変換前に、
    VueRouter (hash mode) が URL を変更しているの
    が原因の模様
    2次リダイレクト先
    URL への変換でパラ
    メーターが⽋落した
    https://developers.line.biz/ja/docs/liff/opening-liff-app/#redirect-flow
    `liff.init()` 前に、
    VueRouter が URL
    を変換してしまい

    View Slide

  23. 2. クエリパラメーターを保持するために⼀⼯夫いる
    n`liff.init()` が完了する前に URL やパラメーターを変
    更しないでね、と公式ドキュメントに書いてありました
    https://developers.line.biz/ja/reference/liff/#initialize-liff-app

    View Slide

  24. 2. クエリパラメーターを保持するために⼀⼯夫いる
    nVueRouter は `history mode` を利⽤する
    Ø SPA でのみ検証済み
    https://v3.router.vuejs.org/ja/guide/essentials/history-mode.html
    mode URL 特徴
    hash https://example.com/#/shops?shop=101 Ø VueRouter でデフォルトの mode
    Ø ルーティングに URL Hash を使⽤
    Ø URL に `# (hash)` が⼊ってしまう
    Ø 古いブラウザでも動く
    history https://example.com/shops?shop=101 Ø ルーティングに HTML5 の History API を
    使⽤
    Ø URL に `# (hash)` が⼊らない
    Ø サーバーで rewrite 設定が必要

    View Slide

  25. 2. クエリパラメーターを保持するために⼀⼯夫いる
    nVueRouter は `history mode` を利⽤する
    Ø Nuxt3 では “v3.0.0-rc.10” 以降で使える
    - rc-8 で⾊々と試していてハマってました
    - すでに stable 版が出ているので RC 版を使うことはないと思いますが
    Ø Nuxt3 での設定⽅法
    - 公式ドキュメントの `Router Options` 参照
    https://nuxt.com/docs/guide/directory-structure/pages/#custom-history-advanced
    https://github.com/nuxt/framework/releases/tag/v3.0.0-rc.10

    View Slide

  26. まとめ

    View Slide

  27. まとめ
    1. フレームワークをうまく使って楽しよう︕
    Ø エラい⼈の知⾒を活⽤しよう
    Ø API 定義から⾃動⽣成すると楽です
    2. Nuxt / Vue で LIFF アプリを開発する時は、
    VueRouter は `history mode` を使おう
    Ø LIFF の挙動は公式ドキュメントで勉強しよう
    3. Stripe はいいぞ︕
    Ø 決済処理実装がめっちゃ楽でした
    Ø コンビニ決済はセブンイレブンにも対応して欲しい

    View Slide

  28. ご清聴
    ありがとうございました︕

    View Slide

  29. SNS アカウントなど
    @sumihiro3
    Sumihiro.Kagawa
    LINE API Expert
    29

    View Slide

  30. E.O.C.

    View Slide