jenkinsci / office-365-connector-plugin

Office 365 Connector plugin sends jobs status notifications to Microsoft Teams or Outlook
https://plugins.jenkins.io/Office-365-Connector/
Apache License 2.0
89 stars 84 forks source link

Retirement of Office 365 connectors within Microsoft Teams #355

Open yogeshpsp opened 1 month ago

yogeshpsp commented 1 month ago

What feature do you want to see added?

Micorosft has announced that office 365 connector will expire on August 2024. Will this affect the office 365 connector jenkins plugin as well. https://devblogs.microsoft.com/microsoft365dev/retirement-of-office-365-connectors-within-microsoft-teams/

Upstream changes

No response

Are you interested in contributing this feature?

No response

PrismaComputer commented 1 month ago

A fix for the problem will be available in time?

wjones38 commented 1 month ago

This plugin can continue to be used if you translate the data it sends on power automate into Microsofts "adaptive card" format. See the comment from Damian E here: https://gitlab.com/gitlab-org/gitlab/-/issues/471344 for the template I used that got this working for me.

The biggest issue I ran into is that this plugin looks for a 200 response and Power Automate does not give 200 responses, it gives 202 responses. I opened an issue to address this here: https://github.com/jenkinsci/office-365-connector-plugin/issues/356

PrismaComputer commented 1 month ago

Folks, don't get me wrong, I know it's for free and open source. But please try to see it from the Admin side, who's just a user from this point of view. It's not the aim of the user to translate anything from this plugin into whatever. Especially if the webservice isn't giving the expected response code anyway. Adjustments have to be made anyway. I think the aim should be to have one checkbox in plugin configuration to trigger the usage of another data format and expecting another response code.

wjones38 commented 1 month ago

@PrismaComputer What you proposed would be nice, but the very simple addition of a 202 response code can be easily done in the short time window that Microsoft has given. Long term I wholeheartedly agree but, to be completely honest, right now I just need something that holds my team over until that long term solution is finished.

damianszczepanik commented 1 month ago

This plugin can continue to be used if you translate the data it sends on power automate into Microsofts "adaptive card" format. See the comment from Damian E here: https://gitlab.com/gitlab-org/gitlab/-/issues/471344 for the template I used that got this working for me.

Can be used but you need to user Power Automate and implement the workflow which will consume requests from this plugin. Is that correct?

wjones38 commented 1 month ago

@damianszczepanik yes, that is correct. Its not probably the nicest solution ever but it gets the job done.

damianszczepanik commented 1 month ago

@damianszczepanik yes, that is correct. Its not probably the nicest solution ever but it gets the job done.

Agree. Then this plugin will work as pure curl with POST method and the adaptive cards with filled subject/text as the body of this request.

PrismaComputer commented 1 month ago

@damianszczepanik Agree. Then this plugin will work as pure curl with POST method and the adaptive cards with filled subject/text as the body of this request.

As far as I can see, at the moment no adaptive cards are used. But for PowerAutomate adaptive cards are mandatory. This is at least my information, maybe I'm wrong. And it's not only the card definition itself. In opposite to “the old method” the card's JSON must be wrapped into "attachments": [] beside the “type”: “message”.

If I'm correct, just solving the 202 problem alone won't do the trick.

So, may I kindly ask where to edit the card's template? I did not find anything in Jenkins directory. But maybe I've overseen something.

jimmygoogle commented 1 month ago

This plugin can continue to be used if you translate the data it sends on power automate into Microsofts "adaptive card" format. See the comment from Damian E here: https://gitlab.com/gitlab-org/gitlab/-/issues/471344 for the template I used that got this working for me.

Can be used but you need to user Power Automate and implement the workflow which will consume requests from this plugin. Is that correct?

Unfortunately, you need a premium license to be able to use "When an http request is received", which would allow you to take the current payload Jenkins plugin sends and transform it to an adaptive card to post to a Teams channel. The "When a Teams webhook request is received" trigger does not require a premium license but it expects an adaptive card payload.

damianszczepanik commented 1 month ago

Can you clarify which one is where? This is not clear to me what is the difference or which one will work after office 365 retirement

jimmygoogle commented 1 month ago

