这是我的第499篇原创文章,写于2023年8月6日。

以前的博文 Dynamics 365推送Model-driven app内通知功能介绍 介绍了Dynamics 365的通知功能,我们这里前进一步,这个通知需要我登录Dynamics 365才会看到,如果想在不登录Dynamics 365的时候也看到呢?可以通过向通知的接收对象的发送Microsoft Teams消息来通知吗?今天我们就来做个小Demo,利用到了一个新的功能,叫做Cards for Power Apps,关于它的介绍请参考官方文档:Cards for Power Apps overview ,有Canvas App基础的人掌握起来会更容易,因为写代码用的也是Power Fx

首先我想在创建一个通知后触发一个Power Automate来处理后续事宜,现在创建通知使用的消息是 SendAppNotification Action ,而不是我写作时候直接创建通知(appnotification)记录的方法了。自然而然我就想到了前些日子通过Action来触发flow的方法了,参考我的博文:通过调用Action/Custom API来触发Flow 。但是因为这个Action的 Allowed Custom Processing Step Type 的属性设置的是None,而不是 Async Only,所以没有办法通过这个Action来触发flow。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Automate


然后我尝试了一下,将Flow注册在通知消息的Create上是可以被触发的,如下:

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Card_02


下面我将创建一个Card,打开 https://make.powerapps.com/ ,点击左侧导航栏的 More > Cards。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Automate_03


点击命令栏的New card或者图片下面的 Create a card。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Platform_04


在弹出的Create a card窗口中为Card取个名字,然后点击Create按钮。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Automate_05


新建的初始界面如下:

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Automate_06


我需要创建两个变量来存储通知的标题和内容,点击左边的Variables图标,然后点击New variable。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Platform_07


第一个变量如下,我选中了Customization下的两个选项,因为我需要从Card外面接收通知的标题。记得Persistance一定要选择Permanent(Value is not reset)。我选中了Customization is required这个选项是因为我一定要传递这个参数的值。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Card_08


第二个变量类似如下,用来接收通知的内容:


通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Card_09


我再加个变量来存储用户选择的日期,并作为输出参数(目前我还不知道如何获取到输出参数的值),我这里设置如下,注意我这里选中了 Allow value to be returned to flow or bot 。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Platform_10


然后我将Card的标题和内容分别的Text属性分别设置为我创建的这两个变量,对于内容我还将其Divider设置为True,这样它的上方会多出一条线,这样分割开来我觉得好看点。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Platform_11


然后我再插入一个Date picker控件给用户来选择一个日期,一个Button控件用来给用户确认。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Automate_12


Date picker控件我设置了默认值为 Text(Today(),"mm/dd/yyyy") ,并且设置了Lable.

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Automate_13


对于新增的按钮控件,我设置Title属性,其Type为 Run PowerFx保持不变,并将其运行的PowerFx设置为 Set(varOutDate,DateValue(datePicker1)) ,也就是变量varOutDate的值设置为前面添加的日期控件datePicker1选择的日期。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Card_14


我还想在点击确定按钮的时候执行一些Dataverse相关的操作,我这里以创建一条记录为例。首先点击左边的Data图标,然后点击 Add data。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Platform_15


只有Microsoft Dataverse可以选,官方说还在增加其他的。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Platform_16


在弹出的窗口中点击OK按钮。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Platform_17


选择我要插入记录的表,点击Select按钮。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Card_18


然后我修改下确认按钮执行的表达式为:Set(varOutDate,DateValue(datePicker1));Collect('Demo Entities', {Name: Text(Now(),"yyyy-mm-dd hh:mm:ss" )}) 

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Automate_19


