Sherine Khoury
Posted on July 19, 2024
Matrix provides an "open network for secure, decentralised communication". With Matrix bridges, you can connect to Slack, IRC, Teams, Discord, you name it!
This blog post explains how to interconnect a Tekton pipeline with a Matrix room, for the purpose of notifying the room members of the pipeline status.
Matrix API
Matrix provides several APIs, Client-Server API is one of them.
In order to be able to send messages to a matrix room, the Tekton pipeline needs to send an access_token
along with the request to the Matrix server.
Thus, a prerequisite to this task is to register a Matrix user for the bot with one of the Matrix servers.
Obtaining a Matrix access_token
Once the registration process is done, I obtained the access_token
through a simple login API call:
curl -XPOST -d '{"type":"m.login.password", "user":"sherine.khoury", "password":"take_a_wild_guess"}' "https://matrix.org/_matrix/client/r0/login"
{"user_id":"@sherine.khoury:matrix.org","access_token":"syt_c2hlcmluZS5raG91cnk_NFpzzGCtxFAHEDVKhYTl_123456","home_server":"matrix.org","device_id":"CNYGHLSLQY","well_known":{"m.homeserver":{"base_url":"https://matrix-client.matrix.org/"}}}
With the access_token
, I created a secret, with name matrix-access-token
in the namespace hosting my pipeline, of type generic with a single key, token
, containing the access_token
I just obtained in the step above.
Example
kind: Secret
apiVersion: v1
metadata:
name: matrix-access-token
stringData:
token: {OAuth token for the bot app}
Obtaining the Matrix Room ID
The hardest for me was to create a room with Matrix. I'm pretty new to Matrix 😛, and it seems every server has different rules when it comes to the request body of POST /_matrix/client/v3/createRoom
.
Similarly, every Matrix client calls the room differently: On FluffyChat, it's a Group, which can be created after creating a space. In Element, it's simply called a room!! Thankfully.
When you create a room in Element, the web UI provides the room ID back to you.
But you still need to set a Local address for the room in the Room Settings
in order to be able to query the roomAlias by API. 🤷
The room alias usually is #ROOM_NAME:SERVER_NAME.
So for a room with name my-team on matrix.org, you can also obtain the RoomID by sending the following request to the client-server API:
curl -v https://matrix.org/_matrix/client/v3/directory/room/%23my-room:matrix.org
{"room_id":"!xWldUqOaDUkrHUZRIP:matrix.org","servers":["matrix.org"]}
Notice there is no need for authentication here. Notice also the %23
replacing the #
character in the room alias.
Tekton Task
Largely inspired from the Slack task on TektonHub:
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: send-to-matrix-room
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Messaging
tekton.dev/tags: messaging
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le"
spec:
description: >-
These tasks post a simple message to a matrix room.
This task uses Matrix's Client-Server REST api to send the message.
params:
- name: matrix-access-token
type: string
description: secret name containing matrix access token (key is token)
- name: room
type: string
description: room id (in the format !<ROOM_ID>:<SERVER_NAME>)
- name: endpoint
type: string
description: Matrix server URL to which to send the message
- name: message
type: string
description: plain text message
steps:
- name: post
image: docker.io/curlimages/curl:7.70.0@sha256:031df77a11e5edded840bc761a845eab6e3c2edee22669fb8ad6d59484b6a1c4 #tag: 7.70.0
script: |
#!/bin/sh
/usr/bin/curl -X POST -H 'Content-type: application/json' --data '{"msgtype":"m.text", "body":"$(params.message)"}' https://$(params.endpoint)/_matrix/client/r0/rooms/$(params.room)/send/m.room.message?access_token=$TOKEN
env:
- name: TOKEN
valueFrom:
secretKeyRef:
name: $(params.matrix-access-token)
key: token
💡 It could be an idea to replace
room
andendpoint
by the room alias.
Instead of having a single step I could have used:
- Use
cut -d\: -f2
, I could retrieve the endpoint- Curl the
/_matrix/client/v3/directory/room
to retrieve the RoomID- Send the message using the RoomID and Endpoint
💡 If this looks good, I could send a PR to the TektonHub.
Tekton example pipeline
Now that I've got a task, I can use that task in a pipeline, like so:
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: pipeline-matrix-hello
namespace: okd-team
spec:
params:
- name: matrix-room
description: room id (in the format !<ROOM_ID>:<SERVER_NAME>)
type: string
- name: matrix-endpoint
description: room id (in the format !<ROOM_ID>:<SERVER_NAME>)
type: string
- name: repo-name
description: The repo name
type: string
- name: bundle-version
description: The bundle version
type: string
tasks:
- name: talk-to-matrix
params:
- name: matrix-access-token
value: matrix-access-token
- name: endpoint
value: $(params.matrix-endpoint)
- name: room
value: $(params.matrix-room)
- name: message
value: Going to run operator pipeline on repo $(params.repo-name) to build $(params.bundle-version)
taskRef:
kind: Task
name: send-to-matrix-room
Finally, start the pipeline using
tkn pipeline start pipeline-matrix-hello --param repo-name=node-observability-operator --param bundle-version=v1.1.1 --param matrix-endpoint=matrix.org --param matrix-room=\!yKXXPqFwfCOTipZMxp:matrix.org
The logs of the pipelinerun show:
tkn pipelinerun logs pipeline-matrix-hello-run-hscx9 -f -n okd-team
[talk-to-matrix : post] % Total % Received % Xferd Average Speed Time Time Time Current
[talk-to-matrix : post] Dload Upload Total Spent Left Speed
100 172 0 59 100 113 114 219 --:--:-- --:--:-- --:--:-- 334
[talk-to-matrix : post] {"event_id":"$EYhJ9A5DlMlBx8xD4ORF9q-8r1KmLTsvODvCgwu5xkU"}
Posted on July 19, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.