Both webhooks will work as they are in the workflow setup (https://make.powerautomate.com/). The "When an http request is received" webhook allows you to supply the payload of the webhook that Microsoft will send. The "When a Teams webhook request is received" webhook expects a payload with a specific structure.

wjones38 commented 1 month ago

Both webhooks will work as they are in the workflow setup (https://make.powerautomate.com/). The "When an http request is received" webhook allows you to supply the payload of the webhook that Microsoft will send. The "When a Teams webhook request is received" webhook expects a payload with a specific structure.

@jimmygoogle have you tested using the "When a Teams webhook request is received" and received errors when sending a format that doesn't match? I have been able to send whatever payload I want to that trigger and it has been working. Not sure if maybe I just managed to find a loop hole on accident or what.

jimmygoogle commented 1 month ago

Both webhooks will work as they are in the workflow setup (https://make.powerautomate.com/). The "When an http request is received" webhook allows you to supply the payload of the webhook that Microsoft will send. The "When a Teams webhook request is received" webhook expects a payload with a specific structure.

@jimmygoogle have you tested using the "When a Teams webhook request is received" and received errors when sending a format that doesn't match? I have been able to send whatever payload I want to that trigger and it has been working. Not sure if maybe I just managed to find a loop hole on accident or what.

Yes I have tried that webhook and I get "Action 'Send_each_adaptive_card' failed: The execution of template action 'Send_each_adaptive_card' failed: the result of the evaluation of 'foreach' expression '@triggerOutputs()?['body']?['attachments']' is of type 'Null'. The result must be a valid array."

PrismaComputer commented 1 month ago

Yes I have tried that webhook and I get "Action 'Send_each_adaptive_card' failed: The execution of template action 'Send_each_adaptive_card' failed: the result of the evaluation of 'foreach' expression '@triggerOutputs()?['body']?['attachments']' is of type 'Null'. The result must be a valid array."

I completely agree.

That is the trigger which Teams will set up automatically if you click the drop-in replacement link (which, unfortunately, does not create a drop-in replacement) in the warning. Additionally, this is the trigger which you can set up manually without PowerAutomate Premium:

image

This trigger expects:

Otherwise, as you wrote, the error appears:

"Action 'Send_each_adaptive_card' failed: The execution of template action 'Send_each_adaptive_card' failed: the result of the evaluation of 'foreach' expression '@triggerOutputs()?['body']?['attachments']' is of type 'Null'. The result must be a valid array."

wjones38 commented 1 month ago

@PrismaComputer @jimmygoogle sounds to me like you guys just need to iterate over something that exists, not the attachments. Change the "send each adaptive card" to look for just the body.

Screenshot 2024-07-18 at 9 42 50 AM

PrismaComputer commented 1 month ago

“Everyone” using Teams Integration will encounter this problem. It is difficult to imagine that “everyone” will be able to resolve this using Power Automate. Previously, the solution involved simply copying and pasting a generated URL into the plugin. This meant that webhooks were utilized by users and companies without any extensive knowledge of automation.

@wjones38 , I understand that it is not your companies fault, but we cannot change the reality.

Could you please confirm whether the “old” MessageCard generated by the plugin will continue to work, or if an additional transformation of the card into adaptive-card is necessary, such as in Power Automate?

Additionally, do we have a timeline for the 202 fix?

jimmygoogle commented 1 month ago

“Everyone” using Teams Integration will encounter this problem. It is difficult to imagine that “everyone” will be able to resolve this using Power Automate. Previously, the solution involved simply copying and pasting a generated URL into the plugin. This meant that webhooks were utilized by users and companies without any extensive knowledge of automation.

@wjones38 , I understand that it is not your companies fault, but we cannot change the reality.

Could you please confirm whether the “old” MessageCard generated by the plugin will continue to work, or if an additional transformation of the card into adaptive-card is necessary, such as in Power Automate?

Additionally, do we have a timeline for the 202 fix?

The 202 fix was merged. According to Microsoft, the notifications as they are right now will stop working in September. The solution is to move to something in workflows.

wjones38 commented 1 month ago

Could you please confirm whether the “old” MessageCard generated by the plugin will continue to work, or if an additional transformation of the card into adaptive-card is necessary, such as in Power Automate?

You need to do some transformation in power automate and I can't guarantee it will be easy. The web UI is clunky and generally hard to understand but it is possible. If you change the foreach command to look only at the request body, then you can use the same general template that I used:

This plugin can continue to be used if you translate the data it sends on power automate into Microsofts "adaptive card" format. See the comment from Damian E here: https://gitlab.com/gitlab-org/gitlab/-/issues/471344 for the template I used that got this working for me.

This should get you most of the way. After that you will just need to look up how to style adaptive cards and plug in the variables from your payload into the adaptive card JSON.

PrismaComputer commented 1 month ago

From what I have observed, it should be possible to export the automation. Would it not be a good idea if someone with a fully functional (not theoretically working) solution shares their anonymised export here?

jimmygoogle commented 1 month ago

From what I have observed, it should be possible to export the automation. Would it not be a good idea if someone with a fully functional (not theoretically working) solution shares their anonymised export here?

@wjones38 got me on the right path and I got this working in Jenkins even with the 202 status returned. I setup a workflow based on the payload that Jenkins sends to the webhook. You can tell the payload after you build the workflow and test and it via Jenkins, Postman, etc.

card

For me, the Jenkins payload looks something like this so this helped me build my adaptive card. I don't see all of the facts that used to be there, I am still looking into that.

  "summary": "branch » master: Build #1",
  "themeColor": "3479BF",
  "sections": [
    {
      "markdown": true,
      "facts": [
        {
          "name": "Status",
          "value": "Success"
        }
      ],
      "activityTitle": "Notification from branch » master",
      "activitySubtitle": "some text here"
    }
  ],
  "potentialAction": []
}

Inside the Post card in chat or channel settings, I used this adaptive card JSON. This is what worked for me and my setup. You might be able to copy/paste it or you might need to adapt it to your situation.

   "type": "AdaptiveCard",
   "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
   "version": "1.4",
   "msteams": {
      "width": "Full"
   },
   "body": [
      {
         "type": "TextBlock",
         "size": "Large",
         "weight": "Bolder",
         "text": "@{replace(triggerBody().sections[0].activityTitle, '\', '\\')}"
      },
      {
         "type": "ColumnSet",
         "columns": [
            {
               "type": "Column",
               "width": "stretch",
               "items": [
                  {
                     "type": "TextBlock",
                     "weight": "Bolder",
                     "text": "@{triggerBody().sections[0].activitySubtitle}",
                     "wrap": true
                  },
                  {
                     "type": "TextBlock",
                     "text": "@{triggerBody().summary}",
                     "wrap": true
                  },
                  {
                     "type": "TextBlock",
                     "text": "Status: @{triggerBody().sections[0].facts[0].value}",
                     "wrap": true
                  }
               ]
            }
         ]
      }
   ]
}

The workflow run history will show you successes, failures and it will show you exactly what was sent. Clicking into the run history for a given request is extremely useful. run-history

PrismaComputer commented 1 month ago

I don't see all of the facts that used to be there, I am still looking into that.

Thank you for the information. I am beginning to understand the approach and objective. Although my opinion remains that it is not the administrator's responsibility to fit a square peg into a round hole, the plugin requires fixing.

Nevertheless, thank you. I shall wait until all questions (regarding why you do not see all the facts) are answered. Perhaps by then, the plugin will have been improved. If not, we can still resort to more drastic measures. I look forward to your investigation, @jimmygoogle. Thank you very much.

jimmygoogle commented 1 month ago

I don't see all of the facts that used to be there, I am still looking into that.

Thank you for the information. I am beginning to understand the approach and objective. Although my opinion remains that it is not the administrator's responsibility to fit a square peg into a round hole, the plugin requires fixing.

Nevertheless, thank you. I shall wait until all questions (regarding why you do not see all the facts) are answered. Perhaps by then, the plugin will have been improved. If not, we can still resort to more drastic measures. I look forward to your investigation, @jimmygoogle. Thank you very much.

I am not sure I am going to figure out why the facts are missing or even if they are missing at all. All I know is I dont have the same information in the webhook payload that diplayed previously for us. That might be a configuration thing on our end for all I know. I currently have a working solution so unless the plugin is updated, I am probably going to leave it as is.

fafl245 commented 1 month ago

From what I have observed, it should be possible to export the automation. Would it not be a good idea if someone with a fully functional (not theoretically working) solution shares their anonymised export here?

@wjones38 got me on the right path and I got this working in Jenkins even with the 202 status returned. I setup a workflow based on the payload that Jenkins sends to the webhook. You can tell the payload after you build the workflow and test and it via Jenkins, Postman, etc.

card

For me, the Jenkins payload looks something like this so this helped me build my adaptive card. I don't see all of the facts that used to be there, I am still looking into that.

  "summary": "branch » master: Build #1",
  "themeColor": "3479BF",
  "sections": [
    {
      "markdown": true,
      "facts": [
        {
          "name": "Status",
          "value": "Success"
        }
      ],
      "activityTitle": "Notification from branch » master",
      "activitySubtitle": "some text here"
    }
  ],
  "potentialAction": []
}

