Dingding robot single chat realizes interactive card push


background

The choice of specific business implementation methods in specific business scenarios

To upgrade the company's OA system, it is necessary to connect the messages in the OA system with the messages outside the system. A demand was put forward for this product. Therefore, 当用户在OA系统收到消息时,可同时在钉钉收到待办消息提醒,提醒用户前往OA系统查看消息,处理相关事宜DingTalk to-do was started. However, the effect after the implementation of DingTalk to-do was not satisfactory. Dingding cards are used for notifications. The use of card notifications is divided into group chat and single chat scenarios. And the whole process of card notification is quite tortuous. Next, I will reorganize the pits I have gone through, so that more people who need it can build it faster. Scenes.

Dingding to do

To-Do is a collaborative office product of DingTalk, which helps enterprise employees manage items (tasks) more efficiently. DingTalk to-do provides powerful open capabilities, and various business systems or self-built applications can be accessed at low cost. Because the main introduction is the realization of the business of sending cards in a single chat with DingTalk robots, so I will briefly mention it here.

DingTalk creates the code address of the pending case

insert image description here
After my own self-test, I found that DingTalk’s current logic is that if there is a jump url configured on the PC side and the app in the to-do list, then the work to-do will be created for you. This kind of to-do reminder is more eye-catching (there will be
red points, and to-do reminders)

insert image description here
But if the double-ended application jump address is not added in the code, the to-do of the work type will not be created, but the to-do of the personal type will be created. The to-do of the personal type will not be prompted by the to-do box,
and Reminders can only be reminded by manually clicking in .
In this case, the experience effect will be poor. Who can take the initiative to enter the to-do list every time to check personal to-do things?

insert image description here
You will think that DingTalk must have considered it, and there must be parameters to set the type of to-do.
But the current situation is that it is impossible to create a to-do without jumping based on the existing parameters provided .
If you can Realized, and you are welcome to try to tell me, let me also learn.
Because of the above reasons, we think that using DingTalk cards to send single-chat in the form of micro-apps or robots.
And then realize the push of OA system messages to Such a demand of DingTalk


nail card

The DingTalk interactive card is a lightweight card with real-time interaction, multi-person collaboration, and data-driven. It can decompose the originally complex application into lightweight cards in each field of DingTalk (please refer to the explanation of the field) Refer to the glossary section below) to run on. Users can complete interaction and collaboration on the card, which improves user communication efficiency and helps businesses better reach users. The official introduction address of DingTalk's interactive card ,

Those who are used to reading official documents can read this. The content in it is what I want to talk about today. Now I will share with you my understanding of this piece and the pitfalls I have stepped on.

After spending a long time reading official documents and debugging, I found that there are not only one kind of DingTalk interactive cards, but an astonishing three types! They are
sending card-type work notifications, and robots sending interactive cards (normal version) , and directly create and deliver cards .
Let me briefly introduce the differences between the three creation methods.

Card Type Job Notification

Send job notifications of card type

insert image description here
Cards created in this way have a fixed format and a low degree of freedom. You cannot edit the notification card format by yourself
insert image description here

Create and serve cards

  • Creating and Serving Cards
    insert image description here
    Card creation is complex. The main steps are:

    1. Enable card permissions and robot permissions (single chat)
    2. Create a card template (edit template, bind parameters)
    3. Add fields to card templates and create card instances
    4. Configure the field and launch the test
    5. web interface page test
    6. Generate relevant code
    7. Encapsulate the api and use

    And after I succeeded, I sent the web interface page test interface, which not only requires n parameters, but also the explanation of the parameters is not complete. After a long
    request, the interface request was successful, but the delivery result was not displayed and Dingding I haven't received the card information.
    Moreover, I can only ask DingTalk customer service about the interface request related issues through a work order,
    and the work order I submitted has not been answered for two working days as of the time of posting...
    insert image description here
    insert image description here