保存后,可以点击右上角的Play运行看看。我这里运行效果如下,也可以点击右上角的Send按钮生成一个Url (比如 https://make.powerapps.com/environment/b41eb721-c965-e08c-b189-619dc547e29e/cards/play/fc305b87-6d34-ee11-bdf5-6045bd571496/Qg0FB3 )通过Microsoft Teams发送给某个用户来展示这个Card。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Card_20

若要更改输入参数的值可以点击右上角的Customize按钮,更改后点击Done按钮。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Automate_21


但是我这里是要通过Flow来发送,所以我保存好这个Card,我们继续Flow的编辑。

Flow中我继续增加一个如下的步骤用来获取通知接收者的邮箱,姓名,特别是邮箱很有用,后面消息/Card要发给谁要用到。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Card_22


然后我们增加一个步骤,这个步骤用到了 Cards for Power Apps 这个Connector (截止本文写作时中国大陆版本的Power Platform还没有这个Connector).

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Card_23


选择 Create card instance这个Action。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Platform_24


我这里选择我前面创建的Card,对于输入参数我分别设置为创建的通知的标题和内容。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Platform_25


然后添加一个步骤,这次使用Microsoft Teams这个Connector中的Create a chat这个步骤。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Automate_26


设置如下图所示:

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Automate_27


然后还是从Microsoft Teams这个Connector中添加一个Post card in a chat or channel Action.

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Automate_28


这个步骤的设置如下:

Post as我选择 Power Apps (Preview),记得一定要选这个。

Post in我选择 Group chat

Group chat我选择前面 Create a chat步骤的输出值Conversation Id

Card我选择前面Create card instance步骤的输出值Card


通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Platform_29


保存好Flow,在测试之前,接收这种Card消息的用户最好是打开Teams,选择应用,搜索 Power Apps,将这个App添加到合适的位置,我这里是添加到聊天。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Platform_30


然后选择一个群组聊天,我这里是和管理员的聊天。

目前看来不需要手动安装Power Apps这个应用应该也可以的,当然提前安装好最好了。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Card_31


然后我这里测试发送,我使用如下代码创建了一个通知给testuser01这个用户:

var Example = window.Example || {};
Example.SendAppNotificationRequest = function (
   title, 
   recipient, 
   body, 
   priority, 
   iconType, 
   toastType, 
   expiry, 
   overrideContent, 
   actions) 
{
    this.Title = title;
    this.Recipient = recipient;
    this.Body = body;
    this.Priority = priority;
    this.IconType = iconType;
    this.ToastType = toastType;
    this.Expiry = expiry;
    this.OverrideContent = overrideContent;
    this.Actions = actions;
};

Example.SendAppNotificationRequest.prototype.getMetadata = function () {
    return {
        boundParameter: null,
        parameterTypes: {
            "Title": {
                "typeName": "Edm.String",
                "structuralProperty": 1
            },
            "Recipient": {
                "typeName": "mscrm.systemuser",
                "structuralProperty": 5
            },
            "Body": {
                "typeName": "Edm.String",
                "structuralProperty": 1
            },
            "Priority": {
                "typeName": "Edm.Int",
                "structuralProperty": 1
            },
            "IconType": {
                "typeName": "Edm.Int",
                "structuralProperty": 1
            },
            "ToastType": {
                "typeName": "Edm.Int",
                "structuralProperty": 1
            },
            "Expiry": {
                "typeName": "Edm.Int",
                "structuralProperty": 1
            },
            "OverrideContent": {
                "typeName": "mscrm.expando",
                "structuralProperty": 5
            },
            "Actions": {
                "typeName": "mscrm.expando",
                "structuralProperty": 5
            },
        },
        operationType: 0, 
        operationName: "SendAppNotification",
    };
};

var SendAppNotificationRequest = new Example.SendAppNotificationRequest(
    title = "这是罗勇测试消息的标题",
    recipient = "/systemusers(0071f756-1605-ee11-8f6e-6045bd571496)",
    body = "这是罗勇测试消息的内容!",
    priority = 200000000,
    iconType = 100000000,
    toastType = 200000000,
);

Xrm.WebApi.online.execute(SendAppNotificationRequest).then(function (response) {
    if (response.ok) {
        console.log("Status: %s %s", response.status, response.statusText);

        return response.json();
    }
})
.then(function (responseBody) {
    console.log("Response Body: %s", responseBody.NotificationId);
})
.catch(function (error) {
    console.log(error.message);
});


然后Testuser01的Teams中就收到了如下的Card:

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Card_32


我点击Load card后界面如下:

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Platform_33


点击确认后会增加一行提示:“你的响应已发送到应用”。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Platform_34


在Model-Driven App中也可以看到新增了一条记录,创建者不是点击这个Card中确认按钮的用户,应该是添加Microsoft Davaverse连接使用的用户。

通过卡片(Card)向用户的Microsoft Teams发送卡片消息_Power Automate_35