ThingWorx Flow > ThingWorx Flow SDK > 教學專區 B:ThingWorx Flow 連接器 SDK 教學專區
教學專區 B:ThingWorx Flow 連接器 SDK 教學專區
先決條件
本教學專區所需的先決條件如下:
支援所安裝之 ThingWorx Flow 版本的 Node.js LTS 版本
欲瞭解目前使用中的 node.js 版本,請開啟「指令提示」,然後執行下列指令:
node -v
可以處理 Node js 專案的整合開發環境 (IDE)。
本教學專區使用 WebStorm 作為 IDE。
對 Node js 程式碼有中等程度的瞭解
範本資料夾
* 
建議使用已安裝 ThingWorx Flow 的相同電腦來使用已安裝的元件。
簡介 
本教學專區將說明建構一般連接器所需的步驟。我們將針對 Gmail 建構一個連接器,因為大多數開發者可能都比較熟悉 Gmail 的工作方式。建構連接器之後,您將會熟悉建構連接器所牽涉的工具、加工品及流程,並可協助您為應用程式建構連接器。建構新連接器不需要部署 ThingWorx Flow。您可在本機建構並測試連接器之後,將其部署至測試內部部署安裝,以進行測試。
本教學專區涵蓋下列內容:
1. 建立連接器專案。
2. OAuth2 組態
3. 建立查詢,用來搜尋與您 Gmail 相關的篩選器。
4. 建立動作,用來取得與所選篩選器相符之電子郵件訊息的 id 與主旨。
5. 建立在收到新郵件時允許啟動新流程的觸發器。
6. 新增圖示
7. 將連接器部署至 ThingWorx Flow 的內部部署實例。
步驟 1:建立連接器專案 
連接器是一種特定的 npm 封裝,其由多種加工品所組成,例如 oauth 組態、動作、查詢、觸發器。專案應遵循建構 npm 封裝的模式。專案應具有一個 package.json、一個 lib 資料夾、一個 test 資料夾,以及各加工品及其版本每個一個資料夾。
開啟 terminal/cmd 視窗,並導覽至您要建立新連接器專案的資料夾。在本教學專區中,我們將會在 c:\test目錄中建立連接器
1. 將目錄變更為測試目錄:cd c:\test
2. 執行下列指令來建立專案:flow init <projectname>
您應該會看到下列內容:
cd c:\test
[2018-10-21T15:35:11.519] [INFO] default - Project gmail created successfully in .
3. 在 IDE 中開啟專案目錄,以檢閱依預設建立的加工品。
每個專案都包含一個 index.js 檔案和一個 package.json 檔案。請勿變更 index.js 檔案,因為需要在 ThingWorx Flow 伺服器中使用該檔案載入連接器。
* 
package.json 檔案會參照 ptc-flow-sdk。若無此相依性,則無法測試、部署或執行連接器。此外,它還提供了一些 API,可以使連接器的開發過程更輕鬆,一致性更好。
1. 執行教學專區 A 中提供的步驟。
2. 使用下列指令安裝 async 封裝:
npm install async
3. 使用下列指令安裝 request 模組。請求模組包含用來發出 HTTP 請求的 API。
npm install request
npm install request-promise
4. 安裝 lodash 模組,它會提供一些有用的功能:
npm install lodash
npm install ptc-flow-sdk@<工具版本> -g
在此查看適用於您 ThingWorx Flow 版本的 <工具版本>
* 
本教學專區中的所有指令都從連接器專案目錄 c:\test\gmail 中執行。這樣便無需使用 -d/--projectDir 選項提供連接器目錄的完整路徑。
步驟 2:建立 OAuth2 組態 
* 
開始之前,請先確定您已依照「用來測試 OAuth 與觸發器的組態」部份所提供的步驟執行。
Gmail 使用 OAuth 2.0 進行驗證。因此,範例連接器使用 OAuth 2.0 作為驗證機制。所有 OAuth2 提供者都需要應用程式才能建立用戶端 id 與用戶端密碼。之後,應用程式可以請求使用者使用這些認證登入 OAuth 提供者。使用者可以授與應用程式代表他存取資料的權限。這些權限依範圍定義。使用者可以選擇性為應用程式提供存取其資料的權限。如需有關如何針對 Gmail 及其他 google 應用程式實行此功能的詳細資訊,請造訪下列連結。
提供重新導向 URL。重新導向 URL:
https://<hostname>:<port>//Thingworx/Oauths/oauth/return 看起來如下所示:
https://flow.local.rnd.ptc.com/Thingworx/Oauths/oauth/return
某些系統允許多個重新導向。
* 
請確保您使用的主機已新增至使用者主目錄中的 .flow\flow.json 檔案。如果這不是實際主機名稱,而是本機主機的別名,請將其新增至您作業系統的主機檔案。flow.json 範例如下。
{
"hostname": "localhost",
"port":443
}
hostname 值必須為 localhost
port 值為 ThingWorx Flow 託管埠號碼。依預設,此埠號碼為 443。
舉例來說,
1. 在 Windows 中,於編輯器上按一下滑鼠右鍵,然後選取「以系統管理員身分執行」。
2. 編輯位於 c:\windows\system32\drivers\etc\hosts 的主機檔案,然後如下所示新增或更新輸入:
127.0.0.1 flow.local.rnd.ptc.com
其中,flow.local.rnd.ptc.com 應以別名取代。
完成之前步驟之後,您即已建立應用程式及應用程式的用戶端 id 與用戶端密碼。
1. 使用下列指令建立 OAuth 組態。
c:\test\gmail>flow add oauth gmail
[2018-10-21T16:26:54.398] [INFO] add-oauth - Oauth configuration gmail added successfully.
此指令會在專案資料夾中建立 \auth\oauth\gmail-gmail 資料夾。該資料夾將只包含一個 config.json 檔案。
在此情況下,config.json 檔案是一個範本,必須予以自訂才能與特定 OAuth 提供者 (例如 Google) 搭配使用。
2. 在文字編輯器或 IDE 中開啟此檔案,然後進行下述變更。請務必以正確方式編輯檔案,確保其保持為有效的 JSON 檔案。
3. 根據需要設定類別、名稱、標題與圖示。有關建立及設定圖示的詳細資訊,請參閱以下將圖示新增至連接器部份。
4. 搜尋金鑰 oauth2_params_other,並將其取代為下列值:
[
"{\"access_type\":\"offline\"}"
]
5. 搜尋金鑰 oauth2_params_scope,並將其值取代為下列 JSON 陣列:
[
"{\"https://www.googleapis.com/auth/gmail.labels\":\"Manage mailbox labels\"}",
"{\"https://www.googleapis.com/auth/gmail.insert\":\"Insert mail into your mailbox\"}",
"{\"https://www.googleapis.com/auth/gmail.modify\":\"All read/write operations except immediate, permanent deletion of threads and messages, bypassing Trash.\"}",
"{\"https://www.googleapis.com/auth/gmail.readonly\":\"Read all resources and their metadata—no write operations.\"}",
"{\"https://www.googleapis.com/auth/gmail.compose\":\"Create, read, update, and delete drafts. Send messages and drafts.\"}",
"{\"https://www.googleapis.com/auth/gmail.send\":\"Send email on your behalf\"}"
]
請注意值 env_local_params。這裡的 local 是環境名稱。可能存在五個環境,且由 env_production_params, env_pre_prod_params, env_staging_params, env_local_params 金鑰表示。值的格式為 {{{local.CLIENT_SECRET}}}local.CLIENT_SECRET 是代表環境名稱的變數。應該用三對大括號將其擴起來。當在 ThingWorx Composer 中執行 LoadOAuthConfiguration 服務以將 OAuth 載入到 ThingWorx Flow 伺服器時,會將這些值取代為客戶提供的值。值透過 JSON 檔案提供。當僅針對 ThingWorx Flow 伺服器執行所在的環境產生 OAuth 組態時,會取代值。如果伺服器的 NODE_ENV 環境變數設定為生產,則生產值 CLIENT_SECRET 會填入 OAuth 資料檔案中提供的值。如此便可針對每個客戶部署自訂 OAuth 組態。
6. 尋找 base_url,並將其值取代為 https://accounts.google.com/o/oauth2
7. 尋找 oauth2_auth_url 並其值取代為 /auth
步驟 3:測試 OAuth 組態 
在部署 OAuth 組態之前,可以先行測試。ThingWorx Flow CLI 會啟動瀏覽器,供您使用您的認證登入 OAuth 提供者,以進行測試。如果驗證成功,會產生存取權杖,並會將其儲存至磁碟以供日後使用。您也可以在內嵌 chrome 瀏覽器視窗中選取適當組態,來測試每個部署組態。
我們需要先建立一個測試資料檔案,且該檔案應包含將如上所述取代 env_<environment-name>_params 的實際用戶端 id 與密碼,然後才能執行。欲執行此操作,請在 c:\test 中建立一個新 JSON 檔案:testOauthData.json,並將下列內容新增至該檔案。
{
"gmail-gmail": {
"Test Gmail Oauth": {
"CLIENT_ID": "<your-client-id-here>"
"CLIENT_SECRET": ""<your-client-secret-here>"
}
}
}
請務必將 <your-client-id-here><your-client-secret-here> 取代為您之前從 google 控制台擷取的值。
接下來,請確保包含在使用者主目錄中的 flow\flow.json 檔案包含正確的主機名稱、埠與憑證密碼。只有在建立自我簽署憑證時提供了此檔案,才需要執行此操作。
在指令提示中執行下列指令,set FLOW_ALLOW_UNTRUSTED_CERTIFICATES=true
由於我們使用了自我簽署憑證來執行工具,因此必須使用此變數。
1. 執行下列指令來測試 OAuth。
flow test oauth gmail-gmail -f ..\testOauthData.json -t "Test Gmail Oauth"
2. 選取要測試的組態,然後按一下「驗證 OAuth 組態」。
3. 選取您要允許應用程式存取的範圍,然後按一下「允許」
4. 輸入您 google 帳戶的使用者名稱。此帳戶可以是任何 google 帳戶,不一定是用來建立用戶端 id 與密碼的帳戶。
5. 輸入您的密碼。如果驗證成功,您應該會看到存取權杖。
6. 按一下「儲存並結束」儲存存取權杖,以供未來使用。
控制台會顯示下列訊息。
[2018-10-22T12:51:07.643] [INFO] oauth - Access token saved with ID :664ec37a-9720-460c-8536-fbf372198cb1
此訊息中的 id 將用來測試依賴存取權杖的其他加工品,例如查詢、動作與觸發器。應使用 -a/--access_token 選項將上述所產生的 id 提供給所有測試指令。
* 
如果您收到例如「重新導向 URI 不符」之類的錯誤,應確認 flow.json 組態是否正確,以及流程所使用的 URL 與使用 google 註冊的 URL 是否相符。流程使用的重新導向 URL 會在測試開始時輸出到控制台中。
例如,[2018-10-22T11:07:53.868] [INFO] oauthServer- 伺服器已啟動,用於 oauth 的 redirect_uri = https://flow.local.rnd.ptc.com:443/Thingworx/Oauths/oauth/return
* 
OAuth 存取權杖的有效期很短,因此在使用存取權杖測試動作、查詢及觸發器之前,您應先執行 flow test oauth 指令以重新產生新權杖。
步驟 4:建立查詢 
查詢就是搜尋機制,通常用來以動態方式取得動作或觸發器某些輸入欄位的選項清單。例如,Gmail 中的電子郵件訊息就可以將標籤與其相關聯。這樣有助於快速搜尋全部使用標籤標記的相關電子郵件。不過,使用者不可能記住在其帳戶中建立之所有標籤的名稱。我們即將建構的查詢會針對在 Gmail 帳戶中找到的標籤產生 id 與值對。之後,便可使用其中一或多個 id 與值對,取得包含這些標籤之電子郵件的 id 及主旨。
查詢沒有中繼資料,而是以單一 index.js 檔案表示。查詢也不會版本化。在 index.js 檔案中可以存在任意數量的查詢方法。
欲建立查詢,請執行下列指令:
c:\test\gmail>flow add lookup
[2018-10-22T14:41:52.298] [INFO] add-lookup - Lookup added successfully
執行此指令會在 lookup\gmail 資料夾中產生一個 index.js 檔案。
在 IDE 中開啟 index.js 檔案,然後將以下所列的程式碼新增到其中。
在檔案的最上方,匯入下列模組。
const async = require('async')
const request = require('request')
const logger = require('ptc-flow-sdk').getLogger('gmail-lookup')
將下列程式碼複製到檔案中的所有現有程式碼之後。

