Cloudflare Pages 靜態網站使用Airtable實現聯絡表單提交

Posted by Y Cheung on Wed, Jun 12, 2024

最近在用Cloudflare的Page功能直接host靜態網頁,實在太方便了。但有時候又會需要提供給訪客提交聯絡表單,Y Cheung研究了下,發現 Cloudflare 官方文檔中提供的方案還行。

官方提及的一個是與 Formspree 一起使用1,一個是與Airtable一起使用2, 事實上他們是不同的服務提供商,前者專門處理表單提交的事務,後者更擅長處理表格和數據,只是恰好在提交contact form的這種場景下都能拿來用而已。

比較了一下,Formspree免費計劃只能給開發和測試的目的使用,而Airtable的免費計劃可以給個人或者小團隊使用,於是就選擇了Airtable的服務啦。本文介紹的就是使用Airtable收集和存儲聯絡表單信息。

1. 創建HTML表單

在項目頁面中創建一個HTML表單3,action的地址設置為/api/submit表示我們將會提交聯絡表單的信息到這個地址。示例代碼如下:

1<form method="POST" action="/api/submit">
2  <input type="text" name="name" pattern="[A-Za-z]+" placeholder="NAME"  value="" autocomplete="name" required />
3  <input type="email" name="email" placeholder="EMAIL" value="" autocomplete="email" required />
4  <textarea rows="10" placeholder="MESSAGE" name="message" required style="resize: none;" ></textarea>
5  <button type="submit">Submit</button>
6</form>

2. 創建處理表單提交的function

Cloudflare Pages 的 Functions 功能允許通過在 functions 目錄中創建文件來定義 URL 請求處理程序4,因此我們可以創建一個處理表單提交的function。

在項目根目錄下創建一個functions文件夾,裡面再創建一個api文件夾,再最裡面創建明為submit.js的js文件,此時文件結構大致如下:

1├── functions
2│   └── api
3│       └── submit.js
4└── public
5    └── index.html

submit.js文件內容如下:

 1/**
 2 * POST /api/submit
 3 */
 4export async function onRequestPost(context) {
 5  try {
 6    let input = await context.request.formData();
 7    let pretty = JSON.stringify([...input], null, 2);
 8    return new Response(pretty, {
 9      headers: {
10        'Content-Type': 'application/json;charset=utf-8',
11      },
12    });
13  } catch (err) {
14    console.log(err);
15    return new Response('Error parsing JSON content', { status: 400 });
16  }
17}

如此,/api/submit的路由route就創建好了。

3. 註冊 Airetable 並新建聯絡表單信息收集table

可以使用Y Cheung的Airetable邀請連結註冊,註冊好賬戶後,在你的Workspace中點擊Create按鈕,彈窗中選擇Start from scratch

create -> Start from Scratch

點擊 + 按鈕添加相應的欄位field:Email, Message。

click to add fields.
add Message field, field type is Long text
add Email field, field type is Email

column是可以移動的,添加好並修改表格名稱後,我們的表格是這樣的:

Form data collection spreadsheet

4. 申請Personal token

Developers中創建Personal access token。 填入NameScopes選擇data.records:writeAccess選擇剛才創建好的表格(base),示例如下:

create new personal access token
在彈窗中複製你的token,並記錄下來我們後面會用到。
copy the token

5. 查看API文檔

回到剛才創建的表格頁面,點擊右上角的**?help**,在側欄中選擇API Documentation

open the API document from side menu after click the help button.

在新窗口的API Documentation中找到你的 Base IDTable ID。(可以用Ctrl + F搜索)基本上這個頁面展示了如何使用API來操作這個表格,可以仔細看看,但在本教學中我們找到這兩個值就好了。

6. 修改submit.js文件,提交表單數據到Airtable

修改後的submit.js文件內容如下:

 1/**
 2 * POST /api/submit
 3 */
 4export async function onRequestPost(context) {
 5  try {
 6    let input = await context.request.formData();
 7    const env = context.env;
 8    let {
 9      name,
10      email,
11      message
12    } = Object.fromEntries(input)
13    let reqBody = {
14      records: [
15        {
16          fields: {
17            "Name": name,
18            "Email": email,
19            "Message": message
20          }
21        }
22      ]
23    }
24    return HandleAirtableData(env, reqBody);
25  } catch (err) {
26    console.log(err);
27    return new Response('Error parsing JSON content', { status: 400 });
28  }
29}
30
31const HandleAirtableData = (env, body) => {
32  return fetch(`https://api.airtable.com/v0/${env.AIRTABLE_BASE_ID}/${encodeURIComponent(env.AIRTABLE_TABLE_ID)}`, {
33    method: "POST",
34    body: JSON.stringify(body),
35    headers: {
36      Authorization: `Bearer ${env.AIRETABLE_API_KEY}`,
37      'Content-Type': 'application/json'
38    }
39  })
40}

7. 在Cloudflare Page中設置環境變數

在Workers&Pages中找到你的項目,在Settings中設置環境變數Environment variables,添加變數名AIRTABLE_BASE_ID,AIRTABLE_TABLE_ID,AIRETABLE_API_KEY。添加好後大概是這樣:

add environment variables

8. 更新代碼

將你的代碼部署到線上,完成!撒花~過程中如果有問題可以找Y Cheung幫忙看看喲。