Inside the Post card in chat or channel settings, I used this adaptive card JSON. This is what worked for me and my setup. You might be able to copy/paste it or you might need to adapt it to your situation.

   "type": "AdaptiveCard",
   "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
   "version": "1.4",
   "msteams": {
      "width": "Full"
   },
   "body": [
      {
         "type": "TextBlock",
         "size": "Large",
         "weight": "Bolder",
         "text": "@{replace(triggerBody().sections[0].activityTitle, '\', '\\')}"
      },
      {
         "type": "ColumnSet",
         "columns": [
            {
               "type": "Column",
               "width": "stretch",
               "items": [
                  {
                     "type": "TextBlock",
                     "weight": "Bolder",
                     "text": "@{triggerBody().sections[0].activitySubtitle}",
                     "wrap": true
                  },
                  {
                     "type": "TextBlock",
                     "text": "@{triggerBody().summary}",
                     "wrap": true
                  },
                  {
                     "type": "TextBlock",
                     "text": "Status: @{triggerBody().sections[0].facts[0].value}",
                     "wrap": true
                  }
               ]
            }
         ]
      }
   ]
}

The workflow run history will show you successes, failures and it will show you exactly what was sent. Clicking into the run history for a given request is extremely useful. run-history

Hello @jimmygoogle, when I try to copy and paste your code to my flow in "code view" it says: "cannot edit in read-only" editor. What can I do? Thank you!

