Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

You have a working FlexDeploy Release/Pipeline. The goal of the tutorial is to send notifications to Microsoft Teams based on certain Release/Pipeline milestones being achieved.  The tutorial will include:

  • Configure credentials in AzureConfigure the Messaging Integration Account in FlexDeploy Configure FlexDeploy Webhooks to send messages to Teams

Configure

...

We would need to perform 3 primary activities,

...

a

...

A Service Principal(Azure Application), to handle authorization and send the messages on Teams on behalf of the user.

...

Provide all relevant access to the Service Principal so that it can send messages to Teams. Admin Consent/User Consent is essential as well.

...

Please refer to the below link on how to configure Service Principal(Azure Application) and provide relevant permissions.

...

FlexDeploy

...

During execution, both user and Azure Application credentials are used internally to generate an OAuth token which is used for authorization.

...

  • From the above steps, we have a valid Azure user and Service Principal(ClientID/Client Secret).

  • Create a new FlexDeploy Messaging Instance with the relevant details.

  • Use Test Connection to validate if the connection is established or not.

...

  • In case of any failure please check the FlexDeploy logs to understand the issue.

Configure a FlexDeploy Webhook to send Teams notifications

  • It may sound a bit complex with the terminology but once we understand how to configure it, you will find it pretty straightforward.

  • First review the below URL to understand the steps to configure an Outbound Webhook.

Getting Started with Outgoing Webhooks /wiki/spaces/FD90/pages/10926699866

  • Basically, there are two parts to a Webhook,

    • Filter – This is the criteria that determines when the Webhook will be triggered.

    • Script – This script is responsible for sending the Teams Notification.

  • Let's understand in a bit more detail. Below are some of the FlexDeploy events that can trigger a Webhook. The complete list of available events can be found in the link below
    Events /wiki/spaces/FD90/pages/10926699808

...

Filter

  • One event can be picked up by one Listener/Webhook only. So in case you have multiple Listeners configured with the same criteria (Filter), the Listener from the top of the list that satisfies the criteria (Filter) first will process the event message.

  • So it's absolutely essential to have a proper Event Message Filter. We have added the below filter.

...

  • You can get a detailed structure of the payload for each event from the below link.
    Events /wiki/spaces/FD90/pages/10926699808

  • Navigate to the Messages section on the Outgoing Webhooks page to view a summary of all the previously processed events.

...

Code Block
languagegroovy
def listenerName = "Send Teams Notification on Stage Completion";
LOG.info("Running listener: ${listenerName}");

def builder = new StringBuilder();

def envCode=EVENT.payload.environment.environmentName
def relName=EVENT.payload.release.releaseName
def pipelineName=EVENT.payload.pipeline.pipelineName
def executionStatus = EVENT.payload.pipelineStageExecution.executionStatus

// Setting the Header of the message
builder.append("<h1 style=\"padding: 10px 0\">Pipeline stage execution completed.</h1>");


// Sending the Stage execution details in Table format
// Below section is to form the HTML table format
builder.append("<table border=1>");

builder.append("<tr>"+
	"<th style=\"padding: 0 10px 5px 0\">Environment Name</th>"+
	"<th style=\"padding: 0 10px 5px 0\">Release Name</th>"+
	"<th style=\"padding: 0 10px 5px 0\">Pipeline Name</th>"+
	"<th style=\"padding: 0 10px 5px 0\">Stage Execution Status</th>"+
"</tr>");
builder.append("<tr>"+
	"<td style=\"padding-right: 10px\">${envCode}</td>"+
	"<td style=\"padding-right: 10px\">${relName}</td>"+
	"<td style=\"padding-right: 10px\">${pipelineName}</td>"+
	"<td style=\"padding-right: 10px\">${executionStatus}</td>"+
"</tr>");

builder.append("</table>");

// Mapping the SringBuilder content to String variable
def htmlMessage = builder.toString();

// Log will be printed in FlexDeploy log for reference
LOG.fine("Sending execution status for ${listenerName} to Teams: ${htmlMessage}" );

// Sending the message to Teams Channel
// sendTeamsMessage operation signature
// sendTeamsMessage(String pTeamsMessagingAccountCode, String pTeamName, String pChannelName, String pMessageText, String pIconURL)
// Argument desription of sendTeamsMessage operation
//   * @param pTeamsMessagingAccountCode: The messaging account code for the Teams account. 
//    									Code of Messaging Instances under Integration
//   * @param pTeamName: Name of the Microsoft Team that will receive the message.
//   * @param pChannelName: Name of the Microsoft Team Channel that the message will be sent to.
//   * @param pMessageText: The text for the message content. Can be plain text or html.
//   * @param pIconURL: The URL for the icon of the sender of the message.

MICROSOFTTEAMS.sendTeamsMessage("TEAMSTEST","Notification Team","General",htmlMessage,null);
  • Apparently, it may look like a huge /complex code, but it isn’t. Let us go through it.

    • It simply retrieves some information from the event payload and assigns it to 4 variables.

    • Then create a simple HTML table(basically String) for better clarity (not mandatory, clear text is also acceptable ).

    • Finally, use the sendTeamsMessage operation to send the message to the Teams channel.

    • A lot of code sections are just comments to give you better clarity.

  • Just to make it clear, the MessagingAccountCode is one that we have already configured under FlexDeploy integration as mentioned under Configure Messaging Integration Account

  • Once the Pipeline stage is executed, we can find the processing logs and the event payload being processed successfully by our Webhook.

  • As a result, we can find the below message in Teams Channel.

...

message to Teams Channel

MICROSOFTTEAMS.sendTeamsWebhookMessage("https://<webhook url goes here>","Title",""Message");
// or
MICROSOFTTEAMS.sendTeamsWebhookMessage("https://<webhook url goes here>",jsonVariableOfMessageCard);

Debugging execution

  • It can happen, that there could be an issue with the script. In such a scenario, navigate to the Messages page and use the actions menu to view the logs.

...

Script - Send Notification to individual users

  • Now we will send a notification to an individual user. We select the Event which will be generated whenever a Release Gets Started. The filter being used can be seen below as well.

...

  • We will try something slightly more complex here. In our Release, we have 4 Projects configured as shown below.

...

  • We want to print all project details as part of our Team message. The implementation will be similar to our previous example. We are just adding a loop to capture details for all Projects.

Code Block
languagegroovy
EVENT.payload.projects.each{ projectSet ->
  LOG.fine("Processing for Project name: ${projectSet.projectName}");
  // Retrieving individual Project Name and Project Group
  def projName = projectSet.projectName;
  def projGroupName = projectSet.groupName;
  // Below section is to form the HTML table row for each Project  
	builder.append("<tr>"+
		"<td style=\"padding-right: 10px\">${projName}</td>"+
		"<td style=\"padding-right: 10px\">${projGroupName}</td>"+
		"<td style=\"padding-right: 10px\">${pipelineName}</td>"+
		"<td style=\"padding-right: 10px\">${relName}</td>"+
	"</tr>");
}
  • In the above code, the projectSet variable is just acting as an iterator, looping through all Project objects and adding rows to the HTML table with individual Project details.

  • Below given is the entire code. This time we will use the sendUserTeamsMessage operation to send the message to specific users.

Code Block
languagegroovy
def listenerName = "Send Teams Notification on Stage Completion-EBS";
LOG.info("Running listener: ${listenerName}");

def builder = new StringBuilder();

def relName=EVENT.payload.release.releaseName
def pipelineName=EVENT.payload.pipeline.pipelineName

// Setting the Header of the message
builder.append("<h1 style=\"padding: 10px 0\">EBS-Pipeline stage execution completed.</h1>"); 

// Sending the Stage execution details in Table format
builder.append("<table border=1>");
builder.append("<tr>"+
	"<th style=\"padding: 0 10px 5px 0\">Project Name</th>"+
	"<th style=\"padding: 0 10px 5px 0\">Project Group</th>"+
	"<th style=\"padding: 0 10px 5px 0\">Pipeline Name</th>"+
	"<th style=\"padding: 0 10px 5px 0\">Release Name</th>"+
"</tr>");
// Loop through all Projects
EVENT.payload.projects.each{ projectSet ->
  LOG.fine("Processing for Project name: ${projectSet.projectName}");
  // Retrieving individual Project Name and Project Group
  def projName = projectSet.projectName;
  def projGroupName = projectSet.groupName;
  // Below section is to form the HTML table row for each Project  
	builder.append("<tr>"+
		"<td style=\"padding-right: 10px\">${projName}</td>"+
		"<td style=\"padding-right: 10px\">${projGroupName}</td>"+
		"<td style=\"padding-right: 10px\">${pipelineName}</td>"+
		"<td style=\"padding-right: 10px\">${relName}</td>"+
	"</tr>");
}
builder.append("</table>");

// Mapping the SringBuilder content to String variable
def htmlMessage = builder.toString();

// Log will be printed in FlexDeploy log for reference
LOG.fine("Sending execution status for ${listenerName} to Teams: ${htmlMessage}" );

// Sending the message to Teams user
// sendUserTeamsMessage operation signature
// sendUserTeamsMessage(String pTeamsMessagingAccountCode, String pTeamName, String pChannelName, String pMessageText, String pIconURL)
// Argument desription of sendUserTeamsMessage operation
//   * @param pTeamsMessagingAccountCode: The messaging account code for the Teams account. 
//    									Code of Messaging Instances under Integration
//   * @param pTeamName: Name of the Microsoft Team that will receive the message.
//   * @param pChannelName: Name of the Microsoft Team Channel that the message will be sent to.
//   * @param pMessageText: The text for the message content. Can be plain text or html.
//   * @param pIconURL: The URL for the icon of the sender of the message.

MICROSOFTTEAMS.sendUserTeamsMessage("TEAMSTEST","ToBeUpdated@domain.com",htmlMessage);
  • Once the Release is triggered, a message like the one shown below will be received by the user.

...

  • A similar example with the Test Results being sent to Teams can be found in the link below.

https://flexagon.atlassian.net/wiki/spaces/FD70/pages/10340172238/Sample+Webhook+Listeners#Send-Test-Results-to-Teams

Congratulations! You have successfully completed the Teams Notification Integration with FlexDeploy.

...