diff --git a/src/langbot/libs/dingtalk_api/api.py b/src/langbot/libs/dingtalk_api/api.py index c0a7492ad..6ead2027d 100644 --- a/src/langbot/libs/dingtalk_api/api.py +++ b/src/langbot/libs/dingtalk_api/api.py @@ -697,9 +697,10 @@ class DingTalkClient: if not await self.check_access_token(): await self.get_access_token() - cardData: dict = {'cardParamMap': _stringify_card_param_map(card_param_map)} + template_params = dict(card_param_map or {}) if card_data_config is not None: - cardData['config'] = json.dumps(card_data_config) + template_params['config'] = card_data_config + cardData: dict = {'cardParamMap': _stringify_card_param_map(template_params)} body: dict = { 'cardTemplateId': card_template_id, diff --git a/tests/unit_tests/platform/test_dingtalk_api.py b/tests/unit_tests/platform/test_dingtalk_api.py index 03c84e97b..450128f3c 100644 --- a/tests/unit_tests/platform/test_dingtalk_api.py +++ b/tests/unit_tests/platform/test_dingtalk_api.py @@ -1,8 +1,11 @@ """Tests for DingTalk API payload helpers.""" import json +from contextlib import asynccontextmanager +from unittest.mock import AsyncMock -from langbot.libs.dingtalk_api.api import _stringify_card_param_map +from langbot.libs.dingtalk_api.api import DingTalkClient, _stringify_card_param_map +from langbot.pkg.utils import httpclient def test_dingtalk_card_param_map_stringifies_select_component_arrays(): @@ -40,3 +43,41 @@ def test_dingtalk_card_param_map_stringifies_unregistered_structures(): assert params['other'] == '["A"]' assert params['empty'] == '' + + +async def test_create_card_embeds_layout_config_as_template_parameter(monkeypatch): + response = type('Response', (), {'status_code': 200})() + post = AsyncMock(return_value=response) + + @asynccontextmanager + async def client_context(): + yield type('HttpClient', (), {'post': post})() + + client = object.__new__(DingTalkClient) + client.access_token = 'access-token' + client.robot_code = 'robot-code' + client.key = 'client-id' + client.logger = None + client.check_access_token = AsyncMock(return_value=True) + client._http_client_context = client_context + monkeypatch.setattr(httpclient, 'response_text', AsyncMock(return_value='{}')) + + original_params = {'content': 'hello'} + delivered = await client.create_and_deliver_card( + card_template_id='template-id', + out_track_id='track-id', + open_space_id='dtv1.card//IM_ROBOT.user-id', + is_group=False, + card_param_map=original_params, + card_data_config={'autoLayout': True}, + ) + + request_body = post.await_args.kwargs['json'] + assert delivered is True + assert request_body['cardData'] == { + 'cardParamMap': { + 'content': 'hello', + 'config': '{"autoLayout": true}', + } + } + assert original_params == {'content': 'hello'}