<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[DevOps Decoded]]></title><description><![CDATA[DevOps Engineer (Team Lead) | Entrepreneur]]></description><link>https://asitsonawane.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1696111835652/FmbykpkeC.png</url><title>DevOps Decoded</title><link>https://asitsonawane.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Sun, 01 Nov 2026 06:28:25 GMT</lastBuildDate><atom:link href="https://asitsonawane.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to send Jenkins Job Notifications with Azure Bot via Webhook on Skype]]></title><description><![CDATA[In the fast-paced world of DevOps and continuous integration, staying informed about your Jenkins job and pipeline statuses is crucial. However, drowning…]]></description><link>https://asitsonawane.hashnode.dev/how-to-send-jenkins-job-notifications-via-webhook-on-skype</link><guid isPermaLink="true">https://asitsonawane.hashnode.dev/how-to-send-jenkins-job-notifications-via-webhook-on-skype</guid><category><![CDATA[Jenkins]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Skype]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Jenkins-installation]]></category><dc:creator><![CDATA[Asit Sonawane]]></dc:creator><pubDate>Sun, 01 Oct 2023 08:20:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1696107751250/4d2202ba-7668-4469-805c-fa68ef2b2776.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the fast-paced world of <strong>DevOps</strong> and continuous integration, staying informed about your <a target="_blank" href="https://www.jenkins.io/"><strong>Jenkins</strong></a> job and pipeline statuses is crucial. However, drowning in email notifications can be overwhelming and inefficient. What if there was a smarter way to receive real-time Jenkins job updates that make your workflow smoother and more efficient?</p>
<p><mark>Why not use Jenkins plugins? The Jenkins Skype plugin already available didn't work for me as it seemed to be outdated and had not been maintained for 12 Years.</mark></p>
<p>Enter the world of <a target="_blank" href="https://azure.microsoft.com/en-in/products/bot-services"><strong>Azure Bot Service</strong></a><strong>,</strong> <a target="_blank" href="https://www.skype.com/en/"><strong>Skype</strong></a> integration, and the game-changing platform, <a target="_blank" href="http://Make.com"><strong>Make.com</strong></a>. In this blog post, we will show you how to revolutionize your Jenkins job notifications by seamlessly sending job and pipeline details directly to your Skype messages. Say goodbye to cluttered inboxes and hello to a streamlined, organized workflow.</p>
<p>By the end of this article, you'll have a comprehensive understanding of how to harness the power of <strong>Azure Bot</strong> and <a target="_blank" href="http://Make.com"><strong>Make.com</strong></a> to effortlessly connect <strong>Jenkins</strong> with <strong>Skype</strong>, ensuring you receive timely job notifications without the hassle. Let's dive in and transform the way you manage <strong>Jenkins</strong> job notifications!</p>
<hr />
<h1 id="heading-architecture">Architecture:</h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695843208767/19b9b320-9914-48e2-97db-bd1d5bb0fdf8.png" alt class="image--center mx-auto" /></p>
<p>In this architecture, it will follow the following flow:</p>
<ol>
<li><p>The Jenkins App will send a payload in the form of JSON using WebHook to the Jenkins Module on make.com.</p>
</li>
<li><p>Jenkins Module would Transfer this payload to Skype Action on make.com.</p>
</li>
<li><p>Skype Action on make.com will connect with Azure Bot Services</p>
</li>
<li><p>Finally, the JSON payload sent to Skype Action will be converted to the desired message and will be sent to the predefined receiver on Skype</p>
</li>
</ol>
<hr />
<h1 id="heading-step-1-setup-makecom">Step 1: Setup Make.com</h1>
<p>Visit <a target="_blank" href="https://www.make.com/en">https://www.make.com/en</a> and create an account:</p>
<p>Log in / Sign up on <code>make.com.</code><br /><mark>NOTE: Integromat is the older version of make.com, we want to use make.com for this integration.</mark></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695985700570/ca557c78-a104-43c9-934f-a1884e04cc03.png" alt class="image--center mx-auto" /></p>
<p>Now visit the <code>dashboard</code> and navigate to <code>scenarios</code>.</p>
<p>Now <code>create a new scenario</code> and search for <code>Jenkins module</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696011330067/a885111a-2857-4e54-9244-070e5a8fdc02.gif" alt class="image--center mx-auto" /></p>
<p>Now copy the webhook and save it somewhere like Notepad as we are going to use this in the Jenkins pipeline.</p>
<hr />
<h1 id="heading-step-2-connecting-skype-to-make-using-azure-bot">Step 2: <strong>Connecting Skype to Make using Azure Bot</strong></h1>
<p>Prerequisites</p>
<ol>
<li><p>A Skype account (create an account at <a target="_blank" href="http://skype.com">skype.com</a>)</p>
</li>
<li><p>Microsoft Azure Account (create an account at <a target="_blank" href="http://azure.microsoft.com/free">azure.microsoft.com/free</a>)</p>
</li>
</ol>
<p>To connect your Skype account to Make, you need to create a bot and obtain the Microsoft App ID and password in your Microsoft Azure account.</p>
<ol>
<li><p>Log in to your Azure Portal.</p>
</li>
<li><p>Click Create a resource.</p>
</li>
<li><p>In the top centre search bar, type bot. From the drop-down list, select Azure Bot.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696089970691/a690906d-2af0-49ff-ab79-e001f5f0c57e.png" alt class="image--center mx-auto" /></p>
<ol>
<li>Click the Create button.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696089998095/144081f3-2761-4116-878e-7eceec9ab7c8.png" alt class="image--center mx-auto" /></p>
<ol>
<li>In the Azure Bot form, provide the required information about your bot, as follows:</li>
</ol>
<table><tbody><tr><td><p><strong>Bot handle</strong></p></td><td><p>Enter the name of your bot.</p></td></tr><tr><td><p><strong>Subscription</strong></p></td><td><p>Select the Azure subscription you want to use.</p></td></tr><tr><td><p><strong>Resource Group</strong></p></td><td><p>Create a new <a target="_blank" class="link" href="https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-overview#resource-groups">resource group</a>, or select an existing one.</p></td></tr><tr><td><p><strong>Location</strong></p></td><td><p>Choose the geographic location for your resource group. It's usually best to choose a location close to you.</p></td></tr><tr><td><p><strong>Pricing Tier</strong></p></td><td><p>Select a pricing tier. You may update the pricing tier at any time. For more information, see <a target="_blank" class="link" href="https://azure.microsoft.com/pricing/details/bot-service/">Bot Service pricing</a>.</p></td></tr><tr><td><p><strong>Type of App</strong></p></td><td><p>Select <em>Multi Tenant</em> from the drop-down.</p></td></tr><tr><td><p><strong>Creation type</strong></p></td><td><p>Create a new Microsoft App ID.</p></td></tr></tbody></table>

