c# 釘釘應用實現監聽審批事件以及獲取審批結果的流程

oa的操作已經測試了一遍

image.png

如果是自建oa則代表發起的審批是跳轉網頁,否則釘釘打開后是一個表單界面,不需要調整自己搞得oa。

所以我感覺目前公司的需求更適合官方oa 表單來填寫,更靈活,還支持用戶配置。

但是用戶點了審批,這個表單的結果怎么監聽呢?
自建了應用之后
填寫了一個網址測試,發現有跡可循。
其實際上的發起的請求一目兩然。

驗簽的c#版本倒是提供了
他推薦流模式,但是只給了java,和go,我喜歡偷懶,那就直接http實現吧
java版本:

import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;@RestController
public class CallbackController {@PostMapping("{你注冊的HTTP地址的urlpath}")public Map<String, String> callBack(@RequestParam(value = "msg_signature", required = false) String msg_signature,@RequestParam(value = "timestamp", required = false) String timeStamp,@RequestParam(value = "nonce", required = false) String nonce,@RequestBody(required = false) JSONObject json) {} 
}
image.png

c#沒有提供案例
但是也可以根據上面的報錯紅色信息 舉一反三,不懂的朋友直接復制curl到apifox里面玩吧。

//https://github.com/open-dingtalk/DingTalk-Callback-Crypto/blob/main/DingTalkEncryptor.cs[HttpPost("callback/{urlpath}")]public string CallBack([FromQuery(Name = "msg_signature")] string? msgSignature,[FromQuery(Name = "timestamp")] string? timestamp,[FromQuery(Name = "nonce")] string? nonce,[FromBody] JObject? json // 以 JObject 接收 JSON 請求體){// 示例:從 JSON 中手動取字段string? encrypt = json?["encrypt"]?.ToString();Console.WriteLine($"接收到 encrypt = {encrypt}");// 構造返回的 JObjectJObject result = new JObject {["status"] = "ok",["msg"] = "callback received",};return result.ToString(); // 返回 JSON}

DingTalk-Callback-Crypto/DingTalkEncryptor.cs at main · open-dingtalk/DingTalk-Callback-Crypto

image.png

然后我開啟斷點調試http://nat.xx.xx.top:1111/callback/ding
點擊保存,這邊立馬傳過來參數了,nice

image.png

驗證沒問題那么保存會成功,保存失敗每次需要重新配置。

image.png

這是我接口直接復制curl里面的東西測試結果

image.png

下面是我自建公網轉發端口映射的技術棧 實現抓取到阿里那邊發起的請求

image.png

解密抓到的事件

//https://github.com/open-dingtalk/DingTalk-Callback-Crypto/blob/main/DingTalkEncryptor.cs[HttpPost("callback/{urlpath}")]public string CallBack([FromQuery(Name = "msg_signature")] string? msgSignature,[FromQuery(Name = "timestamp")] string? timestamp,[FromQuery(Name = "nonce")] string? nonce,[FromBody] JObject? json // 以 JObject 接收 JSON 請求體){// 示例:從 JSON 中手動取字段string? encrypt = json?["encrypt"]?.ToString();//    DingTalkEncryptor dingTalkEncryptor=new DingTalkEncryptor(msgSignature, timestamp, nonce);string aesKey = "jfMpfdLWzGyZAhGc3sljt9rUsEvfiuWEDmDNCcYjoUX";string signKey = "TJKIRtrgH9a6vo72W0JZjp4iU541VJpHANjzX";DingTalkEncryptor callbackCrypto = new DingTalkEncryptor(token: signKey, encodingAesKey: aesKey,corpId:"dinggfmqeejcxfh76eja");String decryptMsg = callbackCrypto.getDecryptMsg(msgSignature, timestamp, nonce, encrypt);Debug.WriteLine("decryptMsg:"+ decryptMsg);// 3. 反序列化回調事件json數據JObject eventJson = JObject.Parse(decryptMsg);String eventType = eventJson["EventType"].ToString(); //bpms_instance_change// 4. 根據EventType分類處理if ("check_url" == eventType) {// 測試回調url的正確性Debug.WriteLine("測試回調url的正確性");}else if ("user_add_org" == eventType) {// 處理通訊錄用戶增加事件Debug.WriteLine("發生了:" + eventType + "事件");}else {// 添加其他已注冊的Debug.WriteLine("發生了:" + eventType + "事件");}// 5. 返回success的加密數據Dictionary<string, string> successMap = callbackCrypto.getEncryptedMap("success");Console.WriteLine($"接收到 encrypt = {encrypt}");return JObject.FromObject(successMap).ToString();}