PrismaComputer commented 1 month ago

And this is, why we need an urgent fix of this plugin.

jimmygoogle commented 1 month ago

And this is, why we need an urgent fix of this plugin.

Even if/when the plugin is fixed you are still going to need setup a workflow. The readonly option is because you are using one of the precanned flows. You need to build your flow using the 2 steps from above.

PrismaComputer commented 1 month ago

@jimmygoogle : No, I disagree.

If the plugin were fixed (or better: given an option to use a different card and expect another return code), there would be no need to set up, tweak, program, modify, or manually handle flows. Within Teams, there's a "fix-it" link embedded in the depreciation warning. If you click this link, a new flow is created automatically—a precanned one, as you call it. This will be done within Teams without requiring any deeper knowledge of Power Automate, and without revealing that this is Power Automate at all.

This is how Microsoft anticipates this problem to be resolved. And this is what the typical admin will do and expect to work. As I wrote at the beginning, the topic here is not the reason for all this. The reason is, Microsoft is disregarding its users. However, the solution should not be to send the users back to Microsoft with their issues.

Of course, you can ask me, why should the developers of this plugin think this way? Answer: First of all, they decided to develop this plugin knowing it is Microsoft-related, with all its downsides. And second, perhaps they want to perform better than Microsoft?

jimmygoogle commented 1 month ago

This is an open source plugin, no one has responsibilities to fix anything. I took a day and learned how Power Automate worked and got a solution working for our situation. We use Team notifications for all sorts of things so it was in our best interest to learn about it and address it.

The crux of the problem here is that the notification is expecting an adaptive card but the payload coming from Jenkins is a message card. The easiest thing to do for us was to pass in an adaptive card template with the parts of the payload coming in from Jenkins.

meiswjn commented 1 month ago

This is an open source plugin, no one has responsibilities to fix anything.

