Turn Gitter Messages into CI Triggers with Webhooks – A Jenkins Example
Learn how to configure Gitter webhooks to automatically fire Jenkins builds when a chat message arrives. Step‑by‑step guide, example payload, and best‑practice checklist.
27 Mar 2026, 23:55 UTC

Why You Should Automate Chat‑Triggered Builds
Teams that use Gitter for day‑to‑day communication often need to kick off continuous‑integration (CI) pipelines when a specific message is posted. Relying on a human to remember to click a button in Jenkins or to run a curl command introduces friction and the possibility of missed builds. Webhooks give you a reliable, low‑latency channel: every time a message appears, Gitter pushes a JSON payload to a URL you control, and the external system can react immediately.
What a Gitter Webhook Is
A webhook in Gitter is an HTTPS endpoint that receives a POST request whenever a subscribed event occurs in a room. The request body is a JSON object that contains the message text, the author, timestamps, and room metadata. Gitter only sends the payload if the endpoint responds with a 200‑series status code; otherwise the message is retried up to three times.
Setting Up a Webhook in a Gitter Room
- Open the room settings. In the Gitter web UI, click the gear icon in the top‑right corner of the room.
- Navigate to the Webhooks tab. If you don’t see it, you need to be a room admin.
- Add a new webhook. Paste the target URL (for example
https://ci.example.com/gitter-webhook) and give the webhook a descriptive name like "Jenkins Trigger". - Select events. For a CI trigger you’ll typically choose
message.created. You can also filter byroom.idoruser.idif the room has many participants. - Click
Saveand note theWebhook IDthat appears. Gitter uses this ID in theX-Gitter-Webhook-Idheader of every request.
During the first run, Gitter will send a test payload to your endpoint. If your server is reachable over the public internet and responds with 200, the webhook is considered active.
Example: Triggering a Jenkins Build
Below is a minimal example that shows how to receive the webhook in Jenkins, detect a keyword, and start a build. The example assumes you have Jenkins 2.x or newer with the Pipeline: REST API plugin installed.
1. Create a Jenkins Job that Exposes a REST Endpoint
# In Jenkins, create a freestyle project named "Deploy from Gitter"
# Add a Build Trigger: "Trigger builds remotely (e.g., from scripts)"
# Set the Authentication Token to "gitter-trigger-123"
# Add a Build Step: Execute shell
# echo "Build triggered by Gitter"
# Save the job.
Once the job is created, Jenkins will expose an endpoint at https://jenkins.example.com/job/Deploy%20from%20Gitter/build?token=gitter-trigger-123. This URL will be used by the webhook listener.
2. Deploy a Simple Listener Service
You can use any language that can accept HTTPS POSTs. The following example uses Python/Flask for brevity.
from flask import Flask, request, abort
import requests
app = Flask(__name__)
# Replace with your real Jenkins URL and token
JENKINS_URL = "https://jenkins.example.com/job/Deploy%20from%20Gitter/build"
TOKEN = "gitter-trigger-123"
@app.route("/gitter-webhook", methods=["POST"])
def gitter_webhook():
data = request.get_json()
if not data:
abort(400, "Invalid JSON payload")
# Quick sanity check: only act on message.created
if data.get("type") != "message.created":
return "Ignored", 200
message = data.get("message", {}).get("text", "")
# Trigger only if the message contains the keyword "deploy"
if "deploy" in message.lower():
# Build Jenkins job via REST API
resp = requests.post(
f"{JENKINS_URL}?token={TOKEN}",
headers={"Content-Type": "application/json"},
)
if resp.status_code == 201:
return "Build started", 200
else:
return f"Jenkins error: {resp.status_code}", 500
return "No trigger keyword", 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=443, ssl_context=("cert.pem", "key.pem"))
Deploy this service behind a TLS termination point (e.g., Nginx or a managed HTTPS endpoint). Gitter will only send the payload if the endpoint responds with a 200‑series code, so make sure your certificate is valid and the domain resolves publicly.
3. Verify the Flow
- In the Gitter room, send a message that includes the word
deploy. - Check the listener logs – you should see a POST request and a message like "Build started".
- Confirm that Jenkins shows a new build in the job queue.
- In the Gitter room settings, open the Webhooks tab and verify that the last status is 200.
Security & Rate‑Limiting Trade‑offs
Webhooks expose your internal services over the public internet. Avoid the following pitfalls:
- Use HTTPS only. Gitter will reject any non‑TLS endpoint.
- Verify the request source. The
X-Gitter-Webhook-Idheader can be used to look up the room’s shared secret (if you enable it in the room settings). Compare the HMAC of the payload to the signature in the header. - Throttle requests. High‑traffic rooms can send thousands of messages per minute. If your listener can’t keep up, consider queuing the payloads (e.g., using a message broker) or filtering events in Gitter (enable the
message.createdfilter only for rooms that need CI integration). - Keep the token secret. Do not expose the Jenkins token in the webhook URL unless you’re sure it’s protected by network security groups.
Practical Checklist Before Production
| Item | Action |
|---|---|
| HTTPS certificate valid and trusted | Test with curl -v https://yourdomain.com/gitter-webhook |
| Webhook payload verified | Check Gitter room logs for 200 status |
| Jenkins job can be triggered manually | Trigger via curl -X POST https://jenkins.example.com/.../build?token=... |
| Listener logs visible | Enable structured logging (e.g., JSON logs) |
| Security controls in place | Enable HMAC verification and limit IP ranges if possible |
Closing Thoughts
By wiring Gitter events to Jenkins through a simple webhook, you eliminate the manual step of starting a build and reduce the time between a chat discussion and a deployment. The pattern scales: you can replace Jenkins with any CI system that exposes a REST endpoint, or add multiple triggers for different keywords. Just remember that every integration that crosses the public internet boundary must enforce TLS, validate requests, and handle retries gracefully. With those safeguards in place, your chat‑first workflow becomes truly automated and reliable.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.