A fast and simple Matrix sticker picker widget
  • HTML 74.4%
  • Go 24.4%
  • Dockerfile 1.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Ladislav Brodecký 26504590d1
All checks were successful
Release / release (push) Successful in 3m16s
Scroll to top when a new search replaces results
2026-07-20 16:43:30 +02:00
.forgejo/workflows Run dockerd inside privileged job container 2026-07-20 16:13:02 +02:00
gif-matrix-proxy Scroll to top when a new search replaces results 2026-07-20 16:43:30 +02:00
.editorconfig Add support for sending gifs via Giphy 2024-05-18 16:18:55 +03:00
.env.example Add Forgejo release workflow for registry-based deploys 2026-07-20 15:26:43 +02:00
.gitattributes Add some .gitattributes 2020-09-13 17:53:18 +03:00
.gitignore Rename project to gif-matrix-proxy and update related configurations 2026-04-19 17:57:38 +02:00
docker-compose.yml Update README and docker-compose for improved reverse proxy configuration 2026-04-19 21:03:36 +02:00
example-config.yaml Add KLIPY support and new assets 2026-04-19 20:46:27 +02:00
LICENSE Switch license to AGPLv3+ 2020-10-30 23:18:55 +02:00
README.md Document runner requirements for the release workflow 2026-07-20 16:15:23 +02:00

GIF Matrix Proxy

A Matrix media proxy server that enables easy integration of Giphy and Tenor GIFs into Matrix clients. Based on maunium/stickerpicker, this proxy implements the Matrix media API to serve GIFs from Giphy and Tenor while maintaining compatibility with Matrix clients.

Features

  • Serves as a Matrix media server for Giphy and Tenor GIFs
  • Implements Matrix federation API for seamless integration
  • Built-in web interface for serving a GIF search and selection widget
  • Supports MSC3860/MSC3916 media download redirects
  • Docker support with Traefik integration
  • Element-style UI with CS/EN localization (detected from ?lang= widget parameter)

Prerequisites

Installation

  1. Clone this repository:
git clone https://git.láďa.eu/ladab/gif-matrix-proxy.git
cd gif-matrix-proxy
  1. Generate a server signing key:
docker build -t gif-matrix-proxy gif-matrix-proxy
docker run --rm gif-matrix-proxy -generate-key
  1. Create your configuration file:
cp example-config.yaml config.yaml
  1. Edit config.yaml with your settings:
  • Set your server_name (e.g., giphy.example.com)
  • Add your generated server key
  • Insert your Giphy and Tenor API keys
  • Configure other options as needed
  1. Configure environment variables:
cp .env.example .env
  1. Edit .env with your settings:
MATRIX_MEDIA_DOMAIN=mediaproxy.example.com
NETWORK_NAME=matrix
CONFIG_PATH=./config.yaml

Reverse Proxy

The container exposes port 8008 on the host (default bind: 127.0.0.1:8008, configurable via HOST_BIND and HOST_PORT in .env). Terminate TLS in your reverse proxy of choice and forward to that port.

nginx example

server {
    listen 443 ssl http2;
    server_name mediaproxy.example.com;

    ssl_certificate     /etc/letsencrypt/live/mediaproxy.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mediaproxy.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8008;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

If your reverse proxy runs in a different container, set HOST_BIND=0.0.0.0 (or attach both containers to the same Docker network and remove the ports: mapping entirely).

Traefik

If you prefer Traefik, replace the ports: block in docker-compose.yml with networks: + labels: for Traefik routing. See maunium/stickerpicker or any Traefik docker-compose example for the label syntax.

Usage

  1. Start the service:
docker-compose up -d
  1. Configure your Matrix client to use the proxy:
  • Set up .well-known delegation for your domain, or
  • Directly proxy your domain to this service
  1. Access the web interface at https://giphy.example.com

Matrix Client Integration

To integrate the GIF picker into your Element Matrix client:

  1. In Element, use the /devtools command
  2. Select "Explore Account Data"
  3. Set the following data for the key m.widgets:
{
  "stickerpicker": {
    "content": {
      "type": "m.stickerpicker",
      "url": "https://your.domain.here/?theme=$theme&lang=$org.matrix.msc2873.client_language",
      "name": "GIF Picker",
      "creatorUserId": "@your-user-id:your.domain.here",
      "data": {}
    },
    "sender": "@your-user-id:your.domain.here",
    "state_key": "stickerpicker",
    "type": "m.widget",
    "id": "stickerpicker"
  }
}
  1. Replace your.domain.here with your proxy's domain and your-user-id with your Matrix ID
  2. After saving, you should now see a GIF button in your message composer

The $lang parameter tells the picker which language to use (CS/EN). The UI automatically falls back to navigator.language and finally English if the parameter is missing.

Note: You may need to refresh Element or reload the page for changes to take effect.

Release & Deploy

Pushing a version tag builds and publishes a Docker image via Forgejo Actions (.forgejo/workflows/release.yml):

git tag v1.2.3
git push origin v1.2.3

The workflow pushes git.xn--la-mia8p.eu/ladab/gif-matrix-proxy:v1.2.3 (and :latest) to the Forgejo container registry and creates a release. It needs a RELEASE_TOKEN secret (user or repo level) with write:package scope, because the automatic job token cannot push to the container registry. The runner must allow privileged job containers — dockerd is bootstrapped inside the job because the runner exposes no docker socket and its services do not support --privileged.

To deploy from the registry instead of building locally, set in .env:

PROXY_IMAGE=git.xn--la-mia8p.eu/ladab/gif-matrix-proxy:latest

and update with:

docker compose pull && docker compose up -d

Local Development

To run locally without Docker:

cd gif-matrix-proxy
go run . -generate-key         # prints a server key — paste into config.yaml
cp ../example-config.yaml config.yaml
# edit config.yaml: fill in server_key, giphy_api_key, tenor_api_key
go run .

Then open http://127.0.0.1:8008/?theme=dark&lang=cs.

config.yaml is gitignored because it contains the server signing key and API secrets.

Configuration Options

See example-config.yaml for all available configuration options and their descriptions.

License

This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). This is a derivative work based on maunium/stickerpicker, which is also licensed under AGPL-3.0.

For more information, see:

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. Make sure to follow the AGPL-3.0 license requirements when contributing.