And to add on that: while nobody is responsible, everyone is invited. If this is a great painpoint for you, the easiest way may be to provide a PR @PrismaComputer.

meiswjn commented 1 month ago

Inside the Post card in chat or channel settings, I used this adaptive card JSON. This is what worked for me and my setup. You might be able to copy/paste it or you might need to adapt it to your situation.

   "type": "AdaptiveCard",
   "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
   "version": "1.4",
   "msteams": {
      "width": "Full"
   },
   "body": [
      {
         "type": "TextBlock",
         "size": "Large",
         "weight": "Bolder",
         "text": "@{replace(triggerBody().sections[0].activityTitle, '\', '\\')}"
      },
      {
         "type": "ColumnSet",
         "columns": [
            {
               "type": "Column",
               "width": "stretch",
               "items": [
                  {
                     "type": "TextBlock",
                     "weight": "Bolder",
                     "text": "@{triggerBody().sections[0].activitySubtitle}",
                     "wrap": true
                  },
                  {
                     "type": "TextBlock",
                     "text": "@{triggerBody().summary}",
                     "wrap": true
                  },
                  {
                     "type": "TextBlock",
                     "text": "Status: @{triggerBody().sections[0].facts[0].value}",
                     "wrap": true
                  }
               ]
            }
         ]
      }
   ]
}

