How to extract content/text of an attachment from an MS Teams messaged generated by a webhook?

Viewed 52

Automation #1 is ServiceNow > webhook > MS Teams > message.

Automation #2 is Power Automate > When keywords are mention (trigger) > read message from automation #1 > Post message in chat or channel

Problem: I am unable to workout the expression needed to read the content from the message body marked as the 2nd of the 3 blocks below i.e. "content":

  "body": {
    "contentType": "html",
    "content": "<attachment id=\"x\"></attachment>",
    "plainTextContent": ""
  },
  "channelIdentity": {
    "teamId": "x",
    "channelId": "x"
  },
  "attachments": [
    {
      "id": "x",
      "contentType": "application/vnd.microsoft.teams.card.o365connector",
      "contentUrl": null,
"content": "{\r\n  \"summary\": \"P1/2 incident next action overdue  [xx_NAO_P1-2]\",\r\n  \"title\": \"P1/2 incident next action overdue  [xx_NAO_P1-2]\",\r\n  \"themeColor\": \"ff0000\",\r\n  \"sections\": [\r\n    {\r\n      \"text\": \"Attn: <strong>name_here</strong> (email_here) \\n</br></br>\\nThe next action for case <strong>case_number</strong> is <span style=\\\"color:red\\\"><strong>over due</strong></span>. The stated action was:\\n</br></br>\\n<span style=\\\"color:blue\\\">This is the next action for case_number.</span>\",\r\n      \"title\": \"\",\r\n      \"activityTitle\": \"\",\r\n      \"activitySubtitle\": \"\",\r\n      \"activityText\": \"\",\r\n      \"markdown\": false,\r\n      \"startGroup\": false\r\n    },\r\n    {\r\n      \"markdown\": true,\r\n      \"startGroup\": false\r\n    }\r\n  ],\r\n  \"potentialAction\": []\r\n}",
      "name": null,
      "thumbnailUrl": null
    }
  ],
2 Answers

You can use the Body Content property for this.

Below is an example of this.

Btw, with an expression that would be:

outputs('Get_message_details')?['body/body/content']

enter image description here

Okay, this is my first ever Power Automate flow, so its not pretty. I think "Compose 2" and "Compose 3" are not required. If there are any suggestions on how to eliminate the need for 2x "Parse JSON" steps I am all ears. If there is a way to bypass the JSON steps altogether, even better.

I hope my experience, can help someone else.

Power Automate – Trigger

When keywords are mentioned
    Message type: Channel
    Keywords to search for: “[my keyword]”
    Team: [my channel]
    Channel – 1: General

Power Automate – Actions

Initialize variable – msg email
    Name: msg_email
    Type: String
    Value: [empty]
Initialize variable – msg caseNumber
    Name: msg_caseNumber
    Type: String
    Value: [empty]
Initialize variable – msg nextAction
    Name: msg_nextAction
    Type: String
    Value: [empty]