Bot sends interactive cards

  • The robot sends the interactive card (common version)
    because it mainly researched the interface of creating and delivering the card before, and immediately tested the relevant parameters.
    The parameters related to the robot’s single chat and field were finally supplemented, but the request failed in the end.
    But When reading the official document, I accidentally found that in the chapter of the robot, there is the function and interface of sending cards.
    So I tested it here. It took only a few minutes to get it done.

insert image description here

This way of creating card notifications has simple parameters, easy calling, and supports calling card templates and variable input.
Therefore, it is finally finalized to use this solution for business function realization


accomplish

The implementation of sending interactive cards based on robots and the introduction of the construction process and stepping on the pit

process build

The whole process can be divided into:

  • authorized
  • Create a bot
  • create card
  • Card delivery test
  • The web end calls the robot to send the card interface
  • Generate to-do and encapsulate interface
  • call test

Next, let's introduce the implementation process according to the above process

1. Authorization

The authorization here is mainly for the convenience of calling the interface later, and the problem of inability to call due to lack of permission

In DingTalk Open Platform -> Application Management -> Permission Management, search for robots, cards. Find the corresponding permissions and enable them
insert image description here
insert image description here

2. Create the bot

Configure the relevant information of the single-chat robot used to send cards later. Here is mainly to obtain the RobotCode, which is used for subsequent interface tests

Create a robot in DingTalk Open Platform->Application Management->Message and Push
insert image description here

3. Create a card

The purpose of creating cards is mainly for developers to create cards that meet their own business environment according to their needs. Bind their own business data through variables, and bind their own jump links through buttons Interactive components supported by cards

For cards, you can refer to the case introduction of the DingTalk card module . You can always do it well if you explore slowly.
Here are two main points: variable creation and linking issues .

variable creation

In the data source on the left side of the card, edit the variables needed later. In the card design, fill it with el expressions. The main format is. ${变量名}We can fill in the Mock data to display the rendering effect of the template

insert image description here

link problem

Interactive cards support link jumps. By default, if the card is configured with an ordinary HTTP protocol link, such as https://dingtalk.com, then it will be opened in a new window (open with the system default browser on the PC side, and open with the Normal H5 page opens).

However, in addition to the regular new window opening, DingTalk also supports various other opening methods, such as sidebar opening, semi-floating layer opening, etc. These jumping effects can be achieved by rationally using DingTalk's unified jumping protocol. However, in addition to the regular new window opening, DingTalk also supports various other opening methods, such as sidebar opening, semi-floating layer opening, etc. These jumping effects can be achieved by rationally using DingTalk's unified jumping protocol. Dingding link jump specification .

insert image description here
Here we mainly introduce the way to open the link in the pop-up window

Format:
dingtalk://dingtalkclient/page/link?popup_wnd=true&url=${url}&title=${title}&width=${width}&height=${height}
Parameter introduction:

insert image description here

According to the above requirements, I load a connection in the form of a window, and the window name is test, and the link should be constructed as
dingtalk://dingtalkclient/page/link?popup_wnd=true&url=https://open.dingtalk.com/document/orgapp/link-jump-specification&title=%E9%92%89%E9%92%89%E9%93%BE%E6%8E%A5%E8%A7%84%E8%8C%83&width=1000&height=800

However, after testing, the title of the pop-up window and the configuration of the width and height of the pop-up window have not taken effect, and related issues have been submitted to DingTalk. I hope it can be resolved as soon as possible.

4. Card delivery test

After the card is edited and bound to variables and parameters, it can be published. After the card is published, a card instance can be created. It is used for delivery in specific scenarios. After
delivery, we can see the message in DingTalk

  1. post card
    insert image description here

  2. Create a card instance in the card instance management
    insert image description here
    After the card instance is created later, the outTrackId will be generated, and the outTrackId will be used in the interface debugging later
    insert image description here

  3. Instance creation is, the type is generally static data.
    This static data means that after the card is sent, the data will only be pulled once.
    The dynamic data means that after the card is sent, it can be dynamically updated in real time according to the specified cycle Pull messages.
    insert image description here

  4. Example of placing a card
    insert image description here
    At present, you can only choose a single chat field for placement. After you choose to put it, you can put it on.
    insert image description here
    After the placement is successful, you will receive this notification in DingTalk. The success of this step means that the card is created successfully.
    insert image description here

  5. Returns the list of templates, where the template ID will be used for interface debugging
    insert image description here