Note that a curly bracket { is missing at the beginning. Apart from that, it works perfectly. Thanks for sharing!

PrismaComputer commented 1 month ago

As I wrote at the beginning, the topic here is not the reason for all this. The reason is, Microsoft is disregarding its users.

I thought I was clear about this. Thank you for clarifying that this is open source. But I mentioned this previously as well to put my words in the right context. I seem to have hit a nerve.

@jimmygoogle, speaking of context: We are developers ourselves. It's not that we won't be able to do it. I'm concerned about the others who are not developers.

kikmon commented 1 month ago

Thanks to the previous comment, I was able to send a simple Teams notification using the declarative pipeline DSL Now, I'm hitting an issue when scaling up this method.

Current payload have optional elements (like potentialAction), and different outputs, so did someone manage to create a single adaptive card that could handle all the possible payloads sent by the plugin ? (I tried using the when keyword without much success) That way we could continue to use this plugin almost transparently

chrisipa commented 1 month ago

I fully agree with @PrismaComputer 's opinion. The plugin code needs to be adjusted, so that the users do not have to do any heavy lifting on their side in MS Power Automate. It should basically become a drop in replacement for the old approach of using the Office365 webhook connector.

That's why I think there should be a global switch in the plugin configuration to either use the old approach or the new one with a MS Power Automate flow.

mbxsuite commented 1 month ago

Current payload have optional elements (like potentialAction), and different outputs, so did someone manage to create a single adaptive card that could handle all the possible payloads sent by the plugin ?

I also tried to play around with the adaptive cards. But that is not something I want to do on the "PowerBla" side. In the end I felt forced to building logic there, depending on the message sent from Jenkins. (If message "contains" element x, use this card otherwise that.) .... That is the wrong approach from my POV.

SoftpymesJuan-Camilo-C commented 1 month ago

I've been working this way, if you're interested take a look here: https://github.com/jenkinsci/office-365-connector-plugin/issues/353#issuecomment-2226115269

mbxsuite commented 1 month ago

OK, I had a look into Card.java and how it is used. If I got it right, the Card object is build by createCompletedCard and other methods and directly turned into Json just before sending it to the remote. So the object structure defines the json request.

Then the Card class might need one or two new siblings for the AdaptiveCard and HtmlMessage format.

The new Workflow does not support ConnectorCards (Card.java) anymore, but AdaptiveCards and "Messages". I personally find AdaptiveCards "nice", but way too bloated. "Messages" on the other hand can contain HTML, but do not get wrapped with an extra border, space and footer message like this "AdaptiveCard": grafik

I played around and came up with these basic message jsons. You are able to test the Workflow with via curl --url <triggerurlwithauth> -XPOST -d @sample.json -H "Content-Type: application/json"

x payload Teams-Workflow Definition
Message {"message":"Surely someone thought <b>HTML</b> is way <sub>more</sub> <i>convenient</i>, than Markdown."} "When a Teams webhook request is received" -> "Post message in a chat or channel" -> Parameters: Message: triggerBody().message
single AdaptiveCard {"$schema":"http://adaptivecards.io/schemas/adaptive-card.json", "type":"AdaptiveCard","version":"1.4", "body":[{"type":"Container","style":"warning","items":[ {"type":"TextBlock","text":"default","weight":"Bolder", "size":"Medium","color":"default"}]}]} "When a Teams webhook request is received" -> "Post to a channel when a webhook request is received" -> Parametes: Adaptive Card: triggerBody()
multiple AdaptiveCards {"attachments":[{"contentType":"text/json","content":{ "$schema":"http://adaptivecards.io/schemas/adaptive-card.json", "type":"AdaptiveCard","version":"1.4", "body":[{"type":"Container","items":[ {"type":"TextBlock","text":"card1", "weight":"Bolder","size":"Medium","color":"warning"}]}]}}, {"contentType":"text/json","content":{ "$schema":"http://adaptivecards.io/schemas/adaptive-card.json", "type":"AdaptiveCard","version":"1.4", "body":[{"type":"Container","items":[ {"type":"TextBlock","text":"card2", "weight":"Bolder","size":"Medium","color":"attention"}]}]}}]} "When a Teams webhook request is received" -> "Send each adaptive card" -> Parameters: "Select an output from previous steps": triggerBody()?['body']?['attachments'] && "Post to a channel when a webhook request is received" -> Parametes: Adaptive Card: item()?['content']

The 1st and 2nd workflow variants are pretty straight forward in Java code (compared to the current implementation) and on the Workflow side. The 3rd workflow gets somehow the default, if you fiddle around in the UI for the first time. I currently don't see the requirement to send multiple cards into one Channel. Yes, that is beyond this plugins scope, but I think this should also be documented here, in case this plugin will get an option to choose the desired message format.

The possibly supportable elements of an adaptive card can be found here.

yogeshpsp commented 1 month ago

image Deadline got extended till Dec 2025 for existing connectors

RobEvans875 commented 1 month ago

Last week I got this working with Power Automate using its "when a Teams webhook request is received" >>> "Post card in a chat or a channel". I used the adaptive card i think @jimmygoogle posted above here and editted it to suit what I needed. This also involved changing the old teams webhook with Power Automates new webhook for nearly every job I have setup in Jenkins.

What I noticed was that I was receiving 3 identical notifications in the Teams channel for every job being completed. I seen this morning that the plugin was updated here so I installed it. That has resolved the 3 notificiations issues and I am only receiving 1 as expected now.

PrismaComputer commented 1 month ago

image Deadline got extended till Dec 2025 for existing connectors

Yes, I have already noticed that the deprecation warning in Teams has been removed. It appears that the appropriate individuals utilized their support plans and connections with Microsoft to prevent this from happening. Much ado about nothing.

…but changes nothing and gives the developers time to implement the user-friendly way.

myronu commented 1 month ago

Just so nobody else runs into this, I found that viewing Workflows in Teams you do not see the body of the request that was sent, however, the PowerAutomate website, https://make.powerautomate.com, does show the body. After looking at the responses we were receiving for both success and failure, and other examples found here and elsewhere, I was able to build an adaptive card that works well for our needs.

abc21086999 commented 1 month ago

Hi guys, I just found a temporary workround for this issue.

First, after Jenkins job is finished and send request to the webhook url, it's payload will be parsed into headers and body: Xnip2024-07-26_16-53-32 You can check this in the Power Automate, here is the body part, it's in a json format:

{
  "summary": "Jenkins » Regression Test » Your Tasks",
  "themeColor": "3479BF",
  "sections": [
    {
      "markdown": true,
      "facts": [
        {
          "name": "Status",
          "value": "Started"
        },
        {
          "name": "Remarks",
          "value": "Started by user Muffin."
        }
      ],
      "activityTitle": "Notification from Jenkins » Regression Test » Your Tasks",
      "activitySubtitle": "Latest status of build #1"
    }
  ],
  "potentialAction": [
    {
      "@context": "http://schema.org",
      "@type": "ViewAction",
      "name": "View Build",
      "target": [
        "https://url_to_your_job"
      ]
    }
  ]
}

And since we are going to let the Workflow bot sent card into the chat, we have to tell the bot what kind of information we want him to write into the card. Microsoft is using something called Adaptive Card for this, so you might need to search for how to make an adaptive card.

Here is the Adaptive card I use:

{
    "type": "AdaptiveCard",
    "body": [
        {
            "type": "TextBlock",
            "size": "Large",
            "weight": "Bolder",
            "text": "@{triggerBody().sections[0].activityTitle}"
        },
        {
            "type": "ColumnSet",
            "columns": [
                {
                    "type": "Column",
                    "width": "stretch",
                    "items": [
                        {
                            "type": "TextBlock",
                            "text": "@{triggerBody().summary}",
                            "wrap": true
                        },
                        {
                            "type": "TextBlock",
                            "weight": "Bolder",
                            "text": "Status: @{triggerBody().sections[0].facts[0].value}",
                            "wrap": true
                        },
                        {
                            "type": "TextBlock",
                            "text": "Remarks: @{triggerBody().sections[0].facts[1].value}",
                            "wrap": true
                        }
                    ]
                }
            ]
        }
    ],
    "actions": [
        {
            "type": "Action.OpenUrl",
            "title": "Link",
            "url": "@{triggerBody().potentialAction[0].target[0]}"
        }
    ],
    "msteams": {
        "width": "Full"
    },
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.4"
}

Anything you need to take out from the body of Jenkins body, you need to use trigger.Body(), for the rest of the features about Adaptive card like how to make the words bigger, you can check at apadtive card's website.

Note: setting adaptive card's version to 1.5 will cause error, causing the workflow bot unable to show message in chat

claudia-ca commented 1 month ago

I wanted to share my 2 cents, since I've been trying to make the switch to a workflow too and eventually got it to work though it took quite a bit of trial and error. Things I've noticed:

Our post now look like this: image

The adaptive card:

    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.4",
    "msteams": {  
        "width": "Full"
    },
    "body": [
        {
            "type": "ColumnSet",
            "columns": [
                {
                    "type": "Column",
                    "width": "5px",
                    "items": [
                        {
                            "type": "Container",
                            "backgroundImage": {
                                "url": "@{variables('imgUrl')}",
                                "fillMode": "RepeatVertically"
                            },
                            "height": "stretch",
                            "minHeight": "5px"
                        }
                    ]
                },
                {
                    "type": "Column",
                    "width": "stretch",
                    "items": [
                        {
                            "type": "TextBlock",
                            "text": "@{variables('activityTitle')}",
                            "weight": "bolder",
                            "wrap": true
                        },
                        {
                            "type": "TextBlock",
                            "wrap": true,
                            "separator": true,
                            "text": "@{body('Parse_JSON')?['sections'][0]['activitySubtitle']}"
                        }
                    ]
                }
            ]
        },
        {
            "type": "Container",
            "items": [
                {
                    "type": "FactSet",
                    "separator": true,
                    "facts": @{variables('factlist')}
                }
            ]
        },
        {
            "type": "Container",
            "items": [
                {
                    "type": "ActionSet",
                    "actions": [
                        {
                            "type": "Action.OpenUrl",
                            "title": "@{body('Parse_JSON')?['potentialAction'][0]['name']}",
                            "url": "@{body('Parse_JSON')?['potentialAction'][0]['target'][0]}"
                        }
                    ]
                }
            ]
        }
    ]
}

