Matrix Ttile

You must be wondering what matrix is. Is it the famous sci-fi film I am writing about? Sadly no but still let’s see how it can make your life easier if you trying to start up and want to analyse user behaviour on your new platform.

What is Matrix?

Well, matrix is an open-source, decentralized communication protocol that provides a secure, real-time communication infrastructure. It’s commonly used for messaging, VoIP (voice over IP), and WebRTC applications, making it a flexible foundation for various types of communication needs. With Matrix, users can communicate across different servers while maintaining control of their data, as the protocol supports decentralized, end-to-end encrypted messaging.

You can think of matrix as a foundation for building application. Matrix works a little like email, but instantaneous and secure:

  • You need to register an account at a provider
  • Whatever your provider is, you can talk to people using other providers
  • In the same way you can use Outlook or Thunderbird with the same email account, you can use different Matrix apps for the same Matrix account.

Elements of Matrix

Matrix works like email, but for instant messaging. People need to use a client to be able to write and receive messages, and they need providers to provide them an account on their homeserver.

Schema of clients connected to homeservers. The servers are federated together as shown below.

Matrix Elements

Let’s explore these pieces together.

Homeserver

A homeserver is a piece of software hosting accounts of Matrix users. Homeservers are the central servers that users connect to within the Matrix network. Each homeserver hosts user accounts, room data, and manages communication between users on that server. Important aspects of homeservers include:

  • User Accounts: Each homeserver manages the accounts for users who register on it, although users can still communicate with those on other homeservers.
  • Rooms: Homeservers store chat rooms and synchronize room data with other homeservers as needed.
  • Data Control: Each organization or individual can host their own homeserver (e.g., Synapse or Dendrite), giving them full control over their data.

It is bound to a single domain that cannot change over time. The accounts on a server have an identifier made of a local part (the username), and a server part, which is the (vanity) domain of the homeserver. A typical identifier would be @username:example.com.

Schema of clients connected to federated homeservers are shown below. All users have a Matrix ID.

Homeserver

You can find a list of existing homeserver implementations at https://matrix.org/ecosystem/servers/. Most of them are open source, so you can explore how they work.

Client

Clients are pieces of software that can use a Matrix account to send and receive events from a specific homeserver. The clients themselves only ever talk to the homeserver of the account they’re using. If a client uses the @alice:example.com account, they will only talk to example.com.

A Matrix client connects to a homeserver, allowing users to send and receive messages, join rooms, and participate in real-time communication within the Matrix network. Clients are essentially the user-facing side of the Matrix protocol, acting as gateways for users to interact with the decentralized Matrix ecosystem.

Here’s a typical interaction flow:

  • Connect to Homeserver: The client connects to a homeserver specified by the user’s Matrix ID (e.g., @user:example.com), which determines where the account and message history are stored.
  • Sync Messages: The client fetches messages and events from rooms that the user has joined, maintaining a real-time connection to keep messages and notifications up-to-date.
  • Send Events: When a user sends a message or updates their profile, the client communicates this action to the homeserver, which then replicates it to other users in the room.
  • End-to-End Encryption: If encryption is enabled, the client handles encryption and decryption of messages locally, so data remains secure between the client and the recipient’s client.

To get a better idea of what clients look like in practice, you can find a list on https://matrix.org/ecosystem/clients/ and give them a go.

AppService (bridges and some bots)

AppServices are specialized integrations that extend Matrix’s functionality by connecting it with external systems or adding advanced automation. Bridges and some types of bots are common examples of Application Services. They act as intermediary services that allow Matrix users to interact with external platforms and automate tasks within Matrix.

Bots

Some bots in Matrix are implemented as AppServices to handle tasks with greater permissions or to interact on behalf of multiple users. Bots can be configured to listen for specific events and respond to commands, perform automation, or interact with other services.

  • Task Automation: Bots can automate tasks like setting reminders, providing weather updates, or summarizing conversations.
  • Room Management: Bots can help moderate rooms, manage membership, enforce rules, or provide notifications.
  • Event-Triggered Actions: Bots can respond to keywords or commands in rooms to perform actions like kicking users, sending alerts, or retrieving information from external APIs.

Sometimes we need to get a more global view of what is happening on our homeserver to take action. If we want to write an anti-spam module for example, we want to be able to read each and every message from public rooms to detect patterns and ring the alarm or take action directly.

To do it with a bot, you would need to invite the bot in each and every room where you want the monitoring to happen. An appservice is able to monitor all the unencrypted events (messages sent/edited/redacted, people joining or leaving rooms) within its namespace.

Bridges

Sometimes we need to do even more than being an all-seeing eye: we need to be able to create users and rooms automatically. A typical use case for this is bridges. Bridges allow you to connect a Matrix community to a third-party platform such as Whatsapp, Discord or Slack. Users on these communities appear as native users on Matrix, and ideally the other way around on the third-party platform as well.

  • The users created on the Matrix side by the bridge to mimic users on the third-party platform are called ghosts.
  • The users created on the third-party platform by the bridge to mimic Matrix users are called puppets.