gmailAPIs.getLabels = function (input, options, output) {
logger.debug('Trying to fetch labels')
// Gmail API to fetch th labels in the gmail account
options.url = 'https://www.googleapis.com/gmail/v1/users/me/labels'
// Validating that the authorization is done and we have a access_token to //make a request else throw the error
options.validateDependencies(input.access_token, function (err, status) {
if (err) {
return output({
error: err
})
}
// If the authorization is proper then execute the request
execute(input, options, output)
})
}
// common function for api to execute the request module
function execute (input, options, output) {
async.waterfall([
function (cb) {
// In input we get auth code which we can use to get access token
getAccessToken(input, options, cb)
}
], function (err, accessToken) {
if (err) {
return output({
error: err
})
} else {
// Execute the request to get the labels from the gmail api
requestExecute(input, accessToken, options, output)
}
})
}
// Extract the acces_token from the input and return it
function getAccessToken (input, options, cb) {
options.getAccessToken(input.access_token, function (err, oauth) {
if (err) {
cb(err)
} else {
oauth = JSON.parse(oauth)
cb(null, oauth.access_token)
}
})
}
// Make a request to the gmail url to get the labels
function requestExecute (input, accessToken, options, output) {
request({
method: 'GET',
headers: {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json'
},
url: options.url
}, function (err, res, body) {
let result = []
if (err) {
return output({
error: err
})
}
if (res.statusCode === 401) {
return output({
error: 'Your access token is Invalid or Expired'
})
}
if (res.statusCode >= 200 && res.statusCode < 400) {
if (typeof (body) === 'string') {
body = JSON.parse(body)
}
result = filterResult(body.messages || body.labels || body, input)
var pageDetails = options.getPage(result, input, options)
var data = {
'results': result.slice(pageDetails.page, (pageDetails.page + options.maxResults))
}
data.next_page = options.getNextPage(data.results.length >= options.maxResults)
return output(null, data)
}
return output({
error: body
})
})
}
// filter result on the basis of output demand
function filterResult (body, input) {
var result = []
if (body && Array.isArray(body)) {
body.forEach(function (item, index) {
result.push({
'id': String(item.name),
'value': item.name
})
})
}
return result
}
欲測試查詢,請執行下列指令:
1. 使用下列指令取得新存取權杖:
flow test oauth gmail-gmail -f ..\testOauthData.json -t "Test Gmail Oauth"
2. 儲存權杖並結束。
3. 使用下列指令測試查詢:
flow test lookup gmail getLabels -a cecd33a3-8a33-4c0c-b298-178fd80a9261 -l trace。您應該會看到查詢產生的輸出。輸出是 ID 與值的 JSON 陣列。
步驟 5:建立及測試動作 
在執行某些操作時,動作會與外部連線系統互動。通常,其為「建立讀取更新刪除」操作。動作會取用輸入,並產生一些輸出。由動作產生的輸入與輸出需在 action.json 檔案中指定。輸入與輸出內容是用來轉譯輸入表單的特殊 JSON 結構描述,而輸出結構描述可用來轉譯對應使用者介面。其他有用的內容包括標籤與圖示,它們可用來在使用者介面中為動作編組及顯示動作的圖示。
欲建立新動作,請執行下列指令:
c:\test\gmail>flow add action get-messages
[2018-10-22T16:26:53.925] [INFO] add-action - Action get-messages, version v1 added successfully
然後,在 IDE 中開啟 action.json 檔案 C:\test\gmail\action\gmail-get-messages\v1\action.json
設定 gmail 的輸入與圖示內容。輸入內容 JSON 結構描述如下列程式碼中所示:
Set the input property to {
"title": "Get email messages",
"type": "object",
"properties": {
"auth": {
"title": "Authorize gmail",
"type": "string",
"oauth": "gmail-gmail",
"minLength": 1
},
"label": {
"title": "Label",
"type": "string",
"minLength": 1,
"lookup": {
"id": "getLabels",
"service": "gmail",
"enabled": true,
"searchable": false,
"auth": "oauth",
"dependencies": [
"auth"
]
}
}
}
}
輸入結構描述會定義一個輸入欄位。這是一個清單,因為它有針對其指定的查詢。當在流程 composer 中使用時,會執行查詢,傳回的值會顯示在清單中。請注意查詢相依性的描述方式。這會通知系統,在呼叫查詢之前,必須填寫驗證欄位。
auth 內容描述此動作使用的驗證方法。在此情況下,我們使用 OAuth 組態 Gmail。
Set the “output” property to {
"messages": {
"title": "Messages",
"type": "array",
"items": {
"type": "object",
"properties": {
"messageId": {
"type": "string",
"title": "Message Detail ID"
},
"subject": {
"type": "string",
"title": "Message Detail Sub"
}
}
}
}
}
* 
此動作產生的輸出是 JSON 物件的 JSON 陣列。每個物件都擁有 messageIdsubject 欄位。
在 IDE 中開啟 index.js 檔案。在檔案最上方新增下列程式馬:
const rp = require('request-promise')
const logger = require('ptc-flow-sdk').getLogger('gmail-get-messages')
將執行方法取代為下列程式碼:
this.execute = function (input, output) {
// Create a request header to get messages under a label selected from
const options = {
method: 'GET',
url: 'https://www.googleapis.com/gmail/v1/users/me/messages',
useQuerystring: true,
qs: {labelIds: ['STARRED']},
headers:
{
'Authorization': 'Bearer ' + input.auth,
'Content-Type': 'application/json'
}
}
rp(options).then((rawData) => {
const data = JSON.parse(rawData)
let mailRequests = []
if (data && data.messages) {
data.messages.forEach((msg) => {
mailRequests.push(this.fetchMessage(msg.id, input.auth))
})
return Promise.all(mailRequests)
} else {
logger.warn('No messages found')
Promise.resolve()
}
}).then((results) => {
if (results) {
let arr = []
results.forEach((result) => {
let resData = JSON.parse(result)
let msgHeader = resData.payload.headers.find(header => header.name === 'Subject')
arr.push({messageId: resData.id, subject: msgHeader ? msgHeader.value : 'No subject'})
})
return output(null, {messages: arr})
} else {
return output(null)
}
}).catch(err => {
return output(err)
})
}
新增以下提供的新方法:
this.fetchMessage = function (msgId, authToken) {
const options = {
method: 'GET',
url: 'https://www.googleapis.com/gmail/v1/users/me/messages/' + msgId,
qs: { format: 'metadata', metadataHeaders: 'Subject' },
headers:
{
'Authorization': 'Bearer ' + authToken,
'Content-Type': 'application/json'
}
}
return rp(options)
}
請確保檔案是有效的 JavaScript 檔案。
1. 再次透過下列步驟取得存取權杖:
設定 FLOW_ALLOW_UNTRUSTED_CERTIFICATES=true
執行下列指令,然後記下傳回的 id。
flow test oauth gmail-gmail -f ..\testOauthData.json -t "Test Gmail Oauth"
2. 建立新 Javascript 檔案 C:\test\gmail\test\actionTestData.js,將下列程式碼新增到此檔案中,並儲存。
module.exports = {
testInput: {
label: 'STARRED'//use a label that applies to a few emails.
},
testOutputFn: function (input, actualOutput) {
// validate the actualOutput against expected output
// return a rejected promise to fail the validation or a resolved promise for success
// return Promise.reject(new Error('Validation successful'))
return Promise.reject(new Error('Validation failed'))
}
}
* 
-i/--input-o/--output 參數會接受傳回承諾的資料或函數。
當在伺服器上執行此程式碼時,標籤可作為輸入參數的一部份使用,而且可作為 input.label 存取。測試公用程式不會執行查詢,因此需要將查詢的輸出傳遞到其中。
3. 依照下列方式執行測試指令:
C:\test\gmail>flow test action gmail-get-messages -a 685b7377-7000-
4a92-8679-8630c68a3265 -l debug -i testInput -f
C:\test\gmail\test\actionTestData.js -o testOutput
The test run should succeed.
步驟 6:建立和測試輪詢觸發器 
1. 欲建立新的輪詢觸發器,請執行下列指令:
flow add trigger -p
[2019-02-28T17:03:23.823] [INFO] add-trigger - Trigger gmail, version v1 added successfully
2. 從 IDE 中開啟位於 C:\test\gmail\trigger\poll\gmail \v1\trigger.jsontrigger.json 檔案。
3. 依下列指示設定 gmail 的圖示內容:
"icon": "gmail",
4. 設定輸入與輸出內容。

