產(chǎn)品介紹
什么是數(shù)環(huán)通
基礎概念講解
應用場景
多渠道數(shù)據(jù)融合
業(yè)務、財務、辦公自動化
產(chǎn)業(yè)鏈應用與數(shù)據(jù)集成
工業(yè)應用與設備互聯(lián)
智慧園區(qū)與未來社區(qū)
快速入門
創(chuàng)建LinkUp
應用授權(quán)
判斷用法
監(jiān)控用法
分支用法
列表逐條處理
變量與表達式
流程管理
項目管理
流程創(chuàng)建
編輯器操作
單步測試與預覽
試運行
發(fā)布與版本管理
錯誤步驟重試
數(shù)據(jù)同步
JSON Path 使用
輸出處理
數(shù)據(jù)編排
1、功能使用手冊
2、腳本使用手冊
1 、簡單查詢
2、謂詞查詢
3、函數(shù)與表達式
4、構(gòu)建結(jié)構(gòu)結(jié)果
5、查詢組合
6、排序、分組和聚合
7、處理模型
8、函數(shù)式編程
9、正則表達式
10、日期、時間處理
11、路徑運算符
12、數(shù)字運算符
13、比較運算符
14、布爾運算符
15、其他運算符
16、字符串函數(shù)
17、數(shù)值函數(shù)
18、 數(shù)字聚合函數(shù)
19、布爾函數(shù)
20、數(shù)組函數(shù)
21、對象函數(shù)
22、日期/時間函數(shù)
23、高階函數(shù)
運行日志
運行記錄
開發(fā)工具
連接器工具
連接器源碼配置
控件類型配置
腳本配置說明
內(nèi)置函數(shù)
應用講解
內(nèi)置應用
瀏覽器插件
數(shù)據(jù)表
文本字符串
日期
數(shù)據(jù)篩選
數(shù)據(jù)處理
延時處理
數(shù)學計算器
定時觸發(fā)器
子流程調(diào)用
手動觸發(fā)器
物流地址解析
腳本執(zhí)行器
自定義變量
文件讀取
Webhook
SMTP發(fā)送郵件
文件傳輸
JSON工具
網(wǎng)絡工具
消息處理
PDF水印工具
文件存儲
API服務
Http請求
循環(huán)控制
EDI 自定義標準數(shù)據(jù)轉(zhuǎn)換
對象類型判斷
瀏覽器操作
三方應用
簡道云
金山數(shù)據(jù)表
抖音
釘釘(自建應用)
語雀
金山表單
微信公眾號
企業(yè)微信群機器人
聚水潭
企業(yè)微信三方授權(quán)
MySQL
SqlServer
ChatGpt
快手
金山輕維表
抖店
維格表
巨量千川
飛書多維表
釘釘機器人
飛書(自建)
釘釘
百度網(wǎng)盤
QQ郵箱
金山工作表
易知微DTable
MQTT
Doirs
中通快遞
韻達速遞
企業(yè)微信(代開發(fā))
知乎效果營銷平臺
飛書云文檔
騰訊企業(yè)郵箱
API管理
API管理概述
數(shù)據(jù)概覽
API服務
訪問憑證
API門戶
API安全密鑰簽名
API監(jiān)控預警
擴展工具
代理網(wǎng)關(guān)
消息處理
管理中心
企業(yè)管理
操作日志
成員管理
開放平臺
開放平臺簡介
接入教程
常見問題
數(shù)環(huán)通ip白名單
最佳實踐
彥祖文化 |通過數(shù)環(huán)通實現(xiàn)全渠道數(shù)據(jù)融合打通
新石器|通過數(shù)環(huán)通實現(xiàn)跨系統(tǒng)、跨部門高效協(xié)同
幫助首頁
開發(fā)工具
連接器源碼配置
連接器源碼配置
# 1. 連接器定義 ## 1.1 授權(quán)定義 * auth:連接器調(diào)用對應 SaaS 軟件的授權(quán)方式,授權(quán)的定義是一個對象,當沒有授權(quán)時可以為空 * authType 授權(quán)類型,是第三方 SaaS 軟件驗證數(shù)環(huán)通權(quán)限的方式,目前主要有以下幾種類型 * api_token 通過 AppKey + AppSecret 直接訪問或者通過 AppKey + AppSecret 換取 AccessToken 進行調(diào)用第三方 SaaS 的 API 接口,典型的 SaaS 有:自建釘釘,維格表等 * oauth2 數(shù)環(huán)通作為第三方 SaaS 的平臺服務商申請 AppKey+ AppSecret, 用戶通過授權(quán)數(shù)環(huán)通,由數(shù)環(huán)通獲取用戶的授權(quán) AccessToken 調(diào)用第三方 SaaS 的 API 接口,典型的 SaaS 有:企業(yè)微信三方,釘釘三方 * polling_oauth2 數(shù)環(huán)通作為第三方 SaaS 的平臺服務商申請 AppKey+ AppSecret, 用戶通過授權(quán)數(shù)環(huán)通,由數(shù)環(huán)通獲取用戶的授權(quán) AccessToken 調(diào)用第三方 SaaS 的 API 接口,但是與 Oauth2 的區(qū)別在于,用戶的授權(quán)信息是通過后端服務接口進行推送的,典型的 SaaS 有:聚水潭  * test 測試輸入賬號有效性的執(zhí)行方法,主要是在新增賬號時調(diào)用,用于驗證用戶輸入的數(shù)據(jù)是否有效,具體執(zhí)行方法的定義參考執(zhí)行方法定義 * validate 驗證當前賬號的授權(quán)有效性的執(zhí)行方法,主要是在賬號新增賬號成功后調(diào)用,用于驗證當前授權(quán)信息如 AccessToken 等是否是有效狀態(tài),具體執(zhí)行方法的定義參考執(zhí)行方法定義 * apiTokenConfig api_token 類型的配置 * autoRefresh 是否需要自動刷新,Boolean 類型 * true 需要刷新,需要配置 refreshAccessToken * false 不需要自動刷新,AccessToken 是永久有效的 * autoRefreshInterval 自動刷新的間隔,Integer 類型 單位秒 例如 3600 表示每小時刷新一次 token * accessToken 獲取 AccessToken 的執(zhí)行方法 * refreshAccessToken 刷新 AccessToken 的執(zhí)行方法 * oauth2Config oauth2 和 polling_oauth2 的授權(quán)配置 * autoRefresh 是否需要自動刷新,Boolean 類型 * true 需要刷新,需要配置 refreshAccessToken * false 不需要自動刷新,AccessToken 是永久有效的 * autoRefreshInterval 自動刷新的間隔,Integer 類型 單位秒 例如 3600 表示每小時刷新一次 token * preAuthorize 獲取授權(quán)鏈接前執(zhí)行方法列表,例如獲取預授權(quán)碼 * authorizeUrl 獲取授權(quán)鏈接的執(zhí)行方法 * accessToken 獲取 AccessToken 的執(zhí)行方法 * refreshAccessToken 刷新 AccessToken 的執(zhí)行方法 * thirdAuthConfig third_auth 類型的配置 * autoRefresh 是否需要自動刷新,Boolean 類型 * true 需要刷新,需要配置 refreshAccessToken * false 不需要自動刷新,AccessToken 是永久有效的 * autoRefreshInterval 自動刷新的間隔,Integer 類型 單位秒 例如 3600 表示每小時刷新一次 token * accessToken 獲取 AccessToken 的執(zhí)行方法 * refreshAccessToken 刷新 AccessToken 的執(zhí)行方法 * helpFields 顯示提示幫助的字段列表,如提示用戶如何進行配置賬號和事件訂閱 * inputFields 用戶需要輸入的參數(shù)字段列表,例如 Appkey,AppSecret 等,具體的字段配置參考字段定義 * outputFields 保存到數(shù)據(jù)的參數(shù)列表,具體的字段配置參考字段定義 授權(quán)類型的說明: api_token 類型的授權(quán)流程:  oauth2 授權(quán)流程:  polling_oauth2 類型授權(quán)流程:  ## 1.2 賬號定義 * asset:連接器的賬號配置,主要是配置授權(quán)的哪些數(shù)據(jù)需要保存到賬號資產(chǎn)的數(shù)據(jù)庫中 * autoRefresh 是否需要自動刷新,Boolean 類型,需要與授權(quán)定義中保持一致 * true 需要刷新,需要配置 refreshAccessToken * false 不需要自動刷新,AccessToken 是永久有效的 * autoRefreshInterval 自動刷新的間隔,Integer 類型 單位秒 例如 3600 表示每小時刷新一次 token * assetTemplate 保存的字段列表,用于定義哪些字段需要存進賬號資產(chǎn)中 * assetNameField 賬號名稱字段 * assetUkField 賬號唯一性標識字段 ## 1.3 模板配置 * requestTemplate:連接器的請求模板配置,主要是配置當前連接器發(fā)起 Http 請求時的公共參數(shù),如 appKey,簽名配置等公共的配置,可以減少請求的配置 * method 發(fā)起請求的方法,支持以下選項 * GET * PUT * POST * PATCH * DELETE * HEAD * url 請求的完整地址 * body 請求 body 配置 * bodyType 請求體類型 * NULL 為空 * STRING 字符串 * ARRAY 數(shù)組 * OBJECT JSON 對象類型 * XML XML 格式 * bodyContent 請求體內(nèi)容,根據(jù) bodyType 傳入具體的值 * queryParams 查詢請求參數(shù),KV 形式 * formParams 表單請求參數(shù),KV 形式 * headers 頭部請求參數(shù) * signConfig 簽名配置 * signType 簽名類型,簽名的實現(xiàn),目前可以使用簽名腳本類型 * script 通過簽名腳本進行簽名 * signOutField 簽名輸出字段 * signInField 簽名字段參數(shù),KV 形式 * signSetting 簽名配置,針對腳本簽名需要增加以下參數(shù) * connectorId 連接器 ID * scriptType 腳本類型 * sceneCode 場景編碼 * version 腳本版本 * responseType 請求返回值類型,默認按照 STRING 處理 * BINARY 二進制 * JSON JSON 格式 * STRING 純文本格式 * beforeRequest 請求前執(zhí)行方法列表,一般用于對請求參數(shù)進行處理 * afterResponse 請求后執(zhí)行方法列表,一般用于對于返回數(shù)據(jù)進行處理 * triggerTemplate:消息通知和回調(diào)的配置。主要是配置當前連接器接收平臺 Http 請求時的參數(shù),可用來做觸發(fā)器配置 * pushUrl:消息推送回調(diào)地址。如:${eventDomainHost}/event/customPush/com.yuque.app/${assetId}/test * com.yuque.app 為連接器 ID,用戶務必配置為當前連接器的 ID * test 為用戶自定義參數(shù) * pushExecutor:推送數(shù)據(jù)的腳本配置 * executeType:執(zhí)行類型。設置為 script * connectorId:當前連接器的 ID * connectorVersion:當前連接器的版本 * sceneCode:場景碼。這里設置為 dealPushEventContent * type:腳本類型。可選擇 java,js,pythone * version:腳本的版本號。可設置為 1~9 ## 1.4 觸發(fā)器 * triggers 觸發(fā)器列表,用于觸發(fā)器定義,觸發(fā)器列表是個 KV 列表,其中 Key 是觸發(fā)器的關(guān)鍵字定義,Value 是一個觸發(fā)器定義 * key 用于唯一標識觸發(fā)器 * value 觸發(fā)器的具體定義 觸發(fā)器對象的定義: * key 觸發(fā)器的 key 和前文的 key 保持一致 * paramClass 參數(shù)對象類型,主要為了以后對參數(shù)映射進行擴展使用,當前暫時可以不配置 * resultClass 結(jié)果對象類型,主要為了以后對參數(shù)映射進行擴展使用,當前暫時可以不配置 * resultIsList 結(jié)果是否是一個數(shù)組列表,此處主要針對的是一級結(jié)果,默認為 false * true 表示結(jié)果是一個數(shù)組列表 * false 表示結(jié)果不是一個數(shù)組列表 * display 展示配置,用于前端頁面展示觸發(fā)器的名稱等信息 m * label 觸發(fā)器展示的名稱 * description 觸發(fā)器的描述信息 * directions 鏈接信息,可以設置為該觸發(fā)器的來源頁面地址 * important 是否置頂,默認為 false * true 表示需要置頂 * false 表示不需要置頂 * hidden 是否隱藏,當設置為 true 時前端不展示該觸發(fā)器,默認為 false * true 表示需要隱藏 * false 表示不需要隱藏 * triggerMode 觸發(fā)器的模式,主要是定義觸發(fā)器的數(shù)據(jù)來源,目前的選項有:輪詢和事件觸發(fā) * polling 通過輪詢方式查詢數(shù)據(jù),一般是通過時間來查詢某個列表 * pushing 事件或者消息來源,一般是第三方 SaaS 通過配置回調(diào)接口,進行事件推送 * triggerConfig 觸發(fā)器配置,主要是針對輪詢方式的觸發(fā)器的配置 * cron 輪詢的時間表達式, * outOfFrequencyControl 配置為 true cron 表達式才生效,否則會根據(jù)用戶版本設置輪訓周期 * startTime 開始觸發(fā)的時間 * ukFields 唯一標識記錄的字段列表,主要用于標識該條記錄有沒有觸發(fā)過 * supportPaging 是否支持分頁,支持分頁時需要 * true 支持 * false 不支持 * pageSize 分頁大小設置 * pageSizeField 分頁大小對應的字段名稱 * pageIndexField 分頁頁碼對應的字段名稱 * operation 獲取觸發(fā)數(shù)據(jù)的執(zhí)行方法,對于輪詢的觸發(fā)器需要進行定義,事件觸發(fā)的無需定義,要求執(zhí)行方法返回的數(shù)據(jù)是數(shù)組 * sample 獲取樣本數(shù)據(jù)的執(zhí)行方法,對于輪詢的觸發(fā)器需要進行定義,事件觸發(fā)的無需定義,要求執(zhí)行方法返回的數(shù)據(jù)是單個對象 * beforeTrigger 觸發(fā)器執(zhí)行請求前執(zhí)行方法列表,一般用于對請求參數(shù)進行處理,beforeTrigger 的執(zhí)行時機是在獲取到觸發(fā)事件的數(shù)據(jù)之后,進行流程觸發(fā)之前,對于事件觸發(fā)的是在收到第三方的事件觸發(fā)之后,對于輪詢觸發(fā)的是在執(zhí)行輪詢 operation,獲取到單個對象之后 * afterTrigger 觸發(fā)器后執(zhí)行方法列表,一般用于對于返回數(shù)據(jù)進行處理,執(zhí)行時機是在發(fā)出觸發(fā)事件之后 ## 1.5 執(zhí)行器 * operations 執(zhí)行器列表,用于執(zhí)行器定義,執(zhí)行器列表是個 KV 列表,其中 Key 是執(zhí)行器的關(guān)鍵字定義,Value 是一個執(zhí)行器定義 * key 用于唯一標識執(zhí)行器 * value 執(zhí)行器的具體定義 執(zhí)行器對象的定義: * key 執(zhí)行器的 key 和前文的 key 保持一致 * paramClass 參數(shù)對象類型,主要為了以后對參數(shù)映射進行擴展使用,當前暫時可以不配置 * resultClass 結(jié)果對象類型,主要為了以后對參數(shù)映射進行擴展使用,當前暫時可以不配置 * resultIsList 結(jié)果是否是一個數(shù)組列表,此處主要針對的是一級結(jié)果,默認為 false * true 表示結(jié)果是一個數(shù)組列表 * false 表示結(jié)果不是一個數(shù)組列表 * hidden 是否隱藏,當設置為 true 時前端不展示該執(zhí)行器,默認為 false * true 表示需要隱藏 * false 表示不需要隱藏 * display 展示配置,用于前端頁面展示執(zhí)行器的名稱等信息 * label 執(zhí)行器展示的名稱 * description 執(zhí)行器的描述信息 * directions 鏈接信息,可以設置為該執(zhí)行器的來源頁面地址 * important 是否置頂,默認為 false * true 表示需要置頂 * false 表示不需要置頂 * categoryName 分類名,把同一類的放在一個組下,如 訂單、商品、 * operation 執(zhí)行器的請求定義,在此定義執(zhí)行器方法(具體定義看 3.8 執(zhí)行方法定義) * inputFields 執(zhí)行器輸入字段定義 * outputFields 執(zhí)行器輸出字段定義 * tags 該執(zhí)行器的備注信息 ## 1.6 執(zhí)行方法定義 執(zhí)行方法是引擎支持的某個具體的執(zhí)行定義,當前支持 4 種類型,分別為: * request 請求類型 * function 函數(shù)類型 * dependency 依賴類型 * script 腳本類型 根據(jù)每個類型有具體的定義: ### 1.6.1 請求類型 請求類型是指主體功能是調(diào)用 HTTP API * executeType: request 請求類型 * method 發(fā)起請求的方法,支持以下選項 * GET * PUT * POST * PATCH * DELETE * HEAD * url 請求的完整地址 * body 請求 body 配置 * bodyType 請求體類型 * NULL 為空 * STRING 字符串 * ARRAY 數(shù)組 * OBJECT JSON 對象類型 * XML XML 格式 * bodyContent 請求體內(nèi)容,根據(jù) bodyType 傳入具體的值 * queryParams 查詢請求參數(shù),KV 形式 * formParams 表單請求參數(shù),KV 形式 * headers 頭部請求參數(shù) (在此定義優(yōu)先級高于 requestTemplate 中的定義) * signConfig 簽名配置 * signType 簽名類型,簽名的實現(xiàn),目前可以使用簽名腳本類型 * script 通過簽名腳本進行簽名 * signOutField 簽名輸出字段 * signInField 簽名字段參數(shù),KV 形式 * signSetting 簽名配置,針對腳本簽名需要增加以下參數(shù) * connectorId 腳本連接器 ID * scriptType 腳本類型 * sceneCode 場景編碼 version 腳本版本 * beforeRequest 請求前執(zhí)行方法列表,一般用于對請求參數(shù)進行處理 * afterResponse 請求后執(zhí)行方法列表,一般用于對于返回數(shù)據(jù)進行處理 ### 1.6.2 函數(shù)類型 函數(shù)類型是指調(diào)用一個內(nèi)置類的函數(shù),或者內(nèi)置表達式 * executeType function 函數(shù)類型 * isExpress 是否是表達式 * true 是 執(zhí)行的是內(nèi)置表達式 * false 否 執(zhí)行的是類方法 * providerClass 執(zhí)行類的全路徑,isExpress 為 false 時必填 示例: ? "providerClass":"com.shuhuan.ipaas.connector.spi.yunpian.InputAndOutputBuilder" * function 執(zhí)行的具體方法,對于表達式來說是具體的表達式,對于執(zhí)行類方法時是類的方法,對于是表達式時是具體的表達式 示例: ? "function":"generateTemplateContentInput" ? "function":"${assert:equals(0,object:eval(body, '/msg'))}" * paramsExpression 參數(shù)表達式,對于執(zhí)行類方法時傳入 * returnType 返回值類型 * VOID 無返回值 * STRING 字符串 * BOOLEAN 布爾值 * NUM 數(shù)字 * INT 整形數(shù)字 * ARRAY 數(shù)組或者列表 * OBJECT 對象或者 Map 類型 * returnItemType 返回列表的數(shù)據(jù)類型,returnType 是 ARRAY 時需要 * VOID 無返回值 * STRING 字符串 * BOOLEAN 布爾值 * NUM 數(shù)字 * INT 整形數(shù)字 * ARRAY 數(shù)組或者列表 * OBJECT 對象或者 Map 類型 ### 1.6.3 依賴類型 依賴類型是指可以調(diào)用一組已經(jīng)配置的執(zhí)行動作,并做一些數(shù)據(jù)處理 * executeType dependency 依賴類型 * dependencyOperationKeys 依賴的執(zhí)行動作的 Key 列表 示例: ? "dependencyOperationKeys": ["getUidByMobile", "getUserDetailByUserId"] * afterResponse 所有依賴的執(zhí)行動作執(zhí)行完成后執(zhí)行方法列表,一般用于對于返回數(shù)據(jù)進行處理 ### 1.6.4 腳本類型 腳本類型是指執(zhí)行一個腳本 * executeType script 腳本類型 * connectorId 腳本對應的連接器 ID * sceneCode 腳本場景碼,用來標識該腳本應用場景 * type 腳本類型 * java * js * python * version 腳本版本 * paramsExpression 執(zhí)行的參數(shù)表達式,表達式為空時將會將整個參數(shù)上下文傳入,不為空時計算完成表達式后傳入 * returnType 返回值類型 * VOID 無返回值 * STRING 字符串 * BOOLEAN 布爾值 * NUM 數(shù)字 * INT 整形數(shù)字 * ARRAY 數(shù)組或者列表 * OBJECT 對象或者 Map 類型 * returnItemType 返回列表的數(shù)據(jù)類型,returnType 是 ARRAY 時需要 * VOID 無返回值 * STRING 字符串 * BOOLEAN 布爾值 * NUM 數(shù)字 * INT 整形數(shù)字 * ARRAY 數(shù)組或者列表 * OBJECT 對象或者 Map 類型 ## 1.7 字段定義 * key 用于該執(zhí)行方法中唯一標識字段 * label 展示配置,用于前端頁面展示字段名稱 * helpText 幫助信息,作為輸入字段時需要,非必要不填寫 * placeholder 輸入框提示信息,作為輸入字段時需要 * type 字段類型 * widget 前端控件 [widgetConfig 配置說明文檔](http://www.sqtsgm.com/help/article/1970) * widgetConfig 前端組件的配置 KV 形式 * required 是否為必填選項,作為輸入字段時需要 * true 必填 * false 選填 * defaultValue 默認值 * supportMultiple 是否支持多選,默認 false(搭配選擇控件時使用) * true 支持 * false 不支持 * datasource 可選數(shù)據(jù)源,KV 形式 * label 展示鍵 * value 實際值 * dynamicDataSource 動態(tài)數(shù)據(jù)源 [動態(tài)數(shù)據(jù)路由](http://www.sqtsgm.com/help/article/1970) * routerType 動態(tài)類型 * beforeRequest 在請求之前 * afterRequest 在請求響應之后 * constant 常量 * condition 判斷是否符合路由條件 * params 執(zhí)行動態(tài)數(shù)據(jù)源的參數(shù)列表 * selectCondition 判斷是否可選的條件表達式 * deepCondition 判斷是否可下拉的條件表達式 * refOperation 獲取動態(tài)數(shù)據(jù)源的執(zhí)行動作 * refLabel 動態(tài) label 的取值方式 * refValue 動態(tài) value 的取值方式 * router 下級的路由規(guī)則 * datasource 靜態(tài)數(shù)據(jù)源,routerType 為 constant 時設置 * dynamicFields 動態(tài)字段 [dynamicFields](http://www.sqtsgm.com/help/article/1970) * routerType 動態(tài)類型 * beforeRequest 在請求之前 * afterRequest 在請求響應之后 * constant 常量 * condition 判斷是否符合路由條件 * params 參數(shù)列表 * refOperation 獲取動態(tài)字段的執(zhí)行動作 * refInputFields 動態(tài)輸入字段的取值表達式 * refOutputFields 動態(tài)輸出字段的取值表達式 * inputFields 對于 routerType 是 constant 時設置 * outputFields 對于 routerType 是 constant 時設置 * childrenType 子節(jié)點類型 * children 子節(jié)點 # 2.簽名腳本開發(fā) 詳細參考:http://www.sqtsgm.com/doc/131/ 在應用 shuhuan-ipaas-app-libs 的 signer 目錄下開發(fā)簽名類,簽名算法改成通過 java 執(zhí)行腳本的方案實現(xiàn)簽名算法,簽名類需要繼承 JavaScriptRunner 類重寫 execute 方法 ``` /** * @author yunmu * @date 2022-03-04 6:44 下午 */ public abstract class JavaScriptRunner { public abstract <T> T execute(Object params); } ``` params 是一個 Map 對象,Map 中會包含以下數(shù)據(jù): * 上下文參數(shù)數(shù)據(jù) * signRequest 待簽名的 http 請求獲取方式: ``` HttpApiRequest apiRequest = (HttpApiRequest) paramsMap.get(SignConfigConstant.SIGN_REQUEST); ``` * 簽名配置中的 signInField 中的信息 * signOutField 簽名的輸出字段 簽名腳本示例: ``` package com.shuhuan.ipaas.applibs.signer; import com.aliyun.unicorn.http.MultipartFormData; import com.aliyun.unicorn.http.MultipartFormValue; import com.aliyun.unicorn.http.QueryString; import com.aliyun.unicorn.sdk.HttpApiRequest; import com.aliyun.unicorn.type.Consumer; import com.aliyun.unicorn.type.Parameter; import com.shuhuan.ipaas.common.ResultCode; import com.shuhuan.ipaas.core.encryption.Md5Util; import com.shuhuan.ipaas.exception.IpaasException; import com.shuhuan.ipaas.meta.constants.SignConfigConstant; import com.shuhuan.ipaas.script.java.JavaScriptRunner; import org.apache.commons.lang3.StringUtils; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; /** * @author yunmu * @date 2022-03-05 4:22 下午 */ public class BanniuScriptSigner extends JavaScriptRunner { private static final String METHOD = "method"; private static final String ACCESS_TOKEN = "access_token"; public static final String TIMESTAMP = "timestamp"; private static final String SIGN = "sign"; @Override public <T> T execute(Object params) { if (!(params instanceof Map)){ throw new IpaasException(ResultCode.PARAM_ERROR, "params is not map"); } Map<String,Object> paramsMap = (Map<String, Object>) params; HttpApiRequest apiRequest = (HttpApiRequest) paramsMap.get(SignConfigConstant.SIGN_REQUEST); String appKey = (String) paramsMap.get(SignConfigConstant.APP_KEY); String appSecret = (String) paramsMap.get(SignConfigConstant.APP_SECRET); QueryString queryString = apiRequest.getQueryString(); TreeMap<String, String> pmap = new TreeMap<>(); queryString.foreachValues((paramKey, value) -> { pmap.put(paramKey, value); }); MultipartFormData formData = apiRequest.getForm(); if (formData != null && !formData.isMultipart()) { apiRequest.getForm().foreach(new Consumer<Parameter<MultipartFormValue>>() { @Override public void accept(Parameter<MultipartFormValue> a) { String v = a.getFirstValue() != null ? a.getFirstValue().getValue() : null; if (METHOD.equals(a.getName())) { pmap.put(METHOD, v); } if (ACCESS_TOKEN.equals(a.getName())) { pmap.put(ACCESS_TOKEN, v); } if (TIMESTAMP.equals(a.getName())) { pmap.put(METHOD, v); } if (ACCESS_TOKEN.equals(a.getName())) { pmap.put(ACCESS_TOKEN, v); } } }); } String stringToSign = sign(pmap, appSecret); String signature = Md5Util.md5(stringToSign, "utf-8").toUpperCase(); queryString.add(SIGN, signature); Map<String, String> resultMap = new HashMap<>(); resultMap.put(SignConfigConstant.SIGNATURE, signature); resultMap.put(SignConfigConstant.STRING_TO_SIGN, stringToSign); return (T) resultMap; } // 代碼一, 簽名排序代碼. // pmap 為所有參數(shù), TreeMap 表示為樹形結(jié)構(gòu)的哈希容器 // appSecret 班牛分配給您的密鑰 private String sign(TreeMap<String, String> pmap, String appSecret) { StringBuilder sb = new StringBuilder(appSecret); Iterator i$ = pmap.entrySet().iterator(); while (i$.hasNext()) { Map.Entry<String, String> entry = (Map.Entry) i$.next(); String name = entry.getKey(); String value = entry.getValue(); if (StringUtils.isNoneEmpty(new String[]{name, value})) { sb.append(name).append(value); } } sb.append(appSecret); return sb.toString(); } } ``` # 3.觸發(fā)器腳本開發(fā) 詳細參考:http://www.sqtsgm.com/doc/131/ 編寫事件回調(diào)數(shù)據(jù)處理腳本。例如 1. ```java package com.shuhuan.ipaas.applibs.dealPushEventContent.caoliao; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Lists; import com.shuhuan.ipaas.script.java.JavaScriptRunner; import lombok.extern.slf4j.Slf4j; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 推送事件 數(shù)據(jù)處理 * 文檔地址: https://cli.im/help/65847 */ @Slf4j public class caoliaoDemo extends JavaScriptRunner { private static final String EVENT_TYPE = "eventType"; private static final String BODY = "body"; private static final String EVENT_CONTENTS = "eventContents"; private static final String EVENT_CONTENT = "eventContent"; private static final String ASSET = "asset"; private static final String RESULT = "result"; @Override public <T> T execute(Object params) { return (T) buildPushEventOutput(params); } /** * @param params * * { * "asset": { * }, * "body": { * "time": "2022-06-30 17:06:39", * "event": "FORM_DATA_SUBMIT", * "data": { * "ref_data": { * "created_at": "2022-06-30 17:06:39", * "serial_number": "L1000001", * "form": { * "number": "D20", * "name": "會議簽到" * }, * "fields": { * "姓名": "草料", * "手機": "18888648888", * "微信名": "CHEN", * "身份證號": "330200000000000000", * "工號": "FBI100", * "單選項": "是" * } * } * } * } * * * @return * { * "result": { * "code": 200, * "message": "success" * }, * "eventContents": [ * { * "eventType": "FORM_DATA_SUBMIT", * "eventContent": { * "ref_data": { * "created_at": "2022-06-30 17:06:39", * "serial_number": "L1000001", * "form": { * "number": "D20", * "name": "會議簽到" * }, * "fields": { * "姓名": "草料", * "手機": "18888648888", * "微信名": "CHEN", * "身份證號": "330200000000000000", * "工號": "FBI100", * "單選項": "是" * } * } * } * } * ] * } */ public static JSONObject buildPushEventOutput(Object params) { JSONObject output = new JSONObject(); if (!(params instanceof Map)) { log.error("當前腳本入?yún)㈩愋湾e誤!期望是 Map,但是實際為{},具體值為{}", params.getClass().getName(), JSON.toJSONString(params)); return output; } JSONObject input = (JSONObject) params; /** * 這里的事件內(nèi)容的數(shù)據(jù)類型,有可能是數(shù)組,也可能是對象,具體按照推送方格式為準,作匹配的處理: * 1.解密(不是所有的消息都需要做) * 2.獲取事件的標識 * 3.將事件標識轉(zhuǎn)換為觸發(fā)器的 key * 4.構(gòu)造接口返回,務必與推送方要求保持一致 */ List<JSONObject> eventContents = Lists.newArrayList(); JSONObject data = (JSONObject) input.get(BODY); JSONObject item = new JSONObject(); //2. 獲取對應事件的 key。 String event = (String) data.get("event"); //3. 做觸發(fā)器的 key 與事件的 key 映射 if ("FORM_DATA_SUBMIT".equals(event)) { item.put(EVENT_TYPE, "FORM_DATA_SUBMIT"); } else if ("FORM_DATA_EDITED".equals(event)) { item.put(EVENT_TYPE, "FORM_DATA_EDITED"); } else if ("FORM_DATA_REVIEW".equals(event)) { item.put(EVENT_TYPE, "FORM_DATA_REVIEW"); } //4. 對應事件的輸出內(nèi)容,與觸發(fā)器的輸出字段保持一致 item.put(EVENT_CONTENT, JSON.parseObject(data.getString("data"))); eventContents.add(item); output.put(EVENT_CONTENTS, eventContents); //推送事件后的響應結(jié)果,必須和推送方要求的返回結(jié)果一致 Map<String, Object> result = new HashMap<>(16); result.put("code", 0); result.put("message", "success"); output.put(RESULT, result); return output; } } ```
上一篇
連接器工具
下一篇
控件類型配置
手機掃碼
復制鏈接
手機掃一掃轉(zhuǎn)發(fā)分享
復制鏈接
Markdown文件
分享
鏈接
類型
密碼
更新密碼
主站蜘蛛池模板:
久草综合在线视频
|
99久久综合狠狠综合久久一区
|
看真人视频一一级毛片
|
国产高清视频在线播放www色
|
激情网婷婷
|
国产在线播放你懂的
|
四虎最新网
|
久久青青草原精品国产麻豆
|
九九热视频免费在线观看
|
久久精品视频网站
|
魔镜号亚洲一区二区三区在线
|
久久99视频免费
|
钢铁魔女一至四集
|
日韩中文字幕亚洲无线码
|
久久精品国产亚洲麻豆
|
高清成人综合
|
国产精品成人一区二区不卡
|
免费福利在线观看
|
欧美性猛交99久久久久99
|
六月婷婷综合网
|
色女人网站
|
97久久精品一区二区三区
|
九九精品在线视频
|
色视频免费网站
|
v影院最新在线v视频
|
99久久国内精品成人免费
|
国产亚洲精品美女
|
欧美午夜艳片欧美精品
|
国内精品久久久久影院亚洲
|
嫩草影视在线观看
|
国产精品久久久久久久久久98
|
免费看电影的视频
|
91久久婷婷国产综合精品青草
|
你懂的免费在线视频
|
午夜丁香婷婷
|
懂得影视大全
|
欧美日韩亚洲国产一区二区三区
|
五月开心综合
|
婷婷丁香五月中文字幕
|
日本欧美在线视频
|
国产精品美女挤奶视频
|