藍圖風格插畫:右側上鎖的收件匣代表讀不到信,只有一封信從上方飛出去,左下的 n8n 流程節點以虛線連到收件匣,表示 n8n 用 Gmail 寄信只給寄信權限

n8n 用 Gmail 寄信,只給「寄信」權限:不用應用程式密碼的 OAuth 設定

想讓 n8n 用自己的 Gmail 寄信,又不想把整個信箱交出去?這篇一步一步設定 Google OAuth,只開「寄信」一項權限:開 Google Cloud 專案、建用戶端、在 n8n 建憑證,再用 HTTP Request 節點寄出第一封信。

在〈不知道 Netflix 要看什麼?我用 AI 做了每週五寄到信箱的 Netflix 推薦片單〉裡,片單是用我平常的 Gmail 主帳號寄出的,但 n8n 只拿到「寄信」這一項權限,讀不到信箱裡的任何一封信。這篇整理讓 n8n 用 Gmail 寄信、又只給寄信權限的設定步驟。

Gmail 寄信為什麼不用應用程式密碼,也不用 n8n 內建節點

讓 n8n 用 Gmail 寄信,最快的做法是產生一組「應用程式密碼」。問題是這組密碼能讀整個信箱,還能繞過兩步驟驗證。

主帳號如果也收各種服務的登入驗證信,這組密碼外流的代價就很大。

n8n 內建的 Gmail 節點也不適合。它用的「Gmail OAuth2 API」憑證會一次要求讀信、管理信件的權限,不是只有寄信。

所以這篇的做法是:自己在 Google Cloud 建一個 OAuth 用戶端,在 n8n 用通用的「Google OAuth2 API」憑證,範圍只填寄信一項,再用 HTTP Request 節點呼叫 Gmail API 寄信。OAuth 是把特定權限交給程式的授權方式,不用把密碼給它。

開始之前要先有一台用 HTTPS 網址連得到的 n8n,Google 授權完會把你導回這個網址。

我的 n8n 架在家裡的舊電腦上,用 Cloudflare Tunnel 對外,做法在〈不開 port 也能從外面連回家:用 Cloudflare Tunnel 架 n8n〉。

步驟 1:開一個專用的 Google Cloud 專案

到 Google Cloud 控制台,從左上角的專案選單建立新專案。我取名 n8n-gmail-send,跟原本 Google Drive 備份用的專案分開,之後要查設定,一眼就知道在哪裡。

Google Cloud 歡迎頁,目前的專案是 n8n-gmail-send
專案名稱會顯示在畫面左上角,確認選對專案再往下做

步驟 2:啟用 Gmail API

左上角選單 →「API 和服務」→「程式庫」,搜尋 Gmail API,按「啟用」。啟用後回到「已啟用的 API 和服務」,清單裡會看到 Gmail API,之後每寄一封信,「要求」數字就會增加。

Google Cloud「已啟用的 API 和服務」清單,第一列是 Gmail API
Gmail API 啟用後,每寄一封信,「要求」就會加 1

步驟 3:設定 Google Auth Platform

在上方搜尋框輸入「Google Auth Platform」(舊名是「OAuth 同意畫面」)。左側有幾個分頁,要設定的是這三個:

品牌:應用程式名稱會出現在授權畫面,也會出現在 Google 帳戶的第三方存取權清單,取個自己看得懂的名字就好,我取「n8n 寄信」。使用者支援電子郵件選自己的信箱。標誌不用上傳,上傳了反而要送 Google 審核。

Google Auth Platform 品牌頁,應用程式名稱填「n8n 寄信」
應用程式名稱會出現在授權畫面和 Google 帳戶的第三方存取權清單

目標對象:使用者類型選「外部」(一般 Gmail 帳號只能選這個),發布狀態按「發布應用程式」,變成「實際運作中」。停在「測試」狀態的話,授權大約 7 天就會失效,n8n 會突然寄不出信。發布不等於送審,不用填審核資料,只是授權時會多一個警告畫面(步驟 6 會講)。

Google Auth Platform 目標對象頁,發布狀態是「實際運作中」,使用者類型是「外部」
發布後狀態會變成「實際運作中」

資料存取權:這裡可以不用動。我的三個範圍清單都是空的,要求哪些權限是在 n8n 授權時才決定。

Google Auth Platform 資料存取權頁,非機密、機密、受限制三個範圍清單都是空的
三個範圍清單都是空的,一樣可以寄信

步驟 4:建立 OAuth 用戶端

先到 n8n 準備重新導向網址:左側「Credentials」→ 新增憑證 → 選「Google OAuth2 API」,畫面最上面的「OAuth Redirect URL」就是。格式是 https://n8n.example.com/rest/oauth2-credential/callback,前面換成你自己的 n8n 網址。這個視窗先不要關。