Apply to each
    Select an output from previous steps: Value = triggerOutputs()?[‘body/value’]
    Get message details
        Message: Message ID = items(‘Apply_to_each’)?[messageId’]
        Message type: Channel
        Team: Team ID = items(‘Apply_to_each’)?[‘teamId’]
        Channel: Channel ID = items(‘Apply_to_each’)?[‘channelId’]
        Parent message ID = [empty]
    Parse JSON
        Content: Body = body(‘Get_message_details’)
        Schema: [I took the output of the message and generated a schema]
            {
                "type": "object",
                "properties": {
                    "@@odata.context": {
                        "type": "string"
                    },
                    "id": {
                        "type": "string"
                    },
                    "replyToId": {},
                    "etag": {
                        "type": "string"
                    },
                    "messageType": {
                        "type": "string"
                    },
                    "createdDateTime": {
                        "type": "string"
                    },
                    "lastModifiedDateTime": {
                        "type": "string"
                    },
                    "lastEditedDateTime": {},
                    "deletedDateTime": {},
                    "subject": {},
                    "summary": {
                        "type": "string"
                    },
                    "chatId": {},
                    "importance": {
                        "type": "string"
                    },
                    "locale": {
                        "type": "string"
                    },
                    "webUrl": {
                        "type": "string"
                    },
                    "policyViolation": {},
                    "eventDetail": {},
                    "from": {
                        "type": "object",
                        "properties": {
                            "device": {},
                            "user": {},
                            "application": {
                                "type": "object",
                                "properties": {
                                    "id": {
                                        "type": "string"
                                    },
                                    "displayName": {
                                        "type": "string"
                                    },
                                    "applicationIdentityType": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    },
                    "body": {
                        "type": "object",
                        "properties": {
                            "contentType": {
                                "type": "string"
                            },
                            "content": {
                                "type": "string"
                            },
                            "plainTextContent": {
                                "type": "string"
                            }
                        }
                    },
                    "channelIdentity": {
                        "type": "object",
                        "properties": {
                            "teamId": {
                                "type": "string"
                            },
                            "channelId": {
                                "type": "string"
                            }
                        }
                    },
                    "attachments": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "string"
                                },
                                "contentType": {
                                    "type": "string"
                                },
                                "contentUrl": {},
                                "content": {
                                    "type": "string"
                                },
                                "name": {},
                                "thumbnailUrl": {}
                            },
                            "required": [
                                "id",
                                "contentType",
                                "contentUrl",
                                "content",
                                "name",
                                "thumbnailUrl"
                            ]
                        }
                    },
                    "mentions": {
                        "type": "array"
                    },
                    "reactions": {
                        "type": "array"
                    },
                    "messageLink": {
                        "type": "string"
                    },
                    "threadType": {
                        "type": "string"
                    },
                    "teamId": {
                        "type": "string"
                    },
                    "channelId": {
                        "type": "string"
                    }
                }
            }

    Apply to each 3
        Select an output from previous steps: attachments = body(‘Parse_JSON’)?[‘attachments’]
        
        Compose 2
            Inputs: content x = items(‘Apply_to_each_3’)?[‘content’]

        Parse JSON 2
            Content: Outputs x = outputs(‘Compose_2’)
            Schema: [I took the output of the attachment item and generated a schema]
                {
                    "type": "object",
                    "properties": {
                        "summary": {
                            "type": "string"
                        },
                        "title": {
                            "type": "string"
                        },
                        "themeColor": {
                            "type": "string"
                        },
                        "sections": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "text": {
                                        "type": "string"
                                    },
                                    "title": {
                                        "type": "string"
                                    },
                                    "activityTitle": {
                                        "type": "string"
                                    },
                                    "activitySubtitle": {
                                        "type": "string"
                                    },
                                    "activityText": {
                                        "type": "string"
                                    },
                                    "markdown": {
                                        "type": "boolean"
                                    },
                                    "startGroup": {
                                        "type": "boolean"
                                    }
                                },
                                "required": [
                                    "markdown",
                                    "startGroup"
                                ]
                            }
                        },
                        "potentialAction": {
                            "type": "array"
                        }
                    }
                }

        Compose 3
            Inputs: bodu(…) x = body(‘Parse_JSON_2’)[‘sections’][0][‘text’]

        Note:  after Compose 3 there are 3 parallel branches to create 3 variables which then converge back at Get an @mention token for a user.

        1.  Branch for variable msg_email
                Find text position “(“
                    Text: Outputs x = outputs(‘Compose_3’)
                    Search Text: (
                Substring email
                    Text: Outputs x = outputs(‘Compose_3’)
                    Starting Position: add(…) x = add(int(outputs('Find_text_position_"("')?['body']),1)
                    Length: sub(…) x = sub(sub(int(outputs('Find_text_position_")"')?['body']),int(outputs('Find_text_position_"("')?['body'])),1)
                Set variable msg email
                    Name: msg_email
                    Value: Body x = body(‘Substring_email’)
        2.  Branch for variable msg_caseNumber
                Find text position “[case prefix]“
                    Text: Outputs x = outputs(‘Compose_3’)
                    Search Text: [case prefix]
                Substring caseNumber
                    Text: Outputs x = outputs(‘Compose_3’)
                    Starting Position: Body x = body(‘Find_text_position_”[case prefix]”’)
                    Length: 11
                Set variable msg caseNumber
                    Name: msg_caseNumber
                    Value: Body x = body(‘Substring_caseNumber’)
        3.  Branch for variable msg_nextAction
                Find text position “colour:blue“
                    Text: Outputs x = outputs(‘Compose_3’)
                    Search Text: color:blue
                Substring nextAction+end tag
                    Text: Outputs x = outputs(‘Compose_3’)
                    Starting Position: add(…) x = add(12,int(outputs('Find_text_position_"color:blue"')?['body']))
                    Length: [empty]
                Substring nextAction
                    Text: Body x = body(‘Substring_nextAction+end_tag’)
                    Starting Position: 0
                    Length: sub(…) x = sub(length(outputs('Substring_nextAction+end_tag')?['body']),7)
                Set variable msg nextAction
                    Name: msg_nextAction
                    Value: Body = body(‘Substring_nextAction’)
    
    Get an @mention token for a user
        User: variables(‘msg_email’)

    Reply with a message in a channel
        Post as: Flow bot
        Post in: Channel
        Message ID: outputs(‘Get_message_deatils’)?[‘body/id’]
        Channel: Channel ID = outputs(‘Get_message_details’)?[‘body/channelId’]
        Message: 
        
            <p>@{outputs('Get_an_@mention_token_for_a_user')?['body/atMention']} Case @{variables('msg_caseNumber')} has an <span style="color: red"><strong>overdue Next Action</strong></span>. The stated action was:.<br>
            <br>
            <span style="color: blue"></span><span style="color: blue">@{variables('msg_nextAction')}</span><span style="color: blue"></span></p>
            
Related