Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
在解決問題之道上不斷前行
之前有個專案需求是透過 LINE bot + Google Form 建立一套可以進行線上預約的LINE OA(官方帳號), 但為了進行 UID 的對應設計一套迂迴的流程,實在不爽快。現在有機會透過 LIFF 導入,能簡化這邊的流程。
由於團隊適應關係,繼續沿用 Google sheet 來做管理,因此需要使用 GAS 來開發一組 API 。
基礎概念很簡單:
這邊使用的開發環境為 Vite + Vue3.3 + Tailwind + axios。
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);
});
})
就是一個 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 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
部署完後,記得要去 LINE 開發者功能中登記 LIFF ,可以參考這篇。
就拿 Github Page 的 url 就可以。
接著要製作 GAS 的 API ,請參考官方文件。
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 部署時,有個
這樣就可以建立一個可以取得 UID 的 LIFF 頁面,並且透過 GAS 存到 Google sheet 中,但記得 GAS API 有一些使用上限制,用來建立微型服務絕對沒問題,但如果有用量上考量,建議不要這樣玩XD