Here's a clip with the whole workflow, in case someone perhaps finds it useful: 2024-07-26_17-24-42

I created the image data uri's with the help of this link.

sebracs commented 1 month ago

I also managed to setup a somewhat generic converter Workflow based on @jimmygoogle 's original example:

{
   "type": "AdaptiveCard",
   "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
   "version": "1.4",
   "msteams": {
      "width": "Full"
   },
   "body": [
      {
         "type": "TextBlock",
         "size": "Large",
         "weight": "Bolder",
         "text": "@{replace(triggerBody().sections[0].activityTitle, '\', '\\')}"
      },
      {
         "type": "ColumnSet",
         "columns": [
            {
               "type": "Column",
               "width": "stretch",
               "items": [
                  {
                     "type": "TextBlock",
                     "weight": "Bolder",
                     "text": "@{triggerBody().sections[0].activitySubtitle}",
                     "wrap": true
                  },
                  {
                     "type": "TextBlock",
                     "text": "@{triggerBody().summary}",
                     "wrap": true
                  },
                  {
                     "type": "TextBlock",
                     "text": "Status: @{triggerBody().sections[0].facts[0].value}",
                     "wrap": true
                  }
               ]
            }
         ]
      }
   ]
}

by adding "Apply to all" loops and Compose data operations: image