A schema of a room bridged between matrix.org and slack.com is shown below:

Bridge

To do so, the bridge needs to be able to create and impersonate users on Matrix, and to control rooms as well. In order to limit the risks of abuse, bridges can be limited to controlling a namespace.

Enough of the theory, let’s see everything in action and how to deploy it.

Deploying matrix with element client

I will be using dockers for deploying the homeserver (synapse), and mautrix-whstasapp as the matrix bridge.

Here’s the compose file for the services:

version: '3.8'

services:
  synapse:
    image: matrixdotorg/synapse:latest
    container_name: synapse
    environment:
      - SYNAPSE_SERVER_NAME=localhost
      - SYNAPSE_REPORT_STATS=yes
    volumes:
      - ./data/synapse:/data
    ports:
      - "8008:8008"
    restart: always

  mautrix-whatsapp:
    image: dock.mau.dev/mautrix/whatsapp:latest
    container_name: mautrix-whatsapp
    environment:
      - MAUTRIX_WHATSAPP_HOMESERVER_URL=http://synapse:8008
      - MAUTRIX_WHATSAPP_DOMAIN=localhost
      - MAUTRIX_WHATSAPP_BRIDGE_PORT=29318
      - MAUTRIX_WHATSAPP_AS_TOKEN=YOUR_GENERATED_AS_TOKEN
    env_file: matrix.env
    depends_on:
      - synapse
    volumes:
      - ./data/mautrix-whatsapp:/data
    ports:
      - "29318:29318"
    restart: always
  
  postgres:
    image: postgres:13
    container_name: mautrix_postgres
    environment:
      POSTGRES_DB: "mautrix_whatsapp"
      POSTGRES_USER: "mautrix_user"
      POSTGRES_PASSWORD: "matrix123"
    ports:
      - 5332:5432
    volumes:
      - ./data/postgres:/var/lib/postgresql/data
    restart: always
  • synapse is the main Matrix homeserver that manages Matrix communication. It acts like a server where all Matrix data and messages are stored and handled.
  • mautrix-whatsapp is a bridge that connects Matrix (via Synapse) with WhatsApp, enabling Matrix users to send and receive WhatsApp messages.
  • postgres is used to store the mautrix-whatsapp data in database

We need to mount the volume from the current data folder (create the folder as mentioned in the compose) in our ubuntu system to /data folder in the docker container.

In deploying the Matrix Synapse server and Mautrix-WhatsApp bridge, three important configuration files are used: homeserver.yaml, config.yaml, and registration.yaml. Each file has a distinct role in configuring various aspects of the deployment. Here’s what each file does and why it’s necessary:

homeserver.yaml

It is the main configuration file for the Matrix Synapse server. It defines essential settings for the Synapse homeserver, including server name, database connection, encryption, federation settings, and other features required to manage Matrix communication. It will will be generated once you start the server but we need to change the configuration a bit to run it locally.

It should be located in the Synapse data directory (e.g., ./data/synapse)

When setting up a Matrix Synapse server, enabling TLS ensures that all communication between clients (such as Matrix clients like Element) and the Synapse server is encrypted. This prevents third parties from intercepting or tampering with data, which is crucial for secure, end-to-end encrypted communication. For local testing, we can create a self-signed certificate, though it will show as “untrusted” in browsers and clients.

openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes

Once the certificate files are generated, we need to copy it in data/synapse folder which resides in your project folder.

Now, we need to change the path of cert files in the homeserver.yaml file something like below

tls_certificate_path: "/data/localhost.tls.crt"
tls_private_key_path: "/data/localhost.tls.key"

We also need to change the servername to localhost in the homeserver.yaml since we are deploying it locally and the path to registration.yaml file which we will be creating later.

## Server ##

server_name: "localhost"
pid_file: /homeserver.pid
web_client: False
soft_file_limit: 0
log_config: "/data/log.config"

app_service_config_files:
  - /data/registration.yaml

config.yaml

It is the primary configuration file for Mautrix-WhatsApp (the bridge). It defines how the bridge interacts with Synapse and WhatsApp, including connection details, user mappings, database settings, and encryption configurations.

It should be located in the bridge’s data directory (e.g., ./data/mautrix-whatsapp).

We need to change the database, homeserver and appservice section in the yaml file as per our configuration in the compose file.

# Config options that affect the central bridge module.
bridge:
    permissions:
        "*": relay
        "localhost": user
        "@admin:localhost": admin
# Config for the bridge's database.
database:
    type: postgres
    uri: postgres://mautrix_user:matrix123@postgres/mautrix_whatsapp?sslmode=disable
    max_open_conns: 5
    max_idle_conns: 1
    max_conn_idle_time: null
    max_conn_lifetime: null

# Homeserver details.
homeserver:
    address: http://synapse:8008 # make sure this matches the url in the compose file
    domain: localhost
    software: standard
    status_endpoint:
    message_send_checkpoint_endpoint:
    async_media: false
    websocket: false
    ping_interval_seconds: 0

