Integrating TeamCity with Slack.com using WebHooks

Posted on Updated on

Here is a quick example of how to integrate slack.com with TeamCity using the tcWebHooks plugin.

Messages posted to Slack.com from TeamCity using the tcWebHooks plugin.
Messages posted to Slack.com from TeamCity using the tcWebHooks plugin.

The first three messages were posted using the first example XML configuration below. The last two are more elaborate and utilise the second XML snippet.

Step by step

  1. Create a new integration in Slack by going to the “Integrations” page.
  2. Scroll to near the bottom and click on the “Incoming WebHooks” button.
  3. Choose a channel to post into and click “Add incoming webhook”. A new integration should be created.
  4. Find the section entitled “Your Unique Webhook URL” copy the URL underneath it including the Token at the end.
  5. Switch to your teamcity web page and create a new WebHook.
  6. Paste in the webhook URL from step 4 into the webhook config.
  7. Choose Name Value Pairs payload format and select your trigger events. I suggest only selecting Successful and Failed. Otherwise you will fill your Slack channel with too many events. You may only want to choose when a build changes state to further reduce noise.
  8. After you’ve saved your webhook config, you need to add the Slack specific payload options by editing the WebHooks configuration file on the TeamCity server. In TeamCity 8 it will be located at: $HOME/.BuildServer/config/projects/<your_project_name>/pluginData/plugin-settings.xml
  9. Find your newly created WebHook and add the following block of XML before the </webhook> tag.
<parameters>
    <param name="payload" value="{&quot;text&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;}"/>
</parameters>

The above XML snippet shows a simple message. Below is a more sophisticated example showing the use of the attachment JSON field to show a coloured bar and heading text on the message.

<parameters>
   <param name="payload" value="{  &quot;text&quot;: &quot;All your build failures are belong to us&quot;, &quot;attachments&quot;: [ { &quot;fallback&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;, &quot;text&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;, &quot;color&quot;: &quot;danger&quot; } ] }"/>
</parameters>

A more complete example

This shows two full webhook XML configurations so you can see the parameter tag in context. If you look closely, you’ll see the first one only applies to build failures, and the second one only applies to build success messages. That is how you can display a different colour and message for different build results.

<?xml version="1.0" encoding="UTF-8"?>
<settings>
  <webhooks enabled="true">
     <webhook url="https://<your_slack_url>.slack.com/services/hooks/incoming-webhook?token=<your_token_here>" enabled="true" format="nvpairs">
      <states>
        <state type="buildSuccessful" enabled="false" />
        <state type="buildInterrupted" enabled="false" />
        <state type="responsibilityChanged" enabled="false" />
        <state type="buildStarted" enabled="false" />
        <state type="buildFailed" enabled="true" />
        <state type="beforeBuildFinish" enabled="false" />
        <state type="buildFixed" enabled="false" />
        <state type="buildFinished" enabled="true" />
        <state type="buildBroken" enabled="false" />
      </states>
      <build-types enabled-for-all="true" enabled-for-subprojects="true" />
      <parameters>
        <param name="payload" value="{  &quot;text&quot;: &quot;All your build failures are belong to us&quot;, &quot;attachments&quot;: [ { &quot;fallback&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;, &quot;text&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;, &quot;color&quot;: &quot;danger&quot; } ] }"/>
      </parameters>
    </webhook>
    <webhook url="https://<your_slack_url>.slack.com/services/hooks/incoming-webhook?token=<your_token_here>" enabled="true" format="nvpairs">
      <states>
        <state type="buildSuccessful" enabled="true" />
        <state type="buildInterrupted" enabled="false" />
        <state type="responsibilityChanged" enabled="false" />
        <state type="buildStarted" enabled="false" />
        <state type="buildFailed" enabled="false" />
        <state type="beforeBuildFinish" enabled="false" />
        <state type="buildFixed" enabled="false" />
        <state type="buildFinished" enabled="true" />
        <state type="buildBroken" enabled="false" />
      </states>
      <build-types enabled-for-all="true" enabled-for-subprojects="true" />
      <parameters>
        <param name="payload" value="{  &quot;text&quot;: &quot;All your build successes should to be celebrated&quot;, &quot;attachments&quot;: [ { &quot;fallback&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;, &quot;text&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;, &quot;color&quot;: &quot;good&quot; } ] }"/>
      </parameters>
    </webhook>
  </webhooks>
</settings>

There is a full list of the variables available.

Advertisements

14 thoughts on “Integrating TeamCity with Slack.com using WebHooks

    Arjan van Wijk said:
    September 23, 2014 at 10:50

    Hi, I’m trying to do the same thing for the Hipchat v2 api, but I’m not sure if I can use the tcWebhook to accomplish this, as the v1 api uses a different method than the v2 api.

    When using the plugin, nothing happens, so it’s kind of a black box 🙂
    I’m getting this error back from HipChat when trying a manual post:
    The request requires a JSON-encoded body with the ‘content-type’ header set to ‘application/json’

    When I send a request from Postman with the correct content-type header and this raw body, it works:
    {“message”: “%{object}: %{title}%{action} by %{author} (%{branch})”, “message_format”: “html”, “color” : “gray”}

    Could you tell me if this is supported in the plugin, and if not, are there any plans to? 🙂

    Thanks in advance!

    post said:
    October 8, 2014 at 12:18

    Where does the proxy configuration go?

    David R. said:
    November 24, 2014 at 05:05

    I just set this up, it works great! Thanks for putting it together. Have you given any thought to creating the reciprocal to kick a build off from slack via an outbound webhook?

      netwolfuk responded:
      November 24, 2014 at 06:50

      There is a web service api in TeamCity and depending on what options there are in slack it might be possible to setup a trigger in slack somehow. Sorry, but I’ve not looked into it.

    Brian Lopez (@thebrianlopez) said:
    October 16, 2015 at 15:35

    Thanks, this helped me.

    Hartmut M. said:
    March 4, 2016 at 12:30

    How can I inject other parameters that come from TeamCity build into the slack’s payload value? For instance, regarding teamcity.projectName, I discovered that I could not use this directly within the value…
    Thanks in advance

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s