add initial matrix-to-sms gateway support

This commit is contained in:
DJ Gillespie 2025-09-10 14:49:55 -06:00
commit b87e62a10f
4 changed files with 83 additions and 0 deletions

10
Dockerfile Normal file
View File

@ -0,0 +1,10 @@
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py ./
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8080"]

6
README.md Normal file
View File

@ -0,0 +1,6 @@
# Email to Matrix SMS Gateway
## Setup
1. Build and run the Docker container:

64
app.py Normal file
View File

@ -0,0 +1,64 @@
import os
import asyncio
from fastapi import FastAPI, Form
from nio import AsyncClient
from fastapi.responses import JSONResponse
from starlette.requests import Request
app = FastAPI()
# Matrix credentials and homeserver from environment
HOMESERVER = os.getenv("MATRIX_HOMESERVER")
USER_ID = os.getenv("MATRIX_USER_ID")
PASSWORD = os.getenv("MATRIX_PASSWORD")
# Initialize nio client globally and login once on startup
matrix_client = AsyncClient(HOMESERVER, USER_ID)
@app.on_event("startup")
async def startup_event():
await matrix_client.login(PASSWORD)
@app.on_event("shutdown")
async def shutdown_event():
await matrix_client.logout()
await matrix_client.close()
@app.post("/mailgun-webhook")
async def mailgun_webhook(
request: Request,
recipient: str = Form(...), # 'recipient' field from Mailgun webhook, e.g. 14155551212@yourdomain.com
subject: str = Form(""),
body_plain: str = Form(""),
):
# Extract phone number from recipient email
phone_jid_localpart = recipient.split("@")[0]
# Assuming your bridge uses cheogram.com domain for XMPP JIDs
target_jid = f"_{phone_jid_localpart}=40cheogram.com:aria-net.org"
# Find or create direct message room with bridged target user
resp = await matrix_client.room_create(
invite=[target_jid],
is_direct=True,
preset="trusted_private_chat",
)
room_id = resp.room_id
# Compose SMS body (you could prepend subject if needed)
message = f"{body_plain}" if body_plain else "(empty message)"
# Send the message to the Matrix bridged user
await matrix_client.room_send(
room_id,
message_type="m.room.message",
content={
"msgtype": "m.text",
"body": message,
}
)
return JSONResponse({"status": "SMS sent", "to": target_jid})
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8080)

3
requirements.txt Normal file
View File

@ -0,0 +1,3 @@
fastapi
uvicorn[standard]
matrix-nio[e2e]