我們專案的 REPO 是放在 GitHub 上面的,有寫個 GitHub Actions 去觸發當有新的 commit 推到 production 時,就會把部署的結果傳送到 Discord 頻道,而底下的流程是基於這個通知的延伸
本次主角是強大的自動化工具 n8n、GitHub、Discord,以及 AI 模型 Gemini
要讓 n8n 能監聽和發送 Discord 訊息,我們需要先建立一個專屬的 Bot
前往「Discord Developer Portal」
新增一個應用程式
到「Bot」分頁點選「Reset Token」就會出現新的金鑰可以複製
把「Privileged Gateway Intents」的設定都打開
接著到「OAuth2」的頁面的「OAuth2 URL Generator」把「bot」打勾
會出現「Bot Permissions」權限列表,把底下都打勾
接著複製最下方產生的網址
會彈出 Discord 可以把機器人加進伺服器
接著到 n8n 的設定介面
切換到「Community nodes」去安裝社群節點「n8n-nodes-discord-trigger」
來到儀表板,新增一個流程「Create Workflow」
初始節點選擇「Discord Trigger」
點選「Add to workflow」
設定新增憑證
「Client ID」在 Discord 機器人設定的「OAuth」頁面裡
到「Bot」分頁點選「Reset Token」就會出現新的金鑰可以複製
「n8n API key」可以到 n8n 的設定頁面生產一個
設定要監聽的頻道
下個節點選擇「IF」來過濾訊息
欄位設定判斷訊息的作者是「Bot」
{{ $json.author.username }}
另一個欄位選擇特定分支
{{ $json.embeds[0].fields.find(f => f.name === 'Branch').value }}
接續在「true」的路徑選擇「Code」節點
程式碼撰寫底下的內容來抓 commit 的 URL
// 取得 'Commit' 欄位的內容,它是一個 Markdown 格式的連結
// 格式為:[d1accfe](https://github.com/...)
const fields = $json.embeds[0].fields;
const commitField = fields.find((f) => f.name === "Commit");
if (!commitField) {
// 如果找不到 Commit 欄位,就回傳空值
return { headSha: null };
}
// 使用正規表示式從 Markdown 連結中提取 URL
const markdownLink = commitField.value;
const urlRegex = /\(([^)]+)\)/; // 符合括號內的內容
const match = markdownLink.match(urlRegex);
if (!match || !match[1]) {
// 如果沒抓到 URL,回傳空值
return { headSha: null };
}
const url = match[1];
const headSha = url.split("/").pop();
return { headSha: headSha };
下個節點選擇「Discord」的「Get many message」來讀取頻道歷史訊息
同樣要新增憑證
貼上 Bot Token
設定要抓的伺服器跟頻道,抓「10」筆就好
下個節點再選擇「Code」
程式碼撰寫如下來找出上次 commit 的 SHA
const messages = $("Discord").item.json;
const triggerMessageId = $("Discord Trigger").item.json.id;
for (const msg of messages) {
// 跳過觸發本次流程的訊息本身,從下一則開始才是歷史紀錄
if (msg.id === triggerMessageId) {
continue;
}
// 確保找到的是來自 GitHub Bot 且格式正確的訊息
if (
msg.author.username === "GitHub" &&
msg.embeds &&
msg.embeds.length > 0 &&
msg.embeds[0].url
) {
const url = msg.embeds[0].url;
const baseSha = url.split("/").pop();
// 找到第一筆符合的就回傳並結束
return { baseSha: baseSha };
}
}
// 安全機制:如果沒找到,回傳一個空值
return { baseSha: null };
下個節點選擇「HTTP Request」
權限選擇「Header Auth」
填上底下的內容,「YOUR_GITHUB_PAT」要改成自己的權杖
Bearer YOUR_GITHUB_PAT
請求的 URL 填上
https://api.github.com/repos/{{ $('Discord Trigger').item.json.embeds[0].author.name.split('/')[0] }}/{{ $('Discord Trigger').item.json.embeds[0].author.name.split('/')[1] }}/compare/{{ $('Code').item.json.baseSha }}...{{ $('Get headSha').item.json.headSha }}
接著「Send Headers」打開,加上底下的欄位
Name: Accept
Value: application/vnd.github.v3+json
Name: X-GitHub-Api-Version
Value: 2022-11-28
下個節點來選「Gemini」把 commit 紀錄丟過去,讓他幫我們產 CHANGELOG
同樣要新增設定憑證
前往底下的網址
點選「Get API key」,選擇「Create API key」
選個快速的模型
Prompt 設定如下
你是一位資深的軟體工程師與技術寫作專家,擅長將零散的技術 commit log 彙整成清晰易懂、適合團隊內部溝通的 changelog。
請根據以下提供的 raw commit messages,幫我完成一份專業的「新功能部署日誌」。
撰寫要求:
1. 使用台灣用語的正體中文。技術名詞若無通用翻譯可保留英文。
2. 根據 commit 內容,將變更分類為【✨ 新功能】、【🐛 錯誤修正】、【🔧 最佳化改善】、【📄 文件】等。如果分類不明顯,可以都放在【🔧 最佳化改善】下。
3. 語氣應專業且帶點輕鬆,讓團隊成員能快速掌握重點。
4. 移除 commit message 中的 issue numbers 或無關的標籤。
5. 最終結果直接以 Markdown 格式輸出,不要有額外的開頭或結尾問候語。
--- Raw Commits ---
{{ $('HTTP Request').item.json.commits.map(c => `- ${c.commit.message.split('\n')[0]}`).join('\n') }}
--- End of Raw Commits ---
接著選擇「Discord」來發送訊息
「Connection Type」選擇「Webhook」,憑證的串接在之前的文章有撰寫過,這邊就不重複惹
Message 設定如下
{
{
$json.text;
}
}
記得在最上方點選啟用「Active」
現在,當下一次部署完成時,我們的團隊就會收到由 AI 自動產生的精美更新日誌惹