5. The web end calls the robot to send the card interface

Enter the interface debugging page, enter the specified parameters and initiate the call. After the execution is successful, click the sample code to get the API called by the message

insert image description here
The following will share the code for the robot to send a single-chat interaction card

To run the following code in the development environment, you need to download the jar package, which I will share in the next chapter

// java代码
package com.aliyun.sample;

import com.aliyun.tea.*;

public class Sample {
    
    

    /**
     * 使用 Token 初始化账号Client
     * @return Client
     * @throws Exception
     */
    public static com.aliyun.dingtalkim_1_0.Client createClient() throws Exception {
    
    
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkim_1_0.Client(config);
    }

    public static void main(String[] args_) throws Exception {
    
    
        java.util.List<String> args = java.util.Arrays.asList(args_);
        com.aliyun.dingtalkim_1_0.Client client = Sample.createClient();
        com.aliyun.dingtalkim_1_0.models.SendRobotInteractiveCardHeaders sendRobotInteractiveCardHeaders = new com.aliyun.dingtalkim_1_0.models.SendRobotInteractiveCardHeaders();
        sendRobotInteractiveCardHeaders.xAcsDingtalkAccessToken = "<your access token>";
        com.aliyun.dingtalkim_1_0.models.SendRobotInteractiveCardRequest sendRobotInteractiveCardRequest = new com.aliyun.dingtalkim_1_0.models.SendRobotInteractiveCardRequest()
                .setSingleChatReceiver("{\"userId\":\"用户userId\"}")
                .setCardData("卡片模板变量填充的串")
                .setCardBizId("卡片唯一id")
                .setCardTemplateId("卡片模板id")
                .setRobotCode("机器人码RobotCode");
        try {
    
    
            client.sendRobotInteractiveCardWithOptions(sendRobotInteractiveCardRequest, sendRobotInteractiveCardHeaders, new com.aliyun.teautil.models.RuntimeOptions());
        } catch (TeaException err) {
    
    
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
    
    
                // err 中含有 code 和 message 属性,可帮助开发定位问题
            }

        } catch (Exception _err) {
    
    
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
    
    
                // err 中含有 code 和 message 属性,可帮助开发定位问题
            }

        }        
    }
}

# python代码
import sys

from typing import List

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_dingtalk.im_1_0 import models as dingtalkim__1__0_models
from alibabacloud_tea_util import models as util_models
from alibabacloud_tea_util.client import Client as UtilClient


