iT邦幫忙

2021 iThome 鐵人賽

DAY 24
0
自我挑戰組

從無到有打造驗證碼共享的 Line 機器人系列 第 24

LIFF APP 串接發送認證碼 API

今天要結合前兩天的成果,完成 LIFF APP 串接 發送認證碼 API 的功能

目標

要完成的功能有兩個:

  1. 發送 POST Request 到 Google App Script 專案 Send Mail
  2. 根據回應顯示驗證碼送出的結果

發送 POST Request

這邊我們選用 axios 處理 Request,當然如果你習慣用 jQuery AJAX / fetch 也是可以的。

安裝 axios

npm i axios --save-dev

別忘了在 vite.config.js 加上設定:

export default defineConfig({
  plugins: [vue()],
  base: '/{YOUR_PROJECT_NAME}/dist/',
  optimizeDeps: {
    include: ["axios"]
  }
})

use axios send post request

在 src 資料夾底下建立一個 service 資料夾,裡面新增一個 api.js 如下:

import axios from 'axios';

export const sendValidationCodePost = (name, mail, token) => {
    const targetUrl = "YOUR_GAS_API_URL";
    let data = JSON.stringify({name, mail, token});
    return axios.post(targetUrl, data, {
        headers: { 'content-type': 'application/x-www-form-urlencoded' }
    }).then(response => {
        if (response) {
            return response;
        } else {
            return Promise.reject();
        }
    }).catch(error => {
        console.log('error', error);
    });
};

呈現結果

修改 Vue Component

因為我們需要兩個 Component

  1. 實作表單
  2. 呈現結果

所以我們將原本 BindMail.vue 拆成以下三個 Component:

  1. BindMail.vue: 負責初始化 LIFF。BindMail功能的父元素。
  2. BindMailForm.vue: 負責處理表單的呈現與送出。BindMail功能的子元素。
  3. BindMailResult.vue: 負責呈現結果頁面。BindMail功能的子元素。

修改 BindMail.vue 如下

<script setup>
import {onMounted, ref, provide} from 'vue'
import BindMailForm from "./BindMailForm.vue";
import BindMailResult from "./BindMailResult.vue";

const errorMsg = ref("");
// 判斷要顯示表單元件還是結果元件
const bindStep = ref('form');
// API 回應結果
const resMessage = ref('');
provide('resMessage', resMessage);

// 切換至結果元件顯示
const next = (event) => {
  resMessage.value = event
  bindStep.value = 'result'
}

// 判斷是否登入以及是否使用 Line 開啟 LIFF
const initializeApp = () => {
  if (!liff.isLoggedIn() || !liff.isInClient()) {
    errorMsg.value = "please use line liff open";
  }
};

// 初始化 LIFF APP
onMounted(() => {
  liff.init({
    liffId: 'YOUR_LIFF_ID'
  }).then(() => {
    initializeApp();
  }).catch((err) => {
    errorMsg.value = "initialize LIFF fail";
  });
});
</script>

<template>
  <h1>驗證碼小幫手 - 身份認證</h1>
  <component v-if="!errorMsg" :is="(bindStep === 'form') ? BindMailForm : BindMailResult"  @nextStep="next"></component>
  <p v-else class="error">{{ errorMsg }}</p>
</template>

新增 BindMailForm.vue 如下

<script setup>
import {onMounted, ref, defineEmits} from 'vue'
import {sendValidationCodePost} from '/src/service/api'

const userName = ref("");
const userToken = ref("");
const userEmail = ref("");
const inputEmail = ref("");

const emit = defineEmits(['nextStep'])

const submit = (mail) => {
  sendValidationCodePost(userName.value, mail, userToken.value)
      .then((res) => {
        const result = res.data.message;
        emit('nextStep', result);
      })
      .catch((err) => {
        console.log("err: ", err);
      });
}

onMounted(() => {
  liff.ready.then(() => {
    const user = liff.getDecodedIDToken();
    userName.value = user && user.name;
    userToken.value = user && user.sub;
    userEmail.value = user && user.email;
  })
})
</script>

<template>
  <template v-if="userEmail">
    <p>將發送身份認證碼到 {{ userEmail }}</p>
    <button type="button" class="btn" @click="submit(userEmail)">確定</button>
  </template>

  <template v-else>
    <p>發送身份認證碼到 <input type="email" v-model="inputEmail" placeholder="請輸入 Email"></p>
    <button type="button" class="btn" @click="submit(inputEmail)">確定</button>
  </template>
</template>

新增 BindMailResult.vue 如下

<template>
  <p>{{(result === 'success') ? '已將驗證碼發送至信箱' : '發送失敗,請稍後再試'}}</p>
  <button type="button" class="btn" @click="closeLiff">關閉</button>
</template>

<script setup>
import {inject} from "vue";

const result = inject('resMessage');
const closeLiff = () => {
  liff.closeWindow();
}
</script>

接著就可以執行 npm run build,然後將打包好的靜態檔案部署到 Github Pages 測試結果囉~


上一篇
用 Google App Script 實現發送認證碼的 API
下一篇
Line Messaging API 切換圖文選單 Rich Menu
系列文
從無到有打造驗證碼共享的 Line 機器人30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言