JavaScript User-Defined Function (UDF) 是一種 Single Message Transform (SMT)。UDF 提供彈性的方式,可在 Pub/Sub 中實作自訂轉換邏輯,類似於 BigQuery JavaScript UDF。
UDF 會接受單一訊息做為輸入內容,對輸入內容執行定義的動作,並傳回處理結果。
UDF 具有下列主要屬性:
程式碼:定義轉換邏輯的 JavaScript 程式碼。
函式名稱:Pub/Sub 會將提供的程式碼套用至訊息,而這個名稱就是程式碼中的 JavaScript 函式名稱。
建立 JavaScript 函式
UDF 程式碼必須包含具有下列簽章的函式:
/**
* Transforms a Pub/Sub message.
* @return {(Object<string, (string | Object<string, string>)>|* null)} - To
* filter a message, return `null`. To transform a message, return a map with
* the following keys:
* - (required) 'data' : {string}
* - (optional) 'attributes' : {Object<string, string>}
* Returning empty `attributes` will remove all attributes from the message.
*
* @param {(Object<string, (string | Object<string, string>)>} - Pub/Sub
* message. Keys:
* - (required) 'data' : {string}
* - (required) 'attributes' : {Object<string, string>}
*
* @param {Object<string, any>} metadata - Pub/Sub message metadata.
* Keys:
* - (optional) 'message_id' : {string}
* - (optional) 'publish_time': {string} YYYY-MM-DDTHH:MM:SSZ format
* - (optional) 'ordering_key': {string}
*/
function <function_name>(message, metadata) {
// Perform custom transformation logic
return message; // to filter a message instead, return `null`
}
輸入內容
這個函式會採用下列輸入內容:
message引數:代表 Pub/Sub 訊息的 JavaScript 物件。其中包含下列屬性:data:(String,必要) 訊息酬載。attributes:(Object<String, String>,選用) 代表訊息屬性的鍵/值配對對應。
metadata引數:包含 Pub/Sub 訊息不可變更中繼資料的 JavaScript 物件:
輸出內容
函式必須傳回下列其中一項:
如要轉換訊息,請編輯
message.data和message.attributes的內容,然後傳回經過變更的message物件。如要篩選訊息,請傳回
null。
輸入 / 輸出需求
- 如果 UDF 會轉換訊息酬載,則酬載輸入和輸出內容必須是 UTF-8 編碼的字串。
- 如果 UDF 未轉換訊息酬載,酬載可能會使用任何編碼。
- 屬性鍵值組必須是 UTF-8 編碼的字串。
UDF 如何轉換訊息
在訊息上執行 UDF 的結果可能是下列其中一項:
UDF 會轉換訊息。
UDF 會傳回
null。主題 SMT:Pub/Sub 會向發布者傳回成功訊息,並在篩選後訊息的回應中加入訊息 ID。Pub/Sub 不會儲存訊息,也不會傳送給任何訂閱者。
訂閱項目 SMT:Pub/Sub 會確認訊息已傳送,但不會將訊息傳送給訂閱者。
UDF 擲回錯誤。
主題 SMT:Pub/Sub 會將錯誤傳回給發布者,且不會發布任何訊息。
訂閱項目 SMT:Pub/Sub 負面確認訊息。
建立 UDF SMT
您可以在 Pub/Sub 主題或訂閱項目上設定 SMT。
- 主題 SMT 會在 Pub/Sub 儲存訊息前執行,且所有訂閱者都能查看結果。
訂閱項目 SMT 會在郵件傳送前執行,且結果只適用於該訂閱項目。
控制台
前往 Cloud de Confiance 控制台的 Pub/Sub「主題」頁面。
建立主題或訂閱項目。
如要建立主題,請按一下「建立主題」。「建立主題」頁面隨即開啟。
如要建立訂閱:
按一下要訂閱的主題名稱。
按一下「建立訂閱項目」。「將訂閱項目新增至主題」頁面隨即開啟。
在「轉換」下方,按一下「新增轉換」。
在「轉換類型」部分,選取「JavaScript UDF」。
選用:您可以使用 Gemini Enterprise 生成 UDF 的程式碼,方法如下:
按一下「使用 AI 生成」。
在文字欄位中,輸入函式應執行的動作說明。例如:「Add a processed_at attribute with the current time」(新增含有目前時間的 processed_at 屬性)。
按一下「提交」。生成的程式碼會顯示在「使用 AI 生成」窗格中,並附上程式碼說明。
檢查代碼是否正確。你可能需要修正說明並重新產生程式碼。
如要使用產生的程式碼,請按一下「匯入」。
在「Function name」(函式名稱) 欄位中,輸入 SMT 呼叫的 JavaScript 函式名稱。範例:
redactSSN。如果您使用 Gemini Enterprise 生成程式碼,這個欄位會自動填入。
在文字區域中輸入 UDF 的程式碼。範例:
function redactSSN(message, metadata) { const data = JSON.parse(message.data); delete data['ssn']; message.data = JSON.stringify(data); return message; }程式碼必須包含名稱與「函式名稱」欄位相符的函式。
如果您使用 Gemini Enterprise 生成程式碼,這個欄位會自動填入。
如不想立即啟用 SMT,請選取「停用轉換」。選取這個選項後,系統會建立 SMT,但不會對內送郵件執行。建立主題後,你可以編輯主題來啟用 SMT。
如要建立主題或訂閱項目,請按一下「建立」。
gcloud
建立定義檔案
建立定義 UDF SMT 的 YAML 或 JSON 檔案。
YAML
- javascriptUdf:
code: { FUNCTION_CODE }
functionName: FUNCTION_NAME
JSON
{
"javascriptUdf": {
"code": {
FUNCTION_CODE
}
"functionName": FUNCTION_NAME
}
}
更改下列內容:
FUNCTION_CODE:UDF 的 JavaScript 程式碼。程式碼必須包含名稱與
functionName欄位相符的函式。範例:function redactSSN(message, metadata) { const data = JSON.parse(message.data); delete data['ssn']; message.data = JSON.stringify(data); return message; }FUNCTION_NAME:SMT 呼叫的 JavaScript 函式名稱。範例:
redactSSN。
建立主題或訂閱項目
如要建立主題,請執行 gcloud pubsub topics create 指令。
gcloud pubsub topics create TOPIC_ID \
--message-transforms-file=TRANSFORMS_FILE
更改下列內容:
- TOPIC_ID:要建立的主題 ID 或名稱。
- TRANSFORMS_FILE:定義檔案的路徑。
如要建立訂閱項目,請執行 gcloud pubsub subscriptions create 指令。
gcloud pubsub subscriptions create SUBSCRIPTION_ID \
--topic=projects/PROJECT_ID/topics/TOPIC_ID \
--message-transforms-file=TRANSFORMS_FILE
更改下列內容:
SUBSCRIPTION_ID:要建立的訂閱項目 ID 或名稱。
PROJECT_ID:包含主題的專案 ID。
TOPIC_ID:要訂閱的主題 ID。
TRANSFORMS_FILE:定義檔案的路徑。
您也可以在建立 SMT 前驗證及測試。詳情請參閱下列頁面:
限制
Pub/Sub 會對 UDF 執行資源限制,確保轉換作業的效率。限制包括:
- 每個 UDF 的程式碼上限為 20 KB
- 每則訊息的執行時間上限為 500 毫秒
- 僅支援 ECMAScript 標準內建函式
- 不呼叫外部 API
- 未匯入外部程式庫
UDF 範例
以下是發布及訂閱的 UDF 範例。您可以在 UDF 程式庫中找到其他範例。
函式:將星期幾的整數轉換為對應的字串
將下列 UDF 新增至主題或訂閱項目後,系統會在發布或傳送訊息時進行下列變更:
Pub/Sub 會將函式套用至訊息。如果訊息沒有 JSON 酬載,UDF 會擲回錯誤。
使用者定義函式會尋找名為
dayOfWeek的欄位,如果這個欄位的值是介於 0 到 6 之間的數字,就會轉換為對應的星期幾,例如Monday。如果該欄位不存在,或數字不在 0 到 6 的範圍內,程式碼會將dayOfWeek欄位設為Unknown。UDF 會將修改後的酬載序列化回訊息中。
Pub/Sub 會將更新後的訊息傳遞至管道的下一個步驟。
function intToString(message, metadata) {
const data = JSON.parse(message.data);
switch(`data["dayOfWeek"]`) {
case 0:
data["dayOfWeek"] = "Sunday";
break;
case 1:
data["dayOfWeek"] = "Monday";
break;
case 2:
data["dayOfWeek"] = "Tuesday";
break;
case 3:
data["dayOfWeek"] = "Wednesday";
break;
case 4:
data["dayOfWeek"] = "Thursday";
break;
case 5:
data["dayOfWeek"] = "Friday";
break;
case 6:
data["dayOfWeek"] = "Saturday";
break;
default:
data["dayOfWeek"] = "Unknown";
}
message.data = JSON.stringify(data);
return message;
}
功能:遮蓋身分證字號
將下列 UDF 新增至主題或訂閱項目後,系統會在發布或傳送訊息時進行下列變更:
Pub/Sub 會將函式套用至訊息。如果訊息沒有 JSON 酬載,UDF 會擲回錯誤。
UDF 會從訊息酬載中移除
ssn欄位 (如果有的話)。UDF 會將修改後的酬載序列化回訊息中。
Pub/Sub 會將更新後的訊息傳遞至管道的下一個步驟。
function redactSSN(message, metadata) {
const data = JSON.parse(message.data);
delete data['ssn'];
message.data = JSON.stringify(data);
return message;
}
功能:篩除特定訊息並自動確認
將下列 UDF 新增至主題或訂閱項目後,系統會在發布或傳送訊息時進行下列變更:
Pub/Sub 會將函式套用至訊息。如果訊息沒有 JSON 酬載,UDF 會擲回錯誤。
UDF 會檢查酬載是否包含名為
region的欄位。如果
region欄位的值不是US,函式會傳回空值,導致 Pub/Sub 篩除訊息。如果
region欄位的值為US,Pub/Sub 會將原始訊息傳遞至管道的下一個步驟。
function filterForUSRegion(message, metadata) {
const data = JSON.parse(message.data);
if (data["region"] !== "US") {
return null;
}
return message;
}
函式:驗證訊息內容,確保金額不超過 100
將下列 UDF 新增至主題或訂閱項目後,系統會在發布或傳送訊息時進行下列變更:
Pub/Sub 會將函式套用至訊息。如果訊息沒有 JSON 酬載,UDF 會擲回錯誤。
UDF 會檢查訊息是否包含名為
amount的欄位。如果
amount欄位的值大於100,函式就會擲回錯誤。如果
amount欄位的值不大於100,函式會傳回原始訊息。Pub/Sub 接著會將訊息標示為失敗,或將原始訊息傳遞至管道中的下一個步驟。
function validateAmount(message, metadata) {
const data = JSON.parse(message.data);
if (data["amount"] > 100) {
throw new Error("Amount is invalid");
}
return message;
}
後續步驟
在 UDF 程式庫中探索其他範例