class Sample:
    def __init__(self):
        pass

    @staticmethod
    def create_client() -> dingtalkim_1_0Client:
        """
        使用 Token 初始化账号Client
        @return: Client
        @throws Exception
        """
        config = open_api_models.Config()
        config.protocol = 'https'
        config.region_id = 'central'
        return dingtalkim_1_0Client(config)

    @staticmethod
    def main(
        args: List[str],
    ) -> None:
        client = Sample.create_client()
        send_robot_interactive_card_headers = dingtalkim__1__0_models.SendRobotInteractiveCardHeaders()
        send_robot_interactive_card_headers.x_acs_dingtalk_access_token = '<your access token>'
        send_robot_interactive_card_request = dingtalkim__1__0_models.SendRobotInteractiveCardRequest(
            single_chat_receiver='{"userId":"userId"}',
            card_data='卡片模板变量填充的json串',
            card_biz_id='chy123123',
            card_template_id='卡片唯一id',
            robot_code='机器人码RobotCode'
        )
        try:
            client.send_robot_interactive_card_with_options(send_robot_interactive_card_request, send_robot_interactive_card_headers, util_models.RuntimeOptions())
        except Exception as err:
            if not UtilClient.empty(err.code) and not UtilClient.empty(err.message):
                # err 中含有 code 和 message 属性,可帮助开发定位问题
                pass

    @staticmethod
    async def main_async(
        args: List[str],
    ) -> None:
        client = Sample.create_client()
        send_robot_interactive_card_headers = dingtalkim__1__0_models.SendRobotInteractiveCardHeaders()
        send_robot_interactive_card_headers.x_acs_dingtalk_access_token = '<your access token>'
        send_robot_interactive_card_request = dingtalkim__1__0_models.SendRobotInteractiveCardRequest(
            single_chat_receiver='{"userId":"01335649490826229549"}',
            card_data='{   "notifyTitle": "您有一个审核带申请",   "notifyType": "审核通知",   "notifyContent": "王康提交的一个新闻中心待申请",   "handleType": "待审核",   "createTime": "2023-03-15 21:40" }',
            card_biz_id='chy123123',
            card_template_id='592fafad-f6ff-4937-b713-73779152c555',
            robot_code='dingm1iglijknxgpjrvc'
        )
        try:
            await client.send_robot_interactive_card_with_options_async(send_robot_interactive_card_request, send_robot_interactive_card_headers, util_models.RuntimeOptions())
        except Exception as err:
            if not UtilClient.empty(err.code) and not UtilClient.empty(err.message):
                # err 中含有 code 和 message 属性,可帮助开发定位问题
                pass


if __name__ == '__main__':
    Sample.main(sys.argv[1:])

6. Generate the to-do and encapsulate the interface

Here I use the method of encapsulating the above parameters through objects, and then configuring the configuration objects through configuration files.

  1. DingTalk sds package download Portal on the download page . Here I choose to download the new version of sdk, and the version number is the latest 1.5.55

  2. Entity class construction

/**
 * info:卡片通知相关
 *
 * @Author caoHaiYang
 * @Date 2023/3/16 14:05
 */
public class CartNotifyDTO {
    
    
    /**
     * 通知标题
     */
    private String notifyTitle;
    /**
     * 通知类型
     */
    private String notifyType;
    /**
     * 通知内容
     */
    private String notifyContent;
    /**
     * 处理类型
     */
    private String handleType;
    /**
     * 创建时间
     */
    private String createTime;
    /**
     * 卡片接受者的用户id
     */
    @JsonIgnore
    private String receiveUserId;

    public String getNotifyTitle() {
    
    
        return notifyTitle;
    }

    public void setNotifyTitle(String notifyTitle) {
    
    
        this.notifyTitle = notifyTitle;
    }

    public String getNotifyType() {
    
    
        return notifyType;
    }

    public void setNotifyType(String notifyType) {
    
    
        this.notifyType = notifyType;
    }

    public String getNotifyContent() {
    
    
        return notifyContent;
    }

    public void setNotifyContent(String notifyContent) {
    
    
        this.notifyContent = notifyContent;
    }

    public String getHandleType() {
    
    
        return handleType;
    }

    public void setHandleType(String handleType) {
    
    
        this.handleType = handleType;
    }

    public String getCreateTime() {
    
    
        return createTime;
    }

    public void setCreateTime(String createTime) {
    
    
        this.createTime = createTime;
    }

    public String getReceiveUserId() {
    
    
        return receiveUserId;
    }

    public void setReceiveUserId(String receiveUserId) {
    
    
        this.receiveUserId = receiveUserId;
    }
  1. Single chat robot sending card business method
    /**
     * 使用 Token 初始化账号Client
     * @return Client
     * @throws Exception
     */
    public static com.aliyun.dingtalkim_1_0.Client createClient2() throws Exception {
    
    
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkim_1_0.Client(config);
    }

