# 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"} ```