然后 如果審批 被同意或者被拒絕則bpms_instance_change中的type等于finish
下面這個:
這是發起實例后,修改了審批人,這個時候type還是等于start,然后 我點了拒絕后的信息

decryptMsg:{"EventType":"check_url"}
測試回調url的正確性
decryptMsg:{"EventType":"check_url"}
測試回調url的正確性
decryptMsg:{"EventType":"check_url"}
測試回調url的正確性
線程 0x5754 已退出,返回值為 0 (0x0)。
decryptMsg:{"processInstanceId":"a3Dk0aPSRjioHwXjwvftZA03241752197014","eventId":"475679dc49894ab0866e21d49cb2fad3","corpId":"ding5769db03cf6cefd4a1320dcb25e91351","resource":"/v1.0/event/bpms_instance_change/processCode/PROC-DD3B3D23-ECA2-492F-847E-20DEB0C0AFB3/type/start","EventType":"bpms_instance_change","businessId":"202507110923000340503","title":"情遷提交的A測試","type":"start","url":"https://aflow.dingtalk.com/dingtalk/mobile/homepage.htm?corpid=ding5769db03cf6cefd4a1320dcb25e91351&dd_share=false&showmenu=false&dd_progress=false&back=native&procInstId=a3Dk0aPSRjioHwXjwvftZA03241752197014&taskId=&swfrom=isv&dinghash=approval&dtaction=os&dd_from=corp#approval","createTime":1752197015000,"processCode":"PROC-DD3B3D23-ECA2-492F-847E-20DEB0C0AFB3","bizCategoryId":"","staffId":"0716043442804764"}
發生了:bpms_instance_change事件decryptMsg:{"processInstanceId":"a3Dk0aPSRjioHwXjwvftZA03241752197014","eventId":"26d224da367e4a12872eca6f42bf82d0","finishTime":1752197095000,"corpId":"ding5769db03cf6cefd4a1320dcb25e91351","resource":"/v1.0/event/bpms_instance_change/processCode/PROC-DD3B3D23-ECA2-492F-847E-20DEB0C0AFB3/type/finish","EventType":"bpms_instance_change","businessId":"202507110923000340503","title":"情遷提交的A測試","type":"finish","url":"https://aflow.dingtalk.com/dingtalk/mobile/homepage.htm?corpid=ding5769db03cf6cefd4a1320dcb25e91351&dd_share=false&showmenu=false&dd_progress=false&back=native&procInstId=a3Dk0aPSRjioHwXjwvftZA03241752197014&taskId=&swfrom=isv&dinghash=approval&dtaction=os&dd_from=corp#approval","result":"refuse","createTime":1752197015000,"processCode":"PROC-DD3B3D23-ECA2-492F-847E-20DEB0C0AFB3","bizCategoryId":"","staffId":"0716043442804764"}
發生了:bpms_instance_change事件

雖然知道了結果但是不知道填寫的具體信息包括拒絕的理由
就需要這個接口了。

curl --location --request POST 'http://api.dingtalk.com/v1.0/workflow/processInstances?processInstanceId=a3Dk0aPSRjioHwXjwvftZA03241752197014' \
--header 'x-acs-dingtalk-access-token: 5f4bab5f471635cea6bb4b3exxxxxxx' \
--header 'AppTime: 1724827203420' \
--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \
--header 'Content-Type: application/json' \
--data-raw '{"originatorUserId" : "0716043442804764","processCode":"PROC-A13F14D1-B48E-4111-AC4F-36DF88BE5110"}'

我這邊返回的結果:

{"result": {"finishTime": "2025-07-11T09:24Z","attachedProcessInstanceIds": [],"businessId": "202507110923000340503","title": "情遷提交的A測試","originatorDeptId": "-1","operationRecords": [{"date": "2025-07-11T09:23Z","result": "NONE","images": [],"showName": "提交申請","type": "START_PROCESS_INSTANCE","userId": "0716043442804764"},{"date": "2025-07-11T09:24Z","result": "REFUSE","activityId": "sid-1234_5678","images": [],"showName": "審批人","remark": "。。。。我拒絕了你","type": "EXECUTE_TASK_NORMAL","userId": "0716043442804764"}],"formComponentValues": [{"componentType": "TextField","name": "用戶名","bizAlias": "TextField-bizAlias","id": "TextField-abcd","value": "單行輸入框示例"}],"result": "refuse","bizAction": "NONE","createTime": "2025-07-11T09:23Z","originatorUserId": "0716043442804764","tasks": [{"result": "REFUSE","activityId": "sid-1234_5678","finishTime": "2025-07-11T09:24Z","pcUrl": "aflow.dingtalk.com?procInsId=a3Dk0aPSRjioHwXjwvftZA03241752197014&taskId=94836079594&businessId=202507110923000340503","createTime": "2025-07-11T09:24Z","mobileUrl": "aflow.dingtalk.com?procInsId=a3Dk0aPSRjioHwXjwvftZA03241752197014&taskId=94836079594&businessId=202507110923000340503","userId": "0716043442804764","taskId": 94836079594,"status": "COMPLETED"}],"originatorDeptName": "測試推送","status": "COMPLETED"},"success": true
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/88918.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/88918.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/88918.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Typecho架構深度剖析:輕量級博客系統的設計哲學與實現原理

文章目錄 深度解析Typecho:輕量級博客系統的架構設計與實現1. Typecho概述與技術背景1.1 發展歷程1.2 核心特性2. 系統架構設計分析2.1 核心架構圖2.2 核心組件3. 核心模塊實現分析3.1 路由系統實現3.2 數據庫抽象層4. 插件系統深度解析4.1 Hook機制實現4.2 插件開發示例5. 性…

LangChain 內存(Memory)

1. 為什么需要內存&#xff1f; 大型語言模型&#xff08;LLM&#xff09;本身是無狀態的。這意味著每次你向 LLM 發送一個請求&#xff08;Prompt&#xff09;&#xff0c;它都會獨立處理這個請求&#xff0c;完全不記得之前任何的交互。這在構建一次性問答應用時沒問題&#…

基于定制開發開源AI智能名片S2B2C商城小程序的社群游戲定制策略研究

摘要&#xff1a;本文聚焦社群游戲定制領域&#xff0c;深入探討以社群文化和用戶偏好為導向的定制策略。通過分析互動游戲活動、社群文化塑造等關鍵要素&#xff0c;結合定制開發開源AI智能名片S2B2C商城小程序的技術特性&#xff0c;提出針對性游戲定制方案。研究旨在提升社群…

自動駕駛決策與規劃

目錄 自動駕駛決策與規劃概述 決策與規劃體系結構 分層遞階式決策規劃 反應式體系結構 混合式體系結構 決策與規劃系統的關鍵環節 路徑規劃 軌跡規劃 行為決策 異常處理 自動駕駛的路徑規劃技術 維諾圖法 柵格法 Dijkstra算法 A*算法 自動駕駛的行為決策方法 …

C++編譯期計算:常量表達式(constexpr)全解析

在C性能優化領域&#xff0c;"將計算盡可能轉移到編譯期"是一條黃金法則。編譯期計算&#xff08;Compile-Time Computation&#xff09;能顯著減少程序運行時的開銷&#xff0c;提升執行效率&#xff0c;同時還能在編譯階段暴露潛在錯誤。C11引入的constexpr關鍵字及…

【micro:bit】從入門到放棄(一):在線、離線版本的使用

1、離線版 micro:bit 1)下載地址 https://makecode.microbit.org/offline-app 2)雙擊安裝包,makecode-microbit-setup-win64.exe,自動安裝,安裝成功后圖標如下圖所示 3)運行程序,查看版本信息 4)主界面如下 5)編程界面 點擊“新建項目”或者“導入”進入編程界…

Flink Forward Asia 2025 主旨演講精彩回顧

作為 Apache Flink 社區備受矚目的年度盛會之一&#xff0c;由阿里云承辦的 Flink Forward Asia 2025 于 7 月 3 日在新加坡正式拉開帷幕。From Real-Time Data Analytics to Real-Time AI&#xff0c;Flink 生態全面擁抱 AI本次大會上&#xff0c;Apache Flink 中文社區發起人…

車道偏離預警(LDW)功能介紹

車道偏離預警&#xff08;LDW&#xff09;功能介紹 LDW功能 通過攝像頭監測前方車道線&#xff0c;當車輛偏離車道線時&#xff0c;系統發出報警提醒。 系統框圖報警條件 最早報警線最遲報警線報警臨界線 設置在 最早/最遲報警線 之間接口定義 輸入/輸出系統算法 橫向偏離速度模…

軟考(軟件設計師)計算機網絡-網絡層

obsidian做markdown筆記太爽了&#xff0c;康奈爾模板筆記看起來舒服&#xff0c;CSDN試了幾種方式&#xff0c;不支持&#xff0c;只能貼圖了&#xff0c;將就看吧&#x1f60f;&#xff08;狗頭保命&#xff09;工作原理圖解 #mermaid-svg-e5Tgpt26jUftujKn {font-family:&qu…

nginx反向代理實現跨域請求