回到 Google Auth Platform →「用戶端」→ 建立用戶端:

  • 應用程式類型:網頁應用程式
  • 名稱:只有自己在控制台看得到,我填 n8n
  • 已授權的重新導向 URI:貼上 n8n 的 OAuth Redirect URL
  • 已授權的 JavaScript 來源:不用填

建立後會拿到「用戶端 ID」和「用戶端密碼」。用戶端密碼之後就看不到完整內容了,先存進密碼管理工具,我是存在 Bitwarden。

Google Auth Platform 網頁應用程式用戶端設定,已授權的重新導向 URI 是 n8n 的 oauth2-credential/callback 網址
重新導向 URI 要和 n8n 顯示的 OAuth Redirect URL 一字不差

這頁右側有一則提醒:OAuth 用戶端連續 6 個月沒用會被自動刪除。每週都會寄信的話不用擔心;如果只是偶爾用,要記得這件事。

步驟 5:在 n8n 建立憑證,範圍只填寄信

回到剛才 n8n 的「Google OAuth2 API」視窗,填三個欄位:

  • Client ID:貼上用戶端 ID
  • Client Secret:貼上用戶端密碼
  • Scope:只填 https://www.googleapis.com/auth/gmail.send

Scope 就是要跟 Google 要哪些權限,gmail.send 只能寄信,不能讀信、刪信、改標籤。憑證名稱我取「Gmail 寄信(只限寄信)」,之後在節點裡選的時候不會選錯。

n8n 的 Google OAuth2 API 憑證「Gmail 寄信(只限寄信)」,帳號已連線,Scope 只有 gmail.send
授權完成後會顯示「Account connected」

步驟 6:授權時的「未經驗證」警告

按「Sign in with Google」,選要用來寄信的帳號。因為這個應用程式沒有送 Google 審核,會先跳出「Google 尚未驗證這個應用程式」的警告。

這個應用程式是你自己剛建的,點「進階」,再點「前往 n8n 寄信(不安全)」繼續。

接著是授權畫面,要確認上面只列了一項:「以你的名義傳送電子郵件」。如果出現讀信或其他權限,表示 Scope 填錯了,先取消回去改。

按「繼續」後回到 n8n,憑證顯示「Account connected」就完成了。

步驟 7:用 HTTP Request 節點寄信

Gmail API 要的信件格式是把整封信(收件人、主旨、內容)編碼成一串文字,放在 raw 欄位送出。

所以流程分兩步:先用 Code 節點把信組好,再用 HTTP Request 節點送出。

Code 節點(語言選 JavaScript),收件人、主旨、內容換成你的:

const to = '[email protected]';
const subject = 'n8n 寄信測試';
const html = '<p>這是 n8n 用 Gmail API 寄出的信。</p>';

const b64 = s => Buffer.from(String(s), 'utf8').toString('base64');
const mime = [
  'To: ' + to,
  'Subject: =?UTF-8?B?' + b64(subject) + '?=',
  'MIME-Version: 1.0',
  'Content-Type: text/html; charset="UTF-8"',
  'Content-Transfer-Encoding: base64',
  '',
  b64(html),
].join('\r\n');

const raw = Buffer.from(mime, 'utf8').toString('base64')
  .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');

return [{ json: { raw } }];

主旨用 =?UTF-8?B?…?= 包起來,中文才不會變亂碼。

HTTP Request 節點接在後面:

  • Method:POST
  • URL:https://gmail.googleapis.com/gmail/v1/users/me/messages/send
  • Authentication:Predefined Credential Type → Google OAuth2 API → 選步驟 5 的憑證
  • Send Body:打開,Body Content Type 選 JSON,內容填 {{ JSON.stringify({ raw: $json.raw }) }}

執行後信箱收到信,就成功了。

我的 Netflix 片單流程多做了一道檢查:寄出前先比對 n8n 資料表裡的收件名單,不在名單上、或一次寄給多個人就直接擋下來,通過才會走到寄信節點。這樣就算流程被誤用,也只能寄給我允許的人。

n8n「Netflix 片單寄信」流程:收到寄信請求、讀收件名單、組成郵件、Gmail 寄出,再整理並寫入推薦紀錄
「組成郵件」先比對收件名單,通過才交給「Gmail 寄出」

不想用了,怎麼撤銷

到 Google 帳戶 →「安全性」→「第三方存取權」,找到「n8n 寄信」,點「全部刪除」。n8n 那邊的憑證會立刻失效,不用改密碼,也不影響帳號其他地方。

有一點要注意:這裡是用「應用程式」來列權限。如果同一個用戶端後來又拿去給別的流程授權,例如讀信,這裡會把所有權限合在一起列出來,按「全部刪除」也會一起斷掉。我後來做信用卡帳單提醒時,就沿用了同一組用戶端,所以現在這頁列了 3 項權限。想讓每個流程分開管,就各自建一組用戶端。