#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ DingTalk webhook callback endpoint. PUBLIC endpoint (any permission) - DingTalk servers call this when approval status changes. Expected POST body: { "processInstanceId": "xxx", "processCode": "xxx", "type": "bpms_instance_change", "result": "agree" / "refuse", "staffId": "xxx", "remark": "optional comment" } """ result = {'success': False, 'message': 'Invalid callback'} try: # DingTalk callback data comes via params_kw (POST body auto-parsed) callback_data = {} # params_kw contains the parsed POST body fields process_instance_id = params_kw.get('processInstanceId', '') callback_type = params_kw.get('type', '') callback_result = params_kw.get('result', '') staff_id = params_kw.get('staffId', '') process_code = params_kw.get('processCode', '') remark = params_kw.get('remark', '') # Also handle nested JSON body case where entire body is under a key if not process_instance_id: body = params_kw.get('body', None) if isinstance(body, dict): process_instance_id = body.get('processInstanceId', '') callback_type = body.get('type', '') callback_result = body.get('result', '') staff_id = body.get('staffId', '') process_code = body.get('processCode', '') remark = body.get('remark', '') callback_data = { 'processInstanceId': process_instance_id, 'type': callback_type, 'result': callback_result, 'staffId': staff_id, 'processCode': process_code, 'remark': remark, } if not process_instance_id: result = {'success': False, 'message': 'Missing processInstanceId'} else: # Call the handle_dingtalk_callback function registered via load_dingdingflow() callback_result_data = await handle_dingtalk_callback(callback_data) result = callback_result_data except Exception as e: result = {'success': False, 'message': f'Callback processing error: {str(e)}'} return json.dumps(result, ensure_ascii=False, default=str)