# Application service host/registration related details.
# Changing these values requires regeneration of the registration (except when noted otherwise)
appservice:
    address: http://localhost:29318 # make sure this matches the url in the compose file
    public_address: https://bridge.example.com
    hostname: 0.0.0.0
    port: 29318 # make sure this matches the port in the compose file
    id: whatsapp
    bot:
        username: _whatsapp_bot
        displayname: WhatsApp bridge bot
        avatar: mxc://maunium.net/NeXNQarUbrlYBiPCpprYsRqr
    ephemeral_events: true
    async_transactions: false
    as_token: "{you_generated_as_token}"
    hs_token: "{you_generated_hs_token}"
    username_template: _whatsapp_

Rest all the services can be kept as it is in the config.yaml file

registration.yaml

It is a special configuration file used to register the Mautrix-WhatsApp bridge as an Application Service (AppService) with Synapse. It grants the bridge specific permissions to interact with the Synapse server, defining what it can do and which users or namespaces it can manage.

It should be placed inside both the ./data/synapse and ./data/mautrix-whatsapp directory

It should look something like:

id: "whatsapp"
url: "http://mautrix-whatsapp:29318"  # URL where the bridge is accessible
as_token: "{you_generated_as_token}"  # Application service token for Synapse to authenticate the bridge
hs_token: "{you_generated_hs_token}"  # Homeserver token for the bridge to authenticate with Synapse
sender_localpart: "_whatsapp_bot"     # The local part of the Matrix user the bridge uses as its bot
namespaces:
  users:
    - regex: "@_whatsapp_.*"
      exclusive: true
  rooms: []
  aliases:
    - regex: "#_whatsapp_.*"
      exclusive: true

If you noticed, we need two tokens to be generated here.

  • AppService Token (as_token): Used by Synapse to authenticate the AppService.
  • Homeserver Token (hs_token): Used by the AppService to authenticate with Synapse.

You can generate random tokens using tools like openssl:

openssl rand -hex 32  # Generates a random token

Make sure to use this as an environment variable if you are deploying it in cloud.

Summary Files

These files work together to enable Synapse and Mautrix-WhatsApp to interact securely and correctly, with each service knowing where to connect and what it’s authorized to do within the Matrix ecosystem.

In action with whatsapp

Now, since you have made all the setup ready get the docker started simply using docker-compose up. This will start a matrix homeserver on url http://localhost:8008

To create a Synapse user after the Docker containers are up, you can use the register_new_matrix_user command, which is included in the Synapse Docker image.

docker exec -it synapse register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008

Once the user is created, go to app.element.io and sign in by changing the homeserver url to http://localhost:8008 and using the user created above.

Element

Once you are logged in, you should see whatsapp bridge bot in the chat section or you can search it using @_whatsapp_bot:localhost and create a room. In the bot chat room, you can use login qr to login to your whatsapp account using qr and link your number.

Whatsapp

There you go, now you have created the bridge and connected with your whatsapp account. Since your WhatsApp messages are bridged to Matrix, they are stored as rooms and messages on the Synapse server. You can retrieve these messages using the Matrix API or by directly querying the Synapse database.

matrix with CRM

Using the Matrix Client-Server API:

  • Get Joined Rooms: First, retrieve all the rooms (chats) you are part of.
    curl -X GET "http://localhost:8008/_matrix/client/r0/joined_rooms?access_token=YOUR_ACCESS_TOKEN"
    
  • Get Messages from a Room: For each room, retrieve messages using the /messages endpoint.
    curl -X  GET "http://localhost:8008/_matrix/client/v3/rooms/{roomId}/messages?access_token=YOUR_ACCESS_TOKEN&dir=b&limit=100"
    

    Replace {roomId} with the room ID of each chat.

After retreiving the chat daata, we can use natural language processing (NLP) or a local language model (such as LLaMA or GPT-3) to classify messages. Once the data is prepared, you can send it to Twenty CRM (or any other CRM tool) for further analysis and action.

Once we have integrated matrix with a CRM tool, we can do futher analysis on user interaction with our platform and understand their behaviour better.

Here’s how a CRM like Twenty or similar tools can help with user analysis in this context:

  1. Customer Interaction Tracking
  2. Sentiment Analysis
  3. Customer Segmentation
  4. Intent Recognition and Categorization
  5. Issue Tracking and Resolution Management
  6. Automated Follow-Up and Customer Retention
  7. Keyword Analysis for Product and Service Insights
  8. Performance Metrics for Customer Support
  9. Customer Lifetime Value (CLV) Prediction
  10. Cross-Channel Integration

Conclusion

Integrating WhatsApp chats into a CRM system, like Twenty, through Matrix and a bridging solution, offers a powerful, data-driven approach to enhancing customer relationship management. By following a structured workflow—retrieving and processing chat data from Matrix, analyzing sentiment and intent, and feeding insights into a CRM—you enable a seamless, comprehensive view of customer interactions across platforms.

You can also read more about matrix from the official documentation https://matrix.org/docs/chat_basics/matrix-for-im/. All the above details have been taken from the official docs only.

Please drop me a mail if you feel anything in this post can be improved or changed.

Happy learning :)