    @Override
    public void setCardNotify(CartNotifyDTO cardNotifyDTO) throws Exception {
    
    
        com.aliyun.dingtalkim_1_0.Client client = createClient2();
        com.aliyun.dingtalkim_1_0.models.SendRobotInteractiveCardHeaders sendRobotInteractiveCardHeaders = new com.aliyun.dingtalkim_1_0.models.SendRobotInteractiveCardHeaders();
        sendRobotInteractiveCardHeaders.xAcsDingtalkAccessToken = "这里注意accessToken有效期, 需要全局进行定时刷新, 所有的接口请求都要调用获取企业accessToken接口";
        com.aliyun.dingtalkim_1_0.models.SendRobotInteractiveCardRequest sendRobotInteractiveCardRequest = new com.aliyun.dingtalkim_1_0.models.SendRobotInteractiveCardRequest()
                .setSingleChatReceiver("{\"userId\":\""+cardNotifyDTO.getReceiveUserId()+"\"}")
                .setCardData(JSONObject.toJSONString(cardNotifyDTO))
                .setCardBizId(UUIDUtil.getUuid())
                .setCardTemplateId(dingTalkConfig.getCardTemplateId())
                .setRobotCode(dingTalkConfig.getRobotCode());
        try {
    
    
            SendRobotInteractiveCardResponse sendRobotInteractiveCardResponse = client.sendRobotInteractiveCardWithOptions(sendRobotInteractiveCardRequest, sendRobotInteractiveCardHeaders, new RuntimeOptions());
        } catch (TeaException err) {
    
    
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
    
    
                // err 中含有 code 和 message 属性,可帮助开发定位问题
                log.error(err.code, err.getMessage());
            }
        } catch (Exception _err) {
    
    
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
    
    
                // err 中含有 code 和 message 属性,可帮助开发定位问题
                log.error(err.code, err.getMessage());
            }
        }
    }

New discovery

When searching for information, I met an excellent blogger, Grandpa_Rick , who made DingTalk send interactive messages into a component. You only need to package the component dingtalk-module project, and then put it in the demo project, and you can use it easily. It is still in use today. Continuous update. The blogger is great, I asked him a lot of questions, and he answered them enthusiastically. If you are interested, you can also take a look at the realization of the DingTalk robot single-chat interactive card message (attached to the warehouse) .

Based on the demo code of the blogger. Only configure the following three places to achieve the above functions ( but you need to rewrite the sendInteractiveMsgToIndividual method under the DingBotMessageHandler class of the dingtalk-module component, and add the card template parameter in the method header method parameter Entity, and then convert the parameter entity into a map in the method and put it in cardData.setCardParamMap. Call the overridden method ).

The following is the configuration modification content

Modification 1: Modification of basic information
insert image description here
Modification 2: Fill in the card template id
insert image description here
Modification 3: User mobile phone number (you can change it to userId or union according to other interfaces provided by DingTalk to realize single-chat robot card push)insert image description here


Summarize

I have to feel that the Alibaba DingTalk open platform is an excellent enterprise-level application development platform, which has the advantages of convenience and ease of use, complete functions, safety and reliability, and community ecology, and can meet the needs of enterprises in digital transformation and business innovation. It is good at opening up the functions developed internally by DingTalk, independently making functions for use by various enterprises. It also combines various functions to realize the development of business scenarios. The combination of various scenarios provides enterprises with the ability to manage and Solutions during operation. Moreover, DingTalk scenario solutions provided by various companies can also be commercialized in DingTalk, so as to better promote the emergence of more DingTalk scenarios and solutions. This model is worthy of the Internet company study.

However, there is still a fly in the ointment. As a benchmark in the industry, DingTalk still has many problems in docking with third-party companies. For example: the document description of the interface part is poor, the cross-scenario correlation is poor, the key parameters of the interface are not clearly defined, and the work order The response is not timely, the interface sdk is divided into old and new versions, and the functions of the new version have not been explained. A
good ecology needs to be supported by a good open environment. I hope that DingTalk will continue to work hard, and don't forget to support developers while commercializing Benign support. Only in this way can the open platform be more open!

Guess you like

Origin blog.csdn.net/qq_43371556/article/details/129589752