钉钉机器人发送互动卡片 - 开发指南
一、引言
在现代企业数字化办公场景中,钉钉作为一款广泛使用的办公平台,其丰富的开放能力为企业定制化办公流程提供了强大支持。其中,钉钉机器人发送互动卡片功能能够极大地提升信息传递的交互性与便捷性。通过互动卡片,用户可以在钉钉客户端内直接进行交互操作,如点击按钮、填写表单等,无需跳转到其他复杂页面,有效缩短操作路径,提高工作效率。无论是用于任务提醒、审批通知,还是信息收集等场景,互动卡片都展现出独特的优势。本文将详细介绍如何开发实现钉钉机器人发送互动卡片的功能。
二、准备工作
(一)创建钉钉应用
- 登录开发者后台:访问钉钉开放平台(https://open.dingtalk.com/),使用企业管理员账号登录。
- 创建应用:在应用开发板块,根据实际需求选择创建企业内部应用或第三方企业应用。如果是企业内部自用的机器人,选择企业内部开发;若应用需要提供给其他企业使用,则选择第三方企业应用。填写应用的基本信息,包括应用名称、描述等。例如,创建一个名为“企业通知助手”的企业内部应用,应用描述为“用于发送各类企业通知及互动卡片消息”。
- 获取AppKey和AppSecret:创建完成后,进入应用的基础信息页面,获取AppKey和AppSecret,这两个关键信息在后续获取accessToken以及接口调用鉴权中会用到。
(二)申请接口权限
- 进入权限管理:在应用管理界面,点击“权限管理”。
- 搜索并申请权限:搜索“机器人”,找到与机器人发送消息、互动卡片相关的接口权限,如“机器人发送互动卡片”“注册卡片交互回调地址”等权限,并提交申请。对于企业内部应用,部分权限申请后无需审批,默认开通;第三方企业应用可能需要经过钉钉官方的审核流程。
(三)搭建互动卡片模板
- 登录互动卡片搭建平台:访问钉钉互动卡片搭建平台,可从钉钉开放平台相关入口进入。
- 新建模板:点击“新建模板”按钮,输入模板名称,选择卡片类型(如通用卡片、表单卡片等)。
- 设计卡片内容:利用平台提供的组件库,添加文本、按钮、图片、表单等组件,设计卡片的布局和样式。例如,创建一个任务提醒的互动卡片,卡片上包含任务标题、截止时间、任务描述,以及“确认完成”和“延期处理”两个按钮。
- 设置数据源与交互逻辑(可选):如果卡片需要动态展示数据,可设置数据源,绑定相关数据字段。对于按钮等交互组件,设置对应的回调URL或操作逻辑。比如,“确认完成”按钮点击后,回调到指定的服务器接口,用于更新任务状态。
- 发布模板:完成设计与设置后,点击“发布”按钮,发布互动卡片模板。发布后,记录下卡片模板的唯一标识cardTemplateId,后续发送互动卡片时会用到。
三、开发实现
(一)获取accessToken
在调用钉钉机器人发送互动卡片接口之前,需要先获取accessToken,用于接口调用的身份验证。accessToken的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的accessToken。开发者需要自行缓存accessToken,用于后续接口的调用。
- 企业内部应用获取accessToken
- Java示例: ```java import com.aliyun.dingtalkoauth2_1_0.Client; import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest; import com.aliyun.teaopenapi.models.Config; import com.aliyun.teautil.Common;
public class AccessTokenUtil { public static String getAccessToken(String appKey, String appSecret) throws Exception { Config config = new Config(); config.protocol = "https"; config.regionId = "central"; Client client = new Client(config); GetAccessTokenRequest request = new GetAccessTokenRequest(); request.setAppKey(appKey); request.setAppSecret(appSecret); return client.getAccessToken(request).getBody().getAccessToken(); } }
- **Python示例**:
```python
from alibabacloud_dingtalk.oauth2_1_0.client import Client as dingtalkoauth2_1_0Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_tea_util import models as util_models
def get_access_token(app_key, app_secret):
config = open_api_models.Config()
config.protocol = "https"
config.region_id = "central"
client = dingtalkoauth2_1_0Client(config)
get_access_token_request = dingtalkoauth2_1_0Client.GetAccessTokenRequest()
get_access_token_request.app_key = app_key
get_access_token_request.app_secret = app_secret
response = client.get_access_token(get_access_token_request)
return response.body.access_token
- 第三方企业应用获取accessToken:第三方企业应用获取accessToken的方式与企业内部应用类似,但需要在授权流程等方面遵循第三方应用的规范。具体可参考钉钉开放平台关于第三方应用授权企业获取accessToken的相关文档。例如,需要在用户授权后,通过授权码等信息来获取accessToken。
(二)发送互动卡片
- 接口调用参数说明
- cardTemplateId:互动卡片模板的ID,在搭建并发布卡片模板后获取。
- openConversationId:会话ID,如果是单聊发送互动卡片,可通过批量安装酷应用到单聊会话或监听单聊酷应用事件获取该参数值;如果是群聊发送,对应群聊的ID。
- robotCode:机器人的唯一标识,在创建机器人应用时生成。
- cardData:卡片数据,可包含自定义的参数、变量等,用于动态填充卡片内容。例如,{"taskTitle":"文档撰写任务","dueTime":"2024-12-31"}。
- outTrackId:由开发者自己生成并作为入参传递给钉钉的唯一标识,钉钉会在对应使用到outTrackId的场景,帮助开发者对TrackId进行记录,可用于跟踪卡片的交互状态等。
- receiverUserIdList:消息仅部分人可见的接收人列表,如果为空则表示发送给所有人。可以是userId模式(填写用户userId)或unionId模式(填写用户unionId)。
- callbackUrl:可控制卡片回调的URL,当用户在卡片上进行交互操作(如点击按钮)时,钉钉会将相关信息发送到该URL,开发者在该URL对应的服务器接口中进行业务逻辑处理。如果不填则无需回调。
- isPurePullMode:是否开启卡片纯拉模式,true表示开启。企业内部应用和第三方企业应用都有对应的纯拉模式接入流程。开启纯拉模式后,卡片内容的更新逻辑会有所不同。
- 发送互动卡片代码示例
- Java示例: ```java import com.aliyun.dingtalkim_1_0.Client; import com.aliyun.dingtalkim_1_0.models.SendInteractiveCardHeaders; import com.aliyun.dingtalkim_1_0.models.SendInteractiveCardRequest; import com.aliyun.dingtalkim_1_0.models.SendInteractiveCardRequest.CardOptions; import com.aliyun.dingtalkim_1_0.models.SendInteractiveCardRequest.CardData; import com.aliyun.teaopenapi.models.Config; import com.aliyun.teautil.Common;
public class SendInteractiveCardSample { public static void main(String[] args) throws Exception { String accessToken = "your_access_token"; String cardTemplateId = "your_card_template_id"; String openConversationId = "your_open_conversation_id"; String robotCode = "your_robot_code";
Config config = new Config();
config.protocol = "https";
config.regionId = "central";
Client client = new Client(config);
SendInteractiveCardHeaders headers = new SendInteractiveCardHeaders();
headers.setXAcsDingtalkAccessToken(accessToken);
CardData cardData = new CardData();
cardData.setCardParamMap(Common.toMap("taskTitle", "会议安排", "dueTime", "2024-10-15"));
CardOptions cardOptions = new CardOptions();
cardOptions.setCardData(cardData);
SendInteractiveCardRequest request = new SendInteractiveCardRequest();
request.setCardTemplateId(cardTemplateId);
request.setOpenConversationId(openConversationId);
request.setRobotCode(robotCode);
request.setCardOptions(cardOptions);
client.sendInteractiveCardWithOptions(request, headers, new com.aliyun.teautil.models.RuntimeOptions());
}
}
- **Python示例**:
```python
from alibabacloud_dingtalk.im_1_0.client import Client as dingtalkim_1_0Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_tea_util import models as util_models
def send_interactive_card(access_token, card_template_id, open_conversation_id, robot_code):
config = open_api_models.Config()
config.protocol = "https"
config.region_id = "central"
client = dingtalkim_1_0Client(config)
send_interactive_card_headers = dingtalkim_1_0Client.SendInteractiveCardHeaders()
send_interactive_card_headers.xAcsDingtalkAccessToken = access_token
card_data = dingtalkim_1_0Client.SendInteractiveCardRequestCardData()
card_data.cardParamMap = {"taskTitle": "项目进度汇报", "dueTime": "2024-10-20"}
card_options = dingtalkim_1_0Client.SendInteractiveCardRequestCardOptions()
card_options.cardData = card_data
send_interactive_card_request = dingtalkim_1_0Client.SendInteractiveCardRequest()
send_interactive_card_request.cardTemplateId = card_template_id
send_interactive_card_request.openConversationId = open_conversation_id
send_interactive_card_request.robotCode = robot_code
send_interactive_card_request.cardOptions = card_options
client.sendInteractiveCardWithOptions(send_interactive_card_request, send_interactive_card_headers, util_models.RuntimeOptions())
(三)处理卡片回调
当用户在互动卡片上进行操作(如点击按钮)时,钉钉会向预先设置的callbackUrl发送POST请求,请求体中包含卡片的相关信息,如outTrackId、用户操作的按钮参数等。开发者需要在服务器端实现该回调接口,对请求进行处理,并根据业务逻辑决定是否更新卡片内容等操作。
- 解析回调请求参数:在服务器端接收到回调请求后,首先需要解析请求体中的参数。以Java的Spring Boot框架为例: ```java import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class CardCallbackController {
@PostMapping("/cardCallback")
public String handleCardCallback(@RequestBody Map
2. **更新卡片内容(可选)**:如果用户的操作需要更新卡片内容,如按钮点击后改变按钮状态、更新卡片显示的数据等,可调用钉钉的更新机器人发送互动卡片接口。更新接口的调用方式与发送接口类似,需要传入outTrackId以及更新后的cardData等参数。
```java
import com.aliyun.dingtalkim_1_0.Client;
import com.aliyun.dingtalkim_1_0.models.UpdateRobotInteractiveCardHeaders;
import com.aliyun.dingtalkim_1_0.models.UpdateRobotInteractiveCardRequest;
import com.aliyun.dingtalkim_1_0.models.UpdateRobotInteractiveCardRequest.CardOptions;
import com.aliyun.dingtalkim_1_0.models.UpdateRobotInteractiveCardRequest.CardData;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.Common;
public class UpdateInteractiveCardSample {
public static void main(String[] args) throws Exception {
String accessToken = "your_access_token";
String outTrackId = "your_out_track_id";
Config config = new Config();
config.protocol = "https";
config.regionId = "central";
Client client = new Client(config);
UpdateRobotInteractiveCardHeaders headers = new UpdateRobotInteractiveCardHeaders();
headers.setXAcsDingtalkAccessToken(accessToken);
CardData cardData = new CardData();
cardData.setCardParamMap(Common.toMap("taskStatus", "已完成"));
CardOptions cardOptions = new CardOptions();
cardOptions.setCardData(cardData);
UpdateRobotInteractiveCardRequest request = new UpdateRobotInteractiveCardRequest();
request.setOutTrackId(outTrackId);
request.setCardOptions(cardOptions);
client.updateRobotInteractiveCardWithOptions(request, headers, new com.aliyun.teautil.models.RuntimeOptions());
}
}
四、常见问题与解决方法
- 接口调用失败:检查accessToken是否有效,是否在有效期内。如果accessToken过期,重新获取并更新缓存。同时,检查接口调用的参数是否正确,如cardTemplateId、openConversationId等是否填写正确。查看钉钉开放平台的接口文档,确认接口调用的频率限制,避免因频繁调用导致接口被拦截。
- 卡片回调未触发:确认callbackUrl是否为公网可访问的地址,并且在配置时没有拼写错误。检查服务器端的网络配置,确保能够正常接收来自钉钉的回调请求。可以通过在服务器端打印请求日志,查看是否有来自钉钉的请求到达。
- 卡片样式与预期不符:在搭建卡片模板时,仔细检查各个组件的设置和布局。注意组件的属性设置,如文本的字体、颜色,按钮的样式等。如果卡片需要动态展示数据,检查数据源的绑定是否正确,数据格式是否符合预期。
五、总结
通过以上步骤,我们详细介绍了如何开发实现钉钉机器人发送互动卡片的功能,包括从创建应用、申请权限、搭建卡片模板,到获取accessToken、发送互动卡片以及处理卡片回调等完整流程。互动卡片为企业办公带来了更丰富、高效的交互体验,开发者可以根据企业的实际业务需求,灵活定制互动卡片的样式和功能,实现更便捷的信息传递与用户交互。在开发过程中,要注意遵循钉钉开放平台的规范和接口要求,及时处理可能遇到的问题,确保功能的稳定运行。