image

You can also get a colored stripe back by adding a background image that is just a single color and repeating it vertically or horizontally only.

Here is the Adaptive Card template json:

{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.4",
    "verticalContentAlignment": "Center",
    "msteams": {
       "width": "Full"
    },
    "backgroundImage": {
        "url": "data:image/gif;base64,R0lGODlhCAABAIABAAD/AAacDywAAAAACAABAAACA4RvBQA7",
        "fillMode": "RepeatVertically"
    },
    "body": [
        {
            "type": "ColumnSet",
            "columns": [
                {
                    "type": "Column",
                    "items": [
                        {
                            "type": "Image",
                            "style": "Person",
                            "url": "https://www.jenkins.io/images/logos/jenkins/jenkins.png",
                            "altText": "Jenkins",
                            "size": "Small"
                        }
                    ],
                    "width": "auto"
                },
                {
                    "type": "Column",
                    "items": [
                        {
                            "type": "TextBlock",
                            "size": "Medium",
                            "weight": "Bolder",
                            "text": "@{replace(triggerBody().sections[0].activityTitle, '\', '\\')}",
                            "color": "@{triggerBody().themeColor}",
                            "style": "heading",
                            "wrap": true
                        }
                    ],
                    "width": "stretch"
                }
            ]
        },
        {
            "type": "TextBlock",
            "text": "@{triggerBody().sections[0].activitySubtitle}",
            "wrap": true
        },
        {
            "type": "FactSet",
            "facts":  @{variables('myfilter')}
        }
    ],
    "actions": @{variables('myactions')}
}
karannnn-exe commented 1 month ago

Check out this one . I have added all the steps to get this working.

https://www.linkedin.com/posts/karandeep-singh-597519173_transforming-notifications-transitioning-activity-7223540111076900864-atak?utm_source=share&utm_medium=member_android

manuelwallrapp commented 1 month ago

We can only support @PrismaComputer, there is a fix necessary in this plugin. We want to send as effortless Teams Notifications as we did so far. That is very possible if the Plugin gets updated. Everything stays simple and lean and the users just need to update their Teams Notification URL to a Teams workflow webhook.

mehroz377 commented 1 month ago

@manuelwallrapp absolutely correct.

kikmon commented 1 month ago

Thanks for the PR, hopefully it will allow us to proceed with the migration in a smooth and elegant way. When can we expect it to be merged ? I don't see much activity from reviewers

sebracs commented 3 weeks ago

I created the image data uri's with the help of this link.

@claudia-ca Do you know if there is any way to do this hex-color to base64 gif conversion using PowerAutomate? There seem to be string, binary and base64 conversion functions, but no way to get binary string from a hex.

PrismaComputer commented 3 weeks ago

As I expect that this issue will be resolved by the developers of this plugin and not by each individual user in a slightly different way each time, this message is more for the developers than for the users:

image

Red: I'm interested in whether this can be changed to “Jenkins” instead of “UserXY via Workflows”. However, I fear this can only (and nearly) be solved by creating a user named Jenkins.

Magenta: How can we have the task name here instead of “Card”?

Orange: How can we remove this completely unnecessary comment?

markush81 commented 3 weeks ago

Magenta: this is your "Jenkins job display name" afaik

Red/Orange: is IMHO completely up to Microsoft.

PrismaComputer commented 3 weeks ago

Red: This can be somewhat resolved by the Admin, for example, by using a Workflow owner named “Jenkins”. Magenta: I hope this is a misunderstanding. This should not be up to “me” (as you wrote “you”. Who is “you”?). Orange: This remains up to Microsoft but is truly a minor issue.