Send messages with a bot
Message types
You can send bot messages in two ways: by calling an API or by using a Webhook. The supported message types and data formats vary by method.We recommend that you send messages by calling an API.
| Message type | Send via API | Send via Webhook |
|---|---|---|
| Text | ✅ | ✅ |
| Markdown | ✅ | ✅ |
| Image | ✅ | ❌ |
| ActionCard | ✅ | ✅ |
| FeedCard | ❌ | ✅ |
| Link | ✅ | ✅ |
| Audio | ✅ | ❌ |
| File | ✅ | ❌ |
| Video | ✅ | ❌ |
Method 1: Call an API
Important
- Bot messages in one-on-one chats between a user and the bot: support sending and receiving images, voice messages, and files.
- Bot messages in group chats: the bot can send images, voice messages, videos, and files. However, users cannot @ the bot to send voice messages, videos, or files to it in a group chat.
Available APIs
Data format
- Message template key: a unique identifier used when developers send messages. It allows the code to quickly reference a predefined message template.
-
Message template parameters: the actual data used to replace predefined placeholders in the message template. For example, when the message template key is
sampleText, you need to set the value of thecontentfield. -
Example: the following HTTP example shows how an internal app bot sends a text message to a group:
- Message template key:
"msgKey" : "sampleText" - Message template parameters:
"msgParam" : "{\"content\":\"DingTalk, where progress happens\"}"
- Message template key:
| Message type | Message template key | Message template parameters | Description |
|---|---|---|---|
| Text | sampleText | { "content": "xxxx" } | |
| Markdown | sampleMarkdown | { "title": "xxxx", "text": "xxxx" } | |
| Image | sampleImageMsg | { "photoURL": "xxxx" } | Note photoURL can be the full URL of the image or the mediaId of the image. To obtain the value of the media_id parameter, call the Upload media files API. |
| Link | sampleLink | { "text": "Message content test", "title": "sampleLink message test", "picUrl": "@lADOADmaWMzazQKA", "messageUrl": "http://dingtalk.io" } | Link message. |
| ActionCard | sampleActionCard | { "title": "Test title", "text": "Content test", "singleTitle": "View details", "singleURL": "https://open.dingtalk.com" } | Card message with one button. |
| sampleActionCard2 | { "title": "Message title test", "text": "Message body test", "actionTitle1": "Button 1", "actionURL1": "https://www.taobao.com", "actionTitle2": "Button 2", "actionURL2": "https://www.tmall.com" } | Card message: two buttons arranged vertically. | |
| sampleActionCard3 | { "title": "Message title test", "text": "Message content test", "actionTitle1": "Text of button 1", "actionURL1": "URL triggered by button 1", "actionTitle2": "Text of button 2", "actionURL2": "URL triggered by button 2", "actionTitle3": "Text of button 3", "actionURL3": "URL triggered by button 3" } | Card message: three buttons arranged vertically. | |
| sampleActionCard4 | { "title":"Message title test", "text":"Message content test", "actionTitle1":"Text of button 1", "actionURL1":"URL triggered by button 1", "actionTitle2":"Text of button 2", "actionURL2":"URL triggered by button 2", "actionTitle3":"Text of button 3", "actionURL3":"URL triggered by button 3", "actionTitle4":"Text of button 4", "actionURL4":"URL triggered by button 4" } | Card message: four buttons arranged vertically. | |
| sampleActionCard5 | { "title":"Message title test", "text":"Message content test", "actionTitle1":"Text of button 1", "actionURL1":"URL triggered by button 1", "actionTitle2":"Text of button 2", "actionURL2":"URL triggered by button 2", "actionTitle3":"Text of button 3", "actionURL3":"URL triggered by button 3", "actionTitle4":"Text of button 4", "actionURL4":"URL triggered by button 4", "actionTitle5":"Text of button 5", "actionURL5":"URL triggered by button 5" } | Card message: five buttons arranged vertically. | |
| sampleActionCard6 | { "title": "xxxx", "text": "xxxx", "buttonTitle1":"xxxxx", "buttonUrl1":"xxxxx", "buttonTitle2":"xxxxx", "buttonUrl2":"xxxxx" } | Card message: two buttons arranged horizontally. | |
| Audio | sampleAudio | { "mediaId": "@IR_P********nFkfhsisbf4A", "duration":"xxxxx" } | Voice message: - mediaId: obtain the value of the media_id parameter by calling the Upload media files API. Note Supports OGG and AMR formats. - duration: duration of the voice message, in milliseconds. |
| File | sampleFile | { "mediaId":"@lAz*********shRs5m2pRL", "fileName":"spreadsheet.xlsx", "fileType":"xlsx" } | File message: - mediaId: obtain the value of the media_id parameter by calling the Upload media files API. - fileName: file name. - fileType: file type. Note Supported file types: xlsx, pdf, zip, rar, doc, and docx. |
| Video | sampleVideo | { "duration":"999", "videoMediaId":"$iQEL**********AXNSs6QPPAAABhKN2L3EEzTcTB84BFM7iCAAJomlt", "videoType":"mp4", "picMediaId":"$igE**********tAFzQUABtoAIYQBpAtR3SICqrQ7ZX0nEJzAKxUDzwAAAYSjdi2cBM02vwcACAAJomltCgQ" } | Video message: - duration: duration of the voice message, in seconds. - videoMediaId: obtain the value of the media_id parameter by calling the Upload media files API. - videoType: video format. Only MP4 is supported. - picMediaId: cover image of the video. Obtain the value of the media_id parameter by calling the Upload media files API. - height: display height of the video, in pixels. - width: display width of the video, in pixels. |
Supported Markdown syntax
Additional notes on the Markdown syntax for the sampleMarkdown message type.
Method 2: Use a Webhook
Webhooks are supported only in group chats.
Text message
| Parameter | Required | Type | Description |
|---|---|---|---|
| msgtype | Yes | String | text. |
| content | Yes | String | Message text. |
| atMobiles | No | Array | Mobile numbers of the users to @. Note Add the mobile numbers of the users to @ in content. Only group members can be @. Mobile numbers of non-members are masked. |
| atUserIds | No | Array | User IDs of the users to @. Note Add the user IDs of the users to @ in content. |
| isAtAll | No | Boolean | Set to true to @ everyone; otherwise, set to false. |
Link message
This type does not support @ People.
| Parameter | Type | Required | Description |
|---|---|---|---|
| msgtype | String | Yes | Message type. Set to link. |
| title | String | Yes | Message title. |
| text | String | Yes | Message content. Long content is truncated. |
| messageUrl | String | Yes | URL to open when the message is tapped: - On mobile devices: opens in the DingTalk Client. - On PC: - Opens in the side panel by default. - To open in an external browser, see Message link description. |
| picUrl | String | No | Image URL. |
Markdown message
| Parameter | Required | Type | Description |
|---|---|---|---|
| msgtype | Yes | String | Message type. Set to markdown. |
| title | Yes | String | The content shown on the first screen of the conversation. |
| text | Yes | String | Message content in Markdown format. |
| atMobiles | No | Array | Mobile numbers of the users to @. Note Add the mobile numbers of the users to @ in text. Only group members can be @. Mobile numbers of non-members are masked. |
| atUserIds | No | Array | User IDs of the users to @. Note Add the user IDs of the users to @ in text. |
| isAtAll | No | Boolean | Set to true to @ everyone; otherwise, set to false. |
ActionCard message
-
Whole-card jump ActionCard
Parameter Required Type Description msgtype Yes String Message type. Set to actionCard. title Yes String The content shown on the first screen of the conversation. text Yes String Message in Markdown format. Note To @ a user, add the user ID in text. For example: @manager7675singleTitle Yes String Title of the single button. singleURL Yes String URL to open when the message is tapped: - On mobile devices: opens in the DingTalk Client. - On PC: - Opens in the side panel by default. - To open in an external browser, see Message link description. btnOrientation No String Button layout: - 0: vertical - 1: horizontal -
Independent-jump ActionCard
Parameter Required Type Description msgtype Yes String actionCard. title Yes String The content shown on the first screen of the conversation. text Yes String Message content in Markdown format. Note To @ a user, add the user ID in text. For example: @manager7675btns Yes Array Buttons. title Yes String Button title. actionURL Yes String URL to open when the button is tapped: - On mobile devices: opens in the DingTalk Client. - On PC: - Opens in the side panel by default. - To open in an external browser, see Message link description. btnOrientation No String Button layout. 0: vertical 1: horizontal
FeedCard message
This type does not support @ People.
| Parameter | Required | Type | Description |
|---|---|---|---|
| msgtype | Yes | String | feedCard. |
| title | Yes | String | Text of each item. |
| messageURL | Yes | String | The URL to open when an item is tapped. For more information, see Message link description. |
| picURL | Yes | String | URL of the image displayed after each item. |
Receive messages with a bot
When a user @ the group bot or sends a direct message to the bot, DingTalk forwards the received message to the bot callback service configured by the developer.Message body
The following example uses the text message type. If you use HTTP callbacks, DingTalk delivers the message with a POST request.| Parameter | Type | Description |
|---|---|---|
| senderPlatform | String | The platform from which the message is sent. |
| conversationId | String | Chat ID. |
| atUsers | Array of Object | Information about the @ users. - dingtalkId: encrypted ID of the @ user. - staffId: user ID of the @ user. This field is empty for external users in an External Chat. - unionId: unionId of the @ user. |
| chatbotCorpId | String | Encrypted organization ID of the organization to which the bot belongs. |
| chatbotUserId | String | Encrypted bot ID. |
| msgId | String | Encrypted message ID. |
| senderNick | String | Name of the sender. |
| isAdmin | Boolean | Whether the sender is an Admin: - true: yes - false: no Takes effect after the bot is published. Otherwise, this field is not returned. |
| senderStaffId | String | The user ID of the member who @ the bot in an internal group. If the sender is not a member of the organization to which the bot belongs (for example, an external user @ the bot in an external group), this field is empty. Takes effect after the bot is published. Otherwise, this field is not returned. |
| senderUnionId | String | unionId of the sender. |
| sessionWebhookExpiredTime | Long | Expiration time of the Webhook URL for the current conversation. |
| createAt | String | Message timestamp, in milliseconds. |
| senderCorpId | String | Organization ID of the sender in an internal group. |
| conversationType | String | Conversation type: - 1: Direct Message - 2: Group Chat |
| senderId | String | Encrypted sender ID. |
| conversationTitle | String | The title of the conversation. Available only in group chats. |
| isInAtList | Boolean | Whether the bot is in the @ list. |
| sessionWebhook | String | Webhook URL for the current conversation. |
| text | Object | Message text: - content: the message content received by the bot. This field exists only when the message type is text. |
| msgtype | String | Message type: - text: text message - richText: Rich Text message - picture: image message - audio: voice message - video: video message - file: file message For the specific format of each type, see Message types below. |
| robotCode | String | Bot code. Custom bots do not have a robotCode. |
Message types
Bots can currently receive messages of the following types: text, voice, image, file, video, and Rich Text. The fields for each message type are explained below. Other than the message type and message body fields, the parameters are the same as in the table above.Text message
| Parameter | Type | Description |
|---|---|---|
| msgtype | String | Message type: - text: text message |
| text | Object | Message text: - content: the message content received by the bot. |
Rich Text message
| Name | Type | Description |
|---|---|---|
| msgtype | String | Message type: - richText: Rich Text |
| content | Object | Message content. |
| richText | Array of Object | Rich Text list. Note The message list can contain: - text: text message - picture: image message Use the image downloadCode to obtain a temporary download URL by calling the Server API Download the file content of messages received by the bot. |
Image message
| Parameter | Type | Description |
|---|---|---|
| msgtype | String | Message type: - picture: image message |
| downloadCode | String | Download code of the image file, used to retrieve the binary content of the image. Call the Server API Download the file content of messages received by the bot to obtain a temporary download URL. |
Voice message
In Group Chat conversations, the bot does not support receiving voice messages when a Group member @ the bot.
| Parameter | Type | Description |
|---|---|---|
| msgtype | String | Message type: - audio: voice message |
| downloadCode | String | Download code of the voice file, used to retrieve the binary content of the voice message. Call the Server API Download the file content of messages received by the bot to obtain a temporary download URL. |
| recognition | String | Text from Speech-to-Text recognition. |
| duration | Long | Duration of the voice message, in milliseconds. |
Video message
In Group Chat conversations, the bot does not support receiving video messages when a Group member @ the bot.
| Parameter | Type | Description |
|---|---|---|
| msgtype | String | Message type: - video: video message |
| downloadCode | String | Download code of the video file, used to retrieve the binary content of the video. Call the Server API Download the file content of messages received by the bot to obtain a temporary download URL. |
| videoType | String | Video file type. |
| duration | Long | Duration of the video, in milliseconds. |
File message
In Group Chat conversations, the bot does not support receiving file messages when a Group member @ the bot.
| Parameter | Type | Description |
|---|---|---|
| msgtype | String | Message type: - video: file message |
| downloadCode | String | Download code of the file, used to retrieve the binary content of the file. Call the Server API Download the file content of messages received by the bot to obtain a temporary download URL. |
| fileName | String | File name. |
Related content
If you select HTTP mode as the message receiving mode when creating an internal app bot, the HTTP header parameters shown below are included along with the message body when the bot receives a message:| Parameter | Description |
|---|---|
| timestamp | Timestamp when the message was sent, in milliseconds. |
| sign | Signature value. |
- If the difference between the timestamp and the current system timestamp is greater than 1 hour, the request is considered illegitimate.
- If the sign does not match the signature value you calculate, the request is considered illegitimate.
| Configuration item | Description |
|---|---|
| timestamp | Current timestamp, in milliseconds. |
| appSecret | The Client Secret of the app. For more information, see Client Secret. |
Error codes
When the bot Webhook or Stream usage exceeds the quota, the following behavior occurs:Error behavior
Group Chat conversations
Direct Message conversations
Error description
| Error code (errorCode) | Error message (errorMessage) | Description | Solution |
|---|---|---|---|
| 20001 | Due to excessive call volume, your message service is currently paused. Contact your organization Admin for assistance. An errorMessage field is added to the received message to display the error message. | - The text and content fields are not included in the received message. - Sign in to the Developer Console to view the call volume. | Upgrade to DingTalk Professional Edition or purchase an add-on package. For more information, see Organization add-on package purchase instructions. |
Related documents
- Send group chat messages with an Enterprise bot
- Send one-on-one messages with an Enterprise bot
- Send group chat messages with a Custom bot
- Send group chat messages with a group template bot