Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

使用 Github + GAS 建立 LIFF 問卷

內容目錄

使用 Github + GAS 建立 LIFF 問卷

之前有個專案需求是透過 LINE bot + Google Form 建立一套可以進行線上預約的LINE OA(官方帳號), 但為了進行 UID 的對應設計一套迂迴的流程,實在不爽快。現在有機會透過 LIFF 導入,能簡化這邊的流程。

由於團隊適應關係,繼續沿用 Google sheet 來做管理,因此需要使用 GAS 來開發一組 API 。

基礎概念很簡單:

  1. 先部署 LIFF 頁面
  2. 製作 LIFF 頁面的問卷
  3. 部署 GAS 為基礎的 API

LIFF 頁面部署

這邊使用的開發環境為 Vite + Vue3.3 + Tailwind + axios。

1. 宣告 LIFF 導入

LIFF 的導入可以參考這篇
宣告 import liff 後,在 onMounted 時宣告 init,如下

import liff from "@line/liff";

onMounted(async () => {
  liff
  .init({
    liffId: "<LIFF ID>", // 從LIFF頁面中拿到的ID
  })
  .then(() => { 
    if(liff.isLoggedIn()){
      //做你想要做的
      isLogin.value = liff.isLoggedIn();
      userid.value = liff.getDecodedIDToken().sub; //這是UID
    }

  })
  .catch((err) => {
    console.log(err.code, err.message);
  });
})

2.在問卷頁中加入送出表單

就是一個 submitForm 。裡面預留 API 的位置,已經撰寫問卷本體。
到這邊 LIFF 大致上就做完了。接下來要部署到 Github Page 上

<form class="flex flex-col items-center" @submit.prevent="submitForm">
<label for="name" class="block mt-4">請問您的姓名:<span class="text-red-500 text-sm">*(請輸入文字)</span></label>
  <input type="text" id="name" v-model="name" placeholder="姓名" class="border border-gray-300 rounded-md px-2 py-1 mt-1" pattern="[A-Za-z]+" title="請輸入有效的姓名(只能包含字母)" required />

  <label for="phone" class="block mt-4">請問您的連絡電話:<span class="text-red-500 text-sm">*(請輸入數字)</span></label>
  <input type="text" id="phone" v-model="phone" placeholder="連絡電話" class="border border-gray-300 rounded-md px-2 py-1 mt-1" pattern="[0-9]+" title="請輸入有效的連絡電話(只能包含數字)" required />

  <label for="purchaseDate" class="block mt-4">請問您的購買時間:</label>
  <input type="date" id="purchaseDate" v-model="purchaseDate" class="border border-gray-300 rounded-md px-2 py-1 mt-1" required />

  <label for="storeAddress" class="block mt-4">請問您購買的經銷門市地址:</label>
  <select id="storeAddress" v-model="storeAddress" class="border border-gray-300 rounded-md px-2 py-1 mt-1" required>
      <option value="">請選擇</option>
      <option value="address1">A門市</option>
      <option value="address2">B門市</option>
      <option value="address3">C門市</option>
  </select>
</form>

const submitForm = () => {

    fconst formData = new FormData();
  formData.append('name', name.value);
  formData.append('phone', phone.value);
  formData.append('userid', user.userid);

    axios({
            method: 'post',
            url: '<GAS api>',
            data: formData,
            headers: { 'Content-Type': 'multipart/form-data' }
        })
        .then(response => {
            // 成功
            console.log(response);
        })
        .catch(error => {
            // 失敗

        });
}

使用 Github Actions 部署

為了省成本而部署在 Github Page 上,使用 Github Actions 來進行,請參考這篇
gh-pages-deploy.yml

name: Deploy

on:
  push:
    branches:
      - main  # 將此處更改為你的默認分支名稱,例如:master

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Install & Build # 執行指令
      run: |
        npm install
        npm run build 

    - name: Deploy
      uses: JamesIves/[email protected]
      with:
        branch: gh-pages  # GitHub Pages 的分支
        folder: dist  # build 後的檔案夾

    - name: Debug git error
      run: git status

登記為 LIFF

部署完後,記得要去 LINE 開發者功能中登記 LIFF ,可以參考這篇
就拿 Github Page 的 url 就可以。

GAS 部署

接著要製作 GAS 的 API ,請參考官方文件

建立 POST 接口

function doPost(e) {
  var param = e.parameter;

  const data = {
    name: param.name,
    phone: param.phone,
    userID: param.userid
  }
  setData(data); //將資料放進表單
  return ContentService.createTextOutput(JSON.stringify({param}))
                       .setMimeType(ContentService.MimeType.JSON) //為了debug 先回傳資料
}

將資料放進表單

因為我是在別的文件開啟GAS,所以另外指定了 fileId 。簡單說就是看你的 Google sheet 位置,像這樣:https://docs.google.com/spreadsheets/d/,取用那段就對了,記得要還要指定工作表喔。

如果是同一個文件,可以使用getActiveSpreadsheet

function setData(data){
    var fileId = '<ID>'; // 請用你的檔案ID替換此處
    // 透過ID開啟另一個檔案
    var file = SpreadsheetApp.openById(fileId);
    // 獲取另一個檔案的工作表
    var sheet = file.getSheetByName('<工作表名稱>');

    const userID = data.userID;
    var lastRow = sheet.getLastRow();

        // 如果是第一筆,先做標題
    if (lastRow == 0) {
      var headerRow = ['name','phone','UID'];
      sheet.appendRow(headerRow);
    }

    // 整理資料成陣列(注意是二維陣列)
    var values = [[data.name,data.phone,userID]];

    // 放資料
    sheet.getRange(lastRow + 1, 1, values.length, values[0].length).setValues(values);
}

部署位置

前面 LIFF 部署時,有個 ,就是這時 GAS 部署完後會有組位置像這樣:https://script.google.com/macros/s/xxxxxxxx/exec,將這串貼到

這樣就可以建立一個可以取得 UID 的 LIFF 頁面,並且透過 GAS 存到 Google sheet 中,但記得 GAS API 有一些使用上限制,用來建立微型服務絕對沒問題,但如果有用量上考量,建議不要這樣玩XD