<ol>
<li><p>Click Review + Create. When Microsoft successfully validates the new bot, click Create.</p>
</li>
<li><p>Go to the new resource and open Channels.</p>
</li>
<li><p>Choose Skype and configure the app. Optionally, you can also configure the other settings in the dialog box, e.g., Disable adding of bot to group conversations option in the Groups tab. Close channel settings.</p>
</li>
<li><p>Click Add to Skype in the Connected Channels list, and add the bot to your Skype contacts.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696090147329/25387f7f-7a67-4ded-a295-35ee33b157e3.gif" alt class="image--center mx-auto" /></p>
<ol>
<li><p>Open Configuration, where you will find the Microsoft App ID.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696090191817/72e425f5-f0b9-48bc-899f-fbe85966eb2d.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Click Manage &gt; + New client secret to create a password.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696090212335/1560bfbd-098c-4392-b683-74ac2112303d.gif" alt class="image--center mx-auto" /></p>
</li>
<li><p>Copy the password now.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696090224726/12abb347-459e-4dd8-98fd-a7f8ca429728.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Go to Make, and open the Skype module's Create a connection dialog. Click Add.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696090520515/47b8fcd8-93d7-4b2a-ae29-6a328f8a1db2.gif" alt class="image--center mx-auto" /></p>
</li>
<li><p>Enter the Microsoft App ID (see step 9 above) and Password (see step 11 above) in the respective fields, and click the Continue button to establish the connection.</p>
</li>
<li><p>The connection has been established. You can proceed with setting up the module.</p>
</li>
<li><p>Now you need a conversation ID:</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696091418561/a1c219c4-8d9b-4821-bade-0448ed424eaf.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>To get a conversation ID we can use Skype's web application and inspect the networks:</p>
<ol>
<li><p>Login to your Web Skype using Chrome,</p>
</li>
<li><p>press F12 to open the developer tool,</p>
</li>
<li><p>switch to the "Network" tab, then send some messages in the chat group you need to know the ID,</p>
</li>
</ol>
</li>
</ol>
<pre><code class="lang-plaintext">Request URL: https://client-s.gateway.messenger.live.com/v1/users/ME/conversations/19%3Axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%40thread.skype/messages?x-ecs-etag=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx....
</code></pre>
<p>after "conversations" in the path, "<code>19:xxxxxxxxxxxxxxxxxxxxx...@</code><a target="_blank" href="http://thread.skype"><code>thread.skype</code></a>" is the chat group id as you want. (<code>%3A</code> is <code>:</code>, <code>%40</code> is <code>@</code>)<br />Replace the required things in the id and put it in the "<code>Conversation ID</code>" in make.com's Skype module.</p>
<p>And Save your scenario. We will get back to make.com later.</p>
<hr />
<h1 id="heading-step-3-install-and-use-docker-on-ubuntu-2204">Step 3: Install and Use Docker on Ubuntu 22.04</h1>
<p>For Detail steps, you can also visit <a target="_blank" href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04"><strong>this</strong></a> tutorial from Digital Ocean.</p>
<p>If you already have docker installed, you can skip to step 2</p>
<h3 id="heading-step-31-installing-docker">Step 3.1 — Installing Docker</h3>
<p>To guarantee we install the most up-to-date version of Docker, we won't rely on the Docker installation package provided in the standard Ubuntu repository. Instead, we'll opt for the official Docker repository. This involves adding a new package source, importing the Docker GPG key for download verification, and subsequently installing the package.</p>
<p>Start by refreshing your current list of packages with the following command:</p>
<pre><code class="lang-bash">sudo apt update
</code></pre>
<p>Next, install a few prerequisite packages that let <code>apt</code> use packages over HTTPS:</p>
<pre><code class="lang-bash">sudo apt install apt-transport-https ca-certificates curl software-properties-common
</code></pre>
<p>Then add the GPG key for the official Docker repository to your system:</p>
<pre><code class="lang-bash">curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
</code></pre>
<p>Add the Docker repository to APT sources:</p>
<pre><code class="lang-bash">sudo add-apt-repository <span class="hljs-string">"deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"</span>
</code></pre>
<p>This will also update our package database with the Docker packages from the newly added repo.</p>
<p>Make sure you are about to install from the Docker repo instead of the default Ubuntu repo:</p>
<pre><code class="lang-bash">apt-cache policy docker-ce
</code></pre>
<p>You’ll see output like this, although the version number for Docker may be different:</p>
<pre><code class="lang-plaintext">docker-ce:
  Installed: (none)
  Candidate: 5:24.0.6-1~ubuntu.20.04~focal
  Version table:
     5:19.03.9~3-0~ubuntu-focal 500
        500 https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