記錄一個項目中遇到的跨域請求問題&#xff0c;解決跨域問題無非幾種辦法&#xff1a;1、后端解決&#xff0c;推薦的做法&#xff0c;可以看我之前寫的文章&#xff0c;fastadmin的后臺配置跨域&#xff1b;2、前端配置proxy代理&#xff08;開發環境用&#xff09;&#xff1…

利用Wisdom SSH高效搭建CI/CD工作流

在軟件開發流程中&#xff0c;CI/CD工作流對于提升效率與確保質量起著關鍵作用。Wisdom SSH作為一款強大工具&#xff0c;其官網為ssh.wisdomheart.cn&#xff0c;借助AI助手能大幅簡化CI/CD工作流的搭建過程。假設服務器已完成基礎配置&#xff0c;下面為您介紹如何利用Wisdom…

深度學習-循環神經網絡RNN

文章目錄序列模型循環神經網絡案例詞的表示輸出的表示矩陣運算表示交叉熵損失時間反向傳播算法BPTT梯度消失與梯度爆炸GRULSTM總結序列模型 循環神經網絡 st是上一個隱層的輸出&#xff0c;體現序列數據之間有很強的關聯性。 案例 > S0是初始輸入&#xff0c;一般是0&#…

【Linux網絡編程】Socket - TCP

目錄 V1版本 - Echo Server 初始化服務器 啟動服務器 客戶端 一些BUG與問題 解決服務器無法一次處理多個請求的問題 多進程版本 多線程版本 線程池版本 V2版本 - 多線程遠程執行命令 V1版本 - Echo Server 初始化服務器 TCP大部分內容與UDP是相同的&#xff0c;我們…

知識圖譜構建簡單分享

最近系統性地學習了知識圖譜構建的關鍵技術&#xff0c;并結合醫療領域知識&#xff0c;完成了一個醫療知識圖譜項目的實踐。以下是整理的項目架構&#xff0c;歡迎交流指正。說明&#xff1a;當前項目實際實現主要應用了數據預處理、模型設計與預訓練、模型優化與測試等核心技…

MCU中的系統控制器(System Controller)是什么?

MCU中的系統控制器&#xff08;System Controller&#xff09;是什么&#xff1f; 在微控制器&#xff08;MCU&#xff09;中&#xff0c;系統控制器&#xff08;System Controller&#xff09;是一個關鍵模塊&#xff0c;負責管理和協調MCU內部的核心功能&#xff0c;確保系統…

【Datawhale夏令營】用AI做帶貨視頻評論分析

文本分類、文本聚類 基礎庫&#xff1a; pandas, sklearn功能&#xff1a; 商品識別、情感分析、評論聚類商品識別&#xff1a; 視頻文本信息&#xff0c;預測推廣商品名稱 & 情感分析&#xff1a;四個維度&#xff08;情感傾向、用戶場景、用戶疑問、用戶建議&#xff09…

[Meetily后端框架] AI摘要結構化 | `SummaryResponse`模型 | Pydantic庫 | vs marshmallow庫

第3章&#xff1a;摘要數據結構&#xff08;Pydantic庫&#xff09; 歡迎回來&#xff01; 在之前的第2章&#xff1a;API文檔中&#xff0c;我們知道API網關提供了端點 而API文檔準確告訴我們如何與這些端點通信&#xff0c;包括需要發送的數據格式和期望接收的數據格式。 …

深度學習 tensor及其相關操作

目錄 Tensor 概念 數據類型 創建tensor 基本創建方式 1、 torch.tensor() 2、torch.Tensor() 3、torch.IntTensor() 等 創建線性張量和隨機張量 1、創建線性張量 2、創建隨機張量 切換設備 類型轉換 與 Numpy 數據轉換 1、張量轉 Numpy 2、Numpy 轉張量 tenso…

如何將FPGA設計的驗證效率提升1000倍以上(4)

本文為系列文章的完結篇。用戶應用設計中的信號&#xff0c;在經歷編譯器的多次迭代優化之后&#xff0c;在FPGA芯片內部運行時&#xff0c;可能已經被重新命名、“改頭換面”或“機里機氣”。要想以人工經驗進行追蹤&#xff0c;構建目標寄存器信號與RTL設計源碼之間的映射關系…

Linux驅動11 --- buildroot雜項驅動開發方法

目錄 一、Buildroot 1.1介紹 文件系統 1.一個完整的操作系統需要包含大量的文件 2.在嵌入式開發中目前應用最廣泛的文件系統制作工具就是 buildroot&#xff0c;busybox 3.buildroot 制作文件系統&#xff08;了解&#xff09; 二、雜項驅動編程 1.1 驅動編程做的內容 2.2…