Set the input property to
{
"properties": {
"auth": {
"type": "string",
"title": "Authorize gmail",
"minLength": 1,
"oauth": "gmail-gmail",
"propertyOrder": 1
},
"search": {
"type": "string",
"title": "Search Text",
"propertyOrder": 2,
"description": "Enter the search text to search for a specific email. E.g., from:john or subject:Christmas"
},
"customFilters": {
"type": "array",
"propertyOrder": 5,
"title": "Custom Filters",
"items": {
"type": "object",
"title": "Filter",
"properties": {
"input": {
"type": "string",
"title": "Input",
"minLength": 1
},
"operator": {
"type": "string",
"title": "Condition",
"enum": [
"Equals",
"GreaterThan"
],
"enumNames": [
"Equals",
"Greater Than"
]
},
"expected": {
"type": "string",
"title": "Expected",
"minLength": 1
}
}
}
}
},
"oneOf": [
{
"type": "object",
"title": "New Email",
"description": "Triggers when a new email is received",
"properties": {
"event": {
"type": "string",
"readonly": true,
"enum": [
"new_mail"
],
"options": {
"hidden": true
},
"propertyOrder": 3
},
"label": {
"type": "string",
"title": "Label",
"propertyOrder": 4,
"description": "Select a label for which you wish to set a trigger. E.g., If you select label as ‘Trash’, the trigger will fire off every time a new mail is moved to label named ‘Trash’ in your Gmail account."
}
}
},
{
"type": "object",
"title": "New Attachment",
"description": "Triggers when a new attachment is received",
"properties": {
"event": {
"type": "string",
"readonly": true,
"enum": [
"new_attachment"
],
"options": {
"hidden": true
},
"propertyOrder": 3
},
"label": {
"type": "string",
"title": "Label",
"propertyOrder": 4,
"description": "Select a label for which you wish to set a trigger. E.g., If you select label as ‘Trash’, the trigger will fire off every time a new mail is moved to label named ‘Trash’ in your Gmail account."
}
}
}
]
}
輸入結構描述會定義一個輸入欄位。OneOf 物件用於定義觸發器支援的事件。上述結構描述可定義兩個觸發器事件:
新電子郵件
新附件
auth 內容描述此觸發器使用的驗證方法。在此情況下,我們使用 OAuth 組態 Gmail。
Set the “output” property to
{
"new_mail": {
"type": "object",
"properties": {
"messageId": {
"type": "string",
"title": "ID",
"displayTitle": "ID"
},
"subject": {
"title": "Subject",
"displayTitle": "Subject",
"type": "string"
}
}
},
"new_attachment": {
"type": "object",
"properties": {
"attachments": {
"title": "Attachments",
"displayTitle": "Attachments",
"type": "array",
"items": {
"type": "object",
"properties": {
"mimeType": {
"title": "Mime Type",
"displayTitle": "Mime Type",
"type": "string"
},
"filename": {
"title": "File Name",
"displayTitle": "File Name",
"type": "string"
},
"attachmentId": {
"title": "Attachment ID",
"displayTitle": "Attachment ID",
"type": "string"
}
}
}
}
}
}
}
上述輸出結構描述用於定義觸發器輸入結構描述中所定義的兩個觸發器事件的輸出內容。
1. 在 IDE 中開啟 index.js 檔案,然後在檔案的頂部新增下列程式碼:
const rp = require('request-promise')
const logger = require('ptc-flow-sdk').getLogger('gmail-trigger')
2. 將執行方法取代為下列程式碼:
Trigger.execute = function (input, options, output) {
// Create a request header to get messages under a label selected from
var date = new Date(options.unixTime * 1000)
const httpOpts = {
method: 'GET',
url: 'https://www.googleapis.com/gmail/v1/users/me/messages',
useQuerystring: true,
qs: { q: 'newer:' + date.getFullYear() + '/' + date.getMonth() + '/' + date.getDay() },
headers:
{
'Authorization': 'Bearer ' + input.auth,
'Content-Type': 'application/json'
}
}
rp(httpOpts).then((rawData) => {
const data = JSON.parse(rawData)
let mailRequests = []
if (data && data.messages) {
data.messages.forEach((msg) => {
mailRequests.push(this.fetchMessage(msg.id, input.auth))
})
return Promise.all(mailRequests)
} else {
logger.warn('No messages found')
Promise.resolve()
}
}).then((results) => {
if (results) {
let arr = []
results.forEach((result) => {
let resData = JSON.parse(result)
let msgHeader = resData.payload.headers.find(header => header.name === 'Subject')
arr.push({ messageId: resData.id, subject: msgHeader ? msgHeader.value : 'No subject' })
})
return output(null, { messages: arr })
} else {
return output(null)
}
}).catch(err => {
return output(err)
})
}
3. 新增以下提供的新方法:
Trigger.fetchMessage = function (msgId, authToken) {
const options = {
method: 'GET',
url: 'https://www.googleapis.com/gmail/v1/users/me/messages/' + msgId,
qs: { format: 'metadata', metadataHeaders: 'Subject' },
headers:
{
'Authorization': 'Bearer ' + authToken,
'Content-Type': 'application/json'
}
}
return rp(options)
}
* 
請確保檔案是有效的 JavaScript 檔案。
步驟 7:擷取存取權杖 
欲再次擷取存取權杖,請執行下列步驟:
1. 設定下列內容:FLOW_ALLOW_UNTRUSTED_CERTIFICATES=true
2. 執行下列指令,然後記下傳回的 id。
flow test oauth gmail-gmail -f ..\testOauthData.json -t "Test Gmail Oauth"
3. 依照下列方式執行測試指令:
flow test trigger gmail execute -p -e new_mail -a e0d56340-2fc4-4618-931c-ad6c983ae0e5 --stopAfter 1 --unixTime 1551312000
步驟 8:將圖示新增至連接器 
1. 在連接器專案中建立 common 資料夾。
2. common 資料夾下,建立名為 css 的資料夾。
3. 以下列格式新增 JSON 檔案:
{ "name": "connector-name",
"background": "#FFFFFF",
"png128pxBase64": "base64encodedbinarydata"
}
name 內容應為連接器的名稱,且應與動作 metadata json 檔案中動作的 icon 內容相符。
背景應為十六進位顏色代碼,如範例所示。
圖示圖像應為 .png 格式,二進位資料應以 base64 編碼。如需詳細資訊,請在網際網路搜尋有關如何將 PNG 轉換為其 base64 編碼二進位表示法的內容。
這是否有幫助?