</code></pre>
<p>Notice that <code>docker-ce</code> is not installed, but the candidate for installation is from the Docker repository for Ubuntu 20.04 (<code>focal</code>).</p>
<p>Finally, install Docker:</p>
<pre><code class="lang-bash">sudo apt install docker-ce
</code></pre>
<p>Docker should now be installed, the daemon started, and the process enabled to start on boot. Check that it’s running:</p>
<pre><code class="lang-bash">sudo systemctl status docker
</code></pre>
<p>The output should be similar to the following, showing that the service is active and running:</p>
<pre><code class="lang-bash">● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2023-09-28 22:29:20 UTC; 8h ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 513 (dockerd)
      Tasks: 42
     Memory: 72.3M
        CPU: 15.769s
     CGroup: /system.slice/docker.service
             ├─ 513 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
</code></pre>
<p>Installing Docker now gives you not just the Docker service (daemon) but also the <code>docker</code> command line utility, or the Docker client.</p>
<h3 id="heading-step-32-executing-the-docker-command-without-sudo-optional">Step 3.2 — Executing the Docker Command Without Sudo (Optional)</h3>
<p>By default, the <code>docker</code> command can only be run by the <strong>root</strong> user or by a user in the <strong>docker</strong> group, which is automatically created during Docker’s installation process. If you attempt to run the <code>docker</code> command without prefixing it with <code>sudo</code> or without being in the <strong>docker</strong> group, you’ll get an output like this:</p>
<pre><code class="lang-bash">Outputdocker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.
See <span class="hljs-string">'docker run --help'</span>.
</code></pre>
<p>If you want to avoid typing <code>sudo</code> whenever you run the <code>docker</code> command, add your username to the <code>docker</code> group:</p>
<pre><code class="lang-bash">sudo usermod -aG docker <span class="hljs-variable">${USER}</span>
</code></pre>
<p>To apply for the new group membership, log out of the server and back in, or type the following:</p>
<pre><code class="lang-bash">su - <span class="hljs-variable">${USER}</span>
</code></pre>
<p>You will be prompted to enter your user’s password to continue.</p>
<p>Confirm that your user is now added to the <strong>docker</strong> group by typing:</p>
<pre><code class="lang-bash">groups
</code></pre>
<p>If you need to add a user to the <code>docker</code> group that you’ve not logged in as declare that username explicitly using:</p>
<pre><code class="lang-bash">sudo usermod -aG docker username
</code></pre>
<p>The rest of this article assumes you are running the <code>docker</code> command as a user in the <strong>docker</strong> group. If you choose not to, please prepend the commands with <code>sudo</code>.</p>
<p>Let’s explore the <code>docker</code> command next.</p>
<hr />
<h1 id="heading-step-4-setup-jenkins-we-will-be-using-docker">Step 4: Setup Jenkins (we will be using Docker)</h1>
<p>Visit tags from <code>jenkins/jenkins</code> repository on Docker Hub: <a target="_blank" href="https://hub.docker.com/r/jenkins/jenkins/tags">https://hub.docker.com/r/jenkins/jenkins/tags</a></p>
<p>I want to use the latest Long-Term Support (LTS) version of Jenkins so I will search LTS on the "Filter Tags" option.</p>
<p><strong><mark>Check the compatibility of OS/ARCH with your VM/PC's OS/ARCH</mark></strong></p>
<p>I am using Linux ubuntu OS with amd64 architecture on AWS. So I will pull the following docker image.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695941717843/05dc96d4-60f1-4acd-8a53-504474c325c8.png" alt class="image--center mx-auto" /></p>
<p>To run the docker, I am using the following command in my ubuntu terminal:</p>
<pre><code class="lang-plaintext">docker run -d --name jenkins -p 8080:8080 -p 50000:50000 -v jenkins_home:/var/jenkins_home --restart=unless-stopped jenkins/jenkins:2.414.2-lts-jdk11
</code></pre>
<p>Let's break down the command step by step:</p>
<ol>
<li><p><code>docker run</code>: This is the command used to create and start a Docker container.</p>
</li>
<li><p><code>-d</code>: This flag stands for "detached" mode, which means the container will run in the background. You won't see the container's output in your terminal unless you explicitly view the logs.</p>
</li>
<li><p><code>--name jenkins</code>: This flag assigns the name "jenkins" to the container. You can use this name to manage the container later.</p>
</li>
<li><p><code>-p 8080:8080</code>: This flag specifies port mapping. It maps port 8080 from your host machine to port 8080 within the container. This is typically the port where the Jenkins web interface will be accessible.</p>
</li>
<li><p><code>-p 50000:50000</code>: This flag also specifies port mapping. It maps port 50000 from your host machine to port 50000 within the container. Port 50000 is used for Jenkins agent communication.</p>
</li>
<li><p><code>-v jenkins_home:/var/jenkins_home</code>: This flag defines volume mapping. It maps a Docker volume named "jenkins_home" to the "/var/jenkins_home" directory within the container. This is done to persistently store Jenkins data and configurations, allowing you to retain your Jenkins data even if the container is stopped or removed.</p>
</li>
<li><p><code>--restart=unless-stopped</code>: This flag instructs Docker to automatically restart the container unless it is explicitly stopped by the user. This ensures that Jenkins will automatically restart if the host machine is rebooted or if the Docker daemon is restarted.</p>
</li>
<li><p><code>jenkins/jenkins:2.414.2-lts-jdk11</code>: This is the Docker image you want to use for the Jenkins container. It specifies the image name along with a tag. In this case, it's using the Jenkins LTS (Long-Term Support) image version 2.414.2 with Java 11 (JDK11).</p>
</li>
</ol>
<p>This Docker command creates a Jenkins container with specific port mappings for web access and agent communication, sets up a persistent volume for Jenkins data, and configures the container to restart automatically unless explicitly stopped. It uses the Jenkins LTS image with JDK 11 as the base image for the container.</p>
<p>Now make sure you have added inbound access to port 8080 on your virtual machine from the Security Group.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695942441787/a8958193-d23a-49d8-bcc9-92d9513f290d.png" alt class="image--center mx-auto" /></p>
<p>Now check if you can access the Jenkins Application through <code>http://ipaddress:8080</code></p>
<p>Make sure you replace <code>ipaddress</code> with your VM's public IPv4 if you are running this project on a VM.</p>
<p>Considering that your Jenkins container is running, to set up Jenkins we will need to visit <code>ipaddress:8080</code>.</p>
<p>Here you will notice it is asking to Unlock Jenkins using an Administrator password.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695942870693/74fa1140-5291-49ef-a018-dada5c1ec057.png" alt class="image--center mx-auto" /></p>
<p>To get this Administrator password, we will now visit the Jenkins app and connect with Jenkins Container's shell using the following command:</p>
<pre><code class="lang-bash">docker <span class="hljs-built_in">exec</span> -it jenkins sh
</code></pre>
<p>This code uses the Docker command "<code>docker exec</code>" to run an interactive shell ("sh") inside a Docker container named "<code>jenkins</code>." It allows you to access and interact with the operating system within the "<code>jenkins</code>" container.</p>
<p>Use the following command to get the password:</p>
<pre><code class="lang-bash">cat /var/jenkins_home/secrets/initialAdminPassword
output:
df9946643XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcaeabccc
</code></pre>
<p>Copy and use this password to unlock your Jenkins.</p>
<p>Now we will set up Jenkins, and for that, you need to install plugins, for the sake of this project we will go ahead with "Install Suggested Plugins".</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695969129603/ae939c5e-3988-4425-a103-ffbe137a7b9b.png" alt class="image--center mx-auto" /></p>
<p>Once it is installed, you will be prompted to create the first admin user.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695985321527/c7693108-77d0-4c7b-9e47-56c2a00cf8c3.png" alt class="image--center mx-auto" /></p>
<p>Input all the necessary details and then click on save and continue.</p>
<p>Now let's create a <code>pipeline</code> job and name it <code>Jenkins-Skype</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695985460615/9a51fe23-4632-4bba-8f14-ba412bc8d873.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695985497460/99f1bcf1-3ad2-4cbd-b4e5-eea203980081.png" alt class="image--center mx-auto" /></p>
<p>For now, we will just create and save it as it is and come back to it later in this blog.</p>
<hr />
<h1 id="heading-step-6-writing-jenkins-pipeline-script">Step 6: Writing Jenkins pipeline script.</h1>
<p>For this project, we will create a pipeline that just prints <code>"Pipeline Running"</code></p>
<p>But before that, we need to make a few changes to our Jenkins.</p>
<p>We will be needing a plugin called <a target="_blank" href="https://plugins.jenkins.io/http_request/"><code>HTTP Request</code></a> plugin.</p>
<p>Go to <code>Dashboard &gt; Manage Jenkins &gt; Plugins</code>, click on <code>Available plugins</code> and then search <code>HTTP Request</code> and install the plugin.</p>
<p>Then we will select the option to <code>restart Jenkins</code>.</p>
<p>This plugin will help us in our script to send webhook payload</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696014141567/d272122b-de7b-4995-97c9-9f6f60096256.gif" alt class="image--center mx-auto" /></p>
<p>Now go to your Jenkins PIPELINE and enter the following script. This script has code that:</p>
<p>1. Sends Notification when the pipeline has started<br />2. It will print "Pipeline Running"<br />3. Sends Notification when the pipeline has finished</p>
<pre><code class="lang-java">def FAILED_STAGE = <span class="hljs-keyword">null</span> <span class="hljs-comment">// Define the variable at the beginning of the script</span>

