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 notification notifications to Microsoft Teams based on certain Release/Pipeline milestone milestones being achieved.  The tutorial will include:

...

  • Configure Messaging Integration Account in FlexDeployConfigure FlexDeploy Webhooks to send message to Teams

Configure credentials in Azure

We would need to perform 3 primary activities,

  • One valid regular Azure user without MFA enabled. Preferably create a dedicated user account for the same.

  • A Service Principal(Azure Application), which will send the messages to the 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 below link on how to configure Service Principal(Azure Application) and provide relevant permissions.

https://flexagon.atlassian.net/wiki/spaces/FD65/pages/10125823470/Configuring+FlexDeploy+for+Teams+Operations+using+User+Credentials

  • Just for information: During execution both user and Azure Application credential is used internally to generate OAuth token which is used for authorization.

Configure

...

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

...

a

...

FlexDeploy

...

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

...

  • In case for any failure please check FlexDeploy log 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 straight forwardstraightforward.

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

https://flexagon.atlassian.net/wiki/spaces/FD65/pages/10125814470/Getting + Started + with + Outgoing + Webhooks

  • Basically, there are two parts of to a Webhook,

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

    • Groovy Script – This script which is responsible to send for sending the Teams Notification.

  • Lets Let's understand in a bit more detailsdetail. Below are some of the FlexDeploy events which that can trigger a Webhook.

...

  • The complete list of available events can be found in the link below
    Events

...

Filter

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

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

...

Code Block
languagegroovy
if(EVENT.payload.environment.environmentCode.equals("DEV")  && 
  && EVENT.payload.pipeline.pipelineName.equals("Teams_Dummy_Pipeline"))    {
    return true;
  
}   else else{
 
  return false;
   }
  • It’s evident from the logic that we want the Webhook to be triggered only when the Pipeline being executed is - Teams_Dummy_Pipeline and the Stage executed/Environment code is DEV

  • Now the obvious question which that will arise is, where exactly are we getting the EVENT.payload object.

  • As mentioned in the earlier step, events get generated under certain conditions only. Tthey They do get generated as a JSON payload with relevant details, it’s processed by Webhook Listener.

...

  • You can get a detailed structure of the payload for each event from the below link.

...

  • Events

  • Navigate to View the Messages under Outgoing Webhook Listeners.

    Image Removed

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

...

  • You can find the actual event message payload details and any available logs from the processing of the event here.

...

...

If this is your first time and you are still confused with the idea of the payload, you can start by creating Webhook without a filter.

...

You will still be able to view the Event payloads. However

...

, it is strongly recommended to always use some filtering in real-life scenarios.

Script - Send notification to Teams Channel

  • Using the same approach, evaluating the payload we can easily write our groovy script.

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

// SettingSending 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 formTeams theChannel
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. Lets go through it.

    • It’ simply retrieving some information from event payload and assigning it to 4 variables.

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

    • At last using sendTeamsMessage operation to send the message to Teams channel.

    • Lot of code section are just comments to give you better clarity.

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

  • Now once the Pipeline stage got executed, we can find below Message being processed successfully by our Webhook.

...

  • As a result we can find below message in 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 Outgoing Webhook Listener --> View Messages and Filter out your Webhook Listener as shown below.

  • Then select the failed one and check select the View Logs option to get clarity on where exactly it got failed.

...

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.

...

  • We provide the Filter as given below.

...

  • We would 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 Teams message. Below given is the generated event payload with 4 Project details.

...

  • The implementation will be similar. 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>");
}
  • On above code, ProjectSet 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 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 below message will be received by the user.

...

  • Another similar reference with Test Result given in below link

...

  • Messages page and use the actions menu to view the logs.

...

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

...