ThingWorx Flow > ThingWorx Flow SDK > 附录 B:ThingWorx Flow 连接器 SDK 教程
附录 B:ThingWorx Flow 连接器 SDK 教程
先决条件
以下是本教程所需的先决条件:
LTS 版本的 Node.js 8.9.0 + 安装程序
可处理 Node js 项目的集成开发环境 (IDE)。
本教程使用 WebStorm 作为 IDE。
对节点 js 代码的中级理解
示例文件夹
简介
本教程说明了构建典型连接器所需的步骤。我们将构建 Gmail 连接器,因为大多数开发人员可能熟悉 Gmail 的工作原理。通过构建连接器,您可以熟悉构建连接器时所涉及的工具、构件和过程,同时也有助于为您的应用程序构建连接器。构建新连接器时不需要部署 ThingWorx Flow。在本地完成连接器的构建和测试后,可以将其部署到本地测试安装,以便进行测试。
本教程涵盖了以下内容:
1. 创建连接器项目。
2. OAuth2 配置
3. 创建一个查找,以搜索使用您的 Gmail 帐户创建的筛选器。
4. 创建一个操作,以获取与所选筛选器相匹配的电子邮件消息的 ID 和主题。
5. 创建一个触发器,以允许在收到新邮件时启动新工作流。
6. 添加图标
7. 将连接器部署到 ThingWorx Flow 的本地实例。
创建连接器项目
连接器是一个专用的 npm 包,其中包含各种构件,例如 OAuth 配置、操作、查找和触发器等。该项目应遵循构建 npm 包的模式。它应该具有 package.json、lib 文件夹、测试文件夹和针对每个构件及其版本的文件夹。
打开 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 选项提供连接器目录的完整路径。
创建 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 文件。如果这不是实际的主机名称,而是本地主机的别名,请将其添加到您所用操作系统的主机文件。
例如,
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 文件是一个模板,必须对其进行自定义,才能将其与类似 google 的特定 OAuth 提供工具配合使用。
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
测试 OAuth 配置
可以在部署之前测试 OAuth 配置。为此,ThingWorx Flow CLI 会启动浏览器,您可以使用凭据登录 OAuth 提供工具。如果身份验证成功,则系统会生成访问令牌,并且您可以将其保存到磁盘,以供日后使用。也可以通过在嵌入式 Chrome 浏览器窗口中选择适当的配置对每个部署配置进行测试。
在运行测试命令之前,我们需要创建测试数据文件,此文件中包含的实际客户端 ID 和密码将替换上述 env_<environment-name>_params。要执行此操作,请在 c:\test 中新建一个名为 testOauthData.json 的 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 将用于测试其他依存访问令牌的构件,例如查找、操作和触发器。上面生成的 ID 应提供给所有使用 -a/--access_token 选项的测试命令。
* 
如果您收到重定向 URI 不匹配这类的错误,您应确保 flow.json 配置正确,且工作流使用的 URL 与注册到 google 的 URL 相匹配。工作流使用的重定向 URL 将在测试启动时在控制台上打印出来。
例如,[2018-10-22T11:07:53.868] [INFO] oauthServer - Server started, redirect_uri used for oauth = https://flow.local.rnd.ptc.com:443/Thingworx/Oauths/oauth/return
* 
OAuth 访问令牌的使用期限很短,在使用访问令牌测试操作、查找、触发器之前,您应该运行 flow test oauth 命令以重新生成新令牌。
创建查找
“查找”是一种搜索机制。它们通常用于动态获取操作或触发器的某些输入字段的选项列表。例如,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 数组。
创建和测试操作
操作与外部连接系统进行交互,以执行一些操作。这些操作通常为“创建”、“读取”、“更新”和“删除”操作。操作会获取输入并生成某些输出。通过操作生成的输入和输出需要在 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
将 input 和 icon 属性设置为 gmail。input 属性 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"
]
}
}
}
}
输入架构将定义单一输入字段。这是一个列表,因为它指定了查找。在工作流合成器中使用时,系统会执行查找,且返回的值会显示在此列表中。请注意查找依赖项的描述方式。这将通知系统在调用查找之前,必须填充身份验证字段。
身份验证属性用于描述此操作所使用的身份验证方法。在这种情况下,我们使用 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 参数会接受返回 promise 的数据或函数。
当此文件在服务器上运行时,标签可作为输入参数的一部分,也可作为 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.
创建和测试轮询触发器
1. 要创建新的轮询触发器,请执行以下命令:
flow add trigger -p
[2019-02-28T17:03:23.823] [INFO] add-trigger - Trigger gmail, version v1 added successfully
2. 在 IDE 中,打开 trigger.json 文件,位于 C:\test\gmail\trigger\poll\gmail\v1\trigger.json
3. 如下所示设置 gmail 的 icon 属性:
"icon": "gmail",
4. 设置 input 和 output 属性。

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"
}
}
}
}
}
}
}
以上输出架构定义在触发器输入架构中指定的两个触发器事件的 output 属性。
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 文件。
获取访问令牌
要再次获取访问令牌,请按以下步骤操作:
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
将图标添加到连接器
1. 在连接器项目中创建 common 文件夹。
2. common 文件夹下,创建一个名为 css 的文件夹。
3. 添加具有下列格式的 JSON 文件:
{ "name": "connector-name",
"background": "#FFFFFF",
"png128pxBase64": "base64encodedbinarydata"
}
name 属性的名称应与连接器名称相同,且应与 metadata json 文件中操作的 icon 属性相匹配。
如示例中所示,背景应为十六进制色码。
图标图像应为 .PNG 格式,二进制数据应使用 base64 进行编码。有关详细信息,请通过互联网搜索如何将 PNG 转换为其 base64 编码二进制表示。