pipeline {

    agent any

    environment {

        webhookUrl = <span class="hljs-string">'https://hook.eu2.make.com/XXXXXXXXXXX'</span> <span class="hljs-comment">// Enter your webhook from make.com</span>
        pipelineName = <span class="hljs-string">'jenkins-skype'</span> <span class="hljs-comment">// Define Pipeline's name for notification</span>

    }

    stages {

        stage(<span class="hljs-string">'Send Notification'</span>) {
            steps {
                catchError(buildResult: <span class="hljs-string">'SUCCESS'</span>, stageResult: <span class="hljs-string">'FAILURE'</span>) {
                    script {
                        FAILED_STAGE = env.STAGE_NAME <span class="hljs-comment">// Set the stage name</span>

                        <span class="hljs-comment">// Define variables for post-build notification message</span>
                        def buildStatus = <span class="hljs-string">"Started"</span>
                        def istTimeZone = TimeZone.getTimeZone(<span class="hljs-string">"Asia/Kolkata"</span>)

                        def buildTimestampStart = System.currentTimeMillis()
                        def formattedTimestampStart = <span class="hljs-keyword">new</span> Date(buildTimestampStart).format(<span class="hljs-string">"hh:mm a"</span>, istTimeZone)

                        <span class="hljs-comment">//Define Payload for sending through webhook</span>
                        def payload = <span class="hljs-string">""</span><span class="hljs-string">"
                            {
                                "</span>pipelineName<span class="hljs-string">": "</span>&lt;b&gt;Pipeline:&lt;/b&gt; ${pipelineName}<span class="hljs-string">",
                                "</span>buildTimestampStart<span class="hljs-string">": "</span>&lt;b&gt;Start Time:&lt;/b&gt; ${formattedTimestampStart}<span class="hljs-string">",
                                "</span>buildStatus<span class="hljs-string">": "</span>&lt;b&gt;Status:&lt;/b&gt; ${buildStatus}&lt;span&gt; &amp;#<span class="hljs-number">9203</span>; &lt;/span&gt;<span class="hljs-string">"
                            }
                            "</span><span class="hljs-string">""</span>

                        <span class="hljs-comment">// Send notification to the webhook</span>
                        def response = httpRequest(
                            url: webhookUrl,
                            httpMode: <span class="hljs-string">'POST'</span>,
                            requestBody: payload,
                            contentType: <span class="hljs-string">'APPLICATION_JSON'</span>
                        )

                        <span class="hljs-comment">// Print this if sending response if failed</span>
                        <span class="hljs-keyword">if</span> (response.status != <span class="hljs-number">200</span>) {
                            error <span class="hljs-string">"Failed to send notification to the webhook. HTTP Status: ${response.status}"</span>
                        }
                    }
                }
            }
        }


        stage(<span class="hljs-string">'Upgrade and Update'</span>) {

            steps {

                script {

                    FAILED_STAGE = env.STAGE_NAME
                    echo <span class="hljs-string">"Update and upgrade completed"</span>
                }
            }
        }
    }

    post {

        always {

            script {

                def buildStatus = currentBuild.resultIsBetterOrEqualTo(<span class="hljs-string">"SUCCESS"</span>) ? <span class="hljs-string">"Completed &lt;span&gt;&amp;#127881;&lt;/span&gt;"</span> : <span class="hljs-string">"Failed &lt;span&gt; &amp;#10060; &lt;/span&gt;"</span>
                def istTimeZone = TimeZone.getTimeZone(<span class="hljs-string">"Asia/Kolkata"</span>)

                def buildTimestampEnd = System.currentTimeMillis()
                def formattedTimestampEnd = <span class="hljs-keyword">new</span> Date(buildTimestampEnd).format(<span class="hljs-string">"hh:mm a"</span>, istTimeZone)

                def durationMillis = currentBuild.duration

                def secondsBigDecimal = <span class="hljs-keyword">new</span> BigDecimal(durationMillis).divide(<span class="hljs-keyword">new</span> BigDecimal(<span class="hljs-number">1000</span>)).setScale(<span class="hljs-number">2</span>, BigDecimal.ROUND_HALF_UP) <span class="hljs-comment">// Convert milliseconds to seconds with two decimal places</span>
                def finalDuration = (secondsBigDecimal / <span class="hljs-number">60</span>)
                def formattedDuration = String.format(<span class="hljs-string">"%.2f mins"</span>, finalDuration)

                def FAILED_STAGE_Deets = currentBuild.resultIsBetterOrEqualTo(<span class="hljs-string">"SUCCESS"</span>) ? <span class="hljs-keyword">null</span> : FAILED_STAGE

                <span class="hljs-comment">//Define Payload for sending through webhook</span>
                def payload = <span class="hljs-string">""</span><span class="hljs-string">"
                {
                    "</span>pipelineName<span class="hljs-string">": "</span>Pipeline: ${pipelineName}<span class="hljs-string">",
                    "</span>buildTimestampEnd<span class="hljs-string">": "</span>End Time: ${formattedTimestampEnd}<span class="hljs-string">",
                    "</span>buildStatus<span class="hljs-string">": "</span>Status: ${buildStatus}<span class="hljs-string">",
                    "</span>buildDuration<span class="hljs-string">": "</span>Duration: ${formattedDuration}<span class="hljs-string">",
                    "</span>failedStage<span class="hljs-string">": "</span>Failed Stage: ${FAILED_STAGE_Deets}<span class="hljs-string">"
                }
                "</span><span class="hljs-string">""</span>

                <span class="hljs-comment">// Send notification to the webhook</span>
                def response = httpRequest(
                    url: webhookUrl,
                    httpMode: <span class="hljs-string">'POST'</span>,
                    requestBody: payload,
                    contentType: <span class="hljs-string">'APPLICATION_JSON'</span>
                )

                <span class="hljs-comment">// Print this if sending response if failed</span>
                <span class="hljs-keyword">if</span> (response.status != <span class="hljs-number">200</span>) {
                    error <span class="hljs-string">"Failed to send notification to the webhook. HTTP Status: ${response.status}"</span>
                }
            }
        }
    }
}
</code></pre>
<p><mark>CHANGE THE WEBHOOK URL TO THE URL FROM MAKE.COM</mark></p>
<p>Insert this script into your Jenkins pipeline's <code>Script</code> section at the end of the configuration page and click on save:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696015296001/9483a0a5-ef0b-4fb3-83a7-6aba7bfa1466.png" alt class="image--center mx-auto" /></p>
<p>You will notice the pipeline didn't run. This is because Multiple scripts are not permitted to be used.</p>
<p>To fix "<code>Scripts not permitted to use new java.math.BigDecimal int</code>" click on <code>X</code> shown in the image below to check the console output and search for <code>Scripts not permitted</code></p>
<p>Then click on <code>Administrators can decide whether to approve or reject this signature.</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696093474988/1837e8a6-7bde-47f3-b281-0ab628c76d69.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696015909097/b8d5bf67-76ec-499f-a552-4faf372e9594.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696015916710/23dd30a4-aa18-4a35-9bdb-deb1b44d7619.png" alt class="image--center mx-auto" /></p>
<p><mark>Repeat this step multiple times until you do not see this error anymore.</mark></p>
<p>You will end up with the following lines in the "<code>Signatures Already Approved</code>" section:</p>
<pre><code class="lang-plaintext">method java.math.BigDecimal divide java.math.BigDecimal
method java.math.BigDecimal setScale int int
new java.math.BigDecimal int
staticField java.math.BigDecimal ROUND_HALF_UP
</code></pre>
<p>Once you have added all these, go to make.com and click on run.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696093257207/f84914ec-910d-4f33-ba5d-c736c04adbfb.png" alt class="image--center mx-auto" /></p>
<p>Go back to Jenkins and build the pipeline, now the Jenkins module should've received payload from the Jenkins application. Now we need to add the variables in Skype.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696095155941/dc102db1-df96-466d-bb12-025d2bd733df.gif" alt class="image--center mx-auto" /></p>
<p>Once this is done, save the scenario and start the scenario.</p>
<p>Then try running your Jenkins pipeline, you will receive a message on Skype regarding your pipeline status.</p>
<hr />
<h1 id="heading-conclusion">Conclusion</h1>
<p>We have used containerized Jenkins with Make.com, Skype and Azure bot to send pipeline status notifications using webhooks.</p>
<hr />
<h1 id="heading-resources">Resources</h1>
<p>Here are the list of resources that would help you follow along:</p>
<ol>
<li><p><a target="_blank" href="https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04">How To Install and Use Docker on Ubuntu 20.04</a></p>
</li>
<li><p><a target="_blank" href="https://www.jenkins.io/doc/tutorials/">Introduction To Jenkins</a></p>
</li>
<li><p><a target="_blank" href="https://www.make.com/en/help/app/skype">Getting Started With Skype and Make.com</a></p>
</li>
</ol>
<hr />
<h1 id="heading-connect-with-me">Connect With Me:</h1>
<p><a target="_blank" href="https://www.linkedin.com/in/asit-sonawane/">LinkedIn</a><br /><a target="_blank" href="https://twitter.com/asitsonawane20">GitHub</a><br /><a target="_blank" href="https://www.instagram.com/asit_sonawane/">Instagram</a><br /><a target="_blank" href="https://github.com/asitsonawane">Twitter (X)</a></p>
]]></content:encoded></item></channel></rss>