- HTML 76.6%
- Go 22.3%
- Dockerfile 1.1%
| gif-matrix-proxy | ||
| .editorconfig | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| .gitlab-ci.yml | ||
| docker-compose.yml | ||
| example-config.yaml | ||
| LICENSE | ||
| README.md | ||
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
- Docker and Docker Compose (or Go 1.22+ if running without Docker)
- A reverse proxy terminating TLS (Traefik, nginx, Caddy, …)
- A domain name with DNS configured
- Giphy API key (get one at https://developers.giphy.com/)
- Tenor API key (get one at https://tenor.com/developer/dashboard)
Installation
- Clone this repository:
git clone https://git.láďa.eu/ladab/gif-matrix-proxy.git
cd gif-matrix-proxy
- Generate a server signing key:
docker build -t gif-matrix-proxy gif-matrix-proxy
docker run --rm gif-matrix-proxy -generate-key
- Create your configuration file:
cp example-config.yaml config.yaml
- Edit
config.yamlwith 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
- Configure environment variables:
cp .env.example .env
- Edit
.envwith 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
- Start the service:
docker-compose up -d
- Configure your Matrix client to use the proxy:
- Set up
.well-knowndelegation for your domain, or - Directly proxy your domain to this service
- Access the web interface at
https://giphy.example.com
Matrix Client Integration
To integrate the GIF picker into your Element Matrix client:
- In Element, use the
/devtoolscommand - Select "Explore Account Data"
- 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"
}
}
- Replace
your.domain.herewith your proxy's domain andyour-user-idwith your Matrix ID - 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.
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:
- LICENSE file in this repository
- maunium/stickerpicker original project
- GNU AGPL-3.0 License
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. Make sure to follow the AGPL-3.0 license requirements when contributing.