# Sending pipeline status to Matrix chat room
## Matrix API
Matrix provides several APIs, [Client-Server API](https://spec.matrix.org/v1.4/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 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:
```bash=
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
```yaml=
kind: Secret
apiVersion: v1
metadata:
name: matrix-access-token
stringData:
token: {OAuth token for the bot app}
```
:clipboard: **Research if the `access_token` has an expiry date.**
### Obtaining the Matrix Room ID
The hardest for me was to create a room with Matrix. I'm pretty new to Matrix :stuck_out_tongue:, and it seems every server has different rules when it comes to the request body of [`POST /_matrix/client/v3/createRoom`](https://spec.matrix.org/v1.4/client-server-api/#creation).
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. :shrug:
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:
```bash=
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](https://raw.githubusercontent.com/tektoncd/catalog/main/task/send-to-channel-slack/0.1/send-to-channel-slack.yaml) on TektonHub:
```yaml=
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
```
> :bulb: It could be an idea to replace `room` and `endpoint` by the room alias.
> Instead of having a single step I could have used:
> 1. Use `cut -d\: -f2`, I could retrieve the endpoint
> 2. Curl the `/_matrix/client/v3/directory/room` to retrieve the RoomID
> 3. Send the message using the RoomID and Endpoint
> :bulb: 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:
```yaml=
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
```bash=
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:
```bash=
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"}
```