🎉 First commit!
This commit is contained in:
commit
99c2c62831
13 changed files with 280 additions and 0 deletions
4
.dockerignore
Normal file
4
.dockerignore
Normal file
|
@ -0,0 +1,4 @@
|
|||
.env
|
||||
bin
|
||||
lib
|
||||
include
|
10
.env.example
Normal file
10
.env.example
Normal file
|
@ -0,0 +1,10 @@
|
|||
BOT_HOMESERVER="https://example.org"
|
||||
BOT_USERNAME="PrayingTimesBotUsername"
|
||||
BOT_PASSWORD="supersecret"
|
||||
REGISTRATION_API_URL="http://localhost:5001/api/token"
|
||||
REGISTRATION_API_SHARED_SECRET="supersecret"
|
||||
REGISTRATION_URL="https://matrix.example.org/register?token="
|
||||
SMTP_HOSTNAME="smtp.example.org"
|
||||
SMTP_USERNAME="username"
|
||||
SMTP_PASSWORD="password"
|
||||
MAIL_FROM_ADDRESS="me@example.org"
|
38
.forgejo/workflows/ci.yaml
Normal file
38
.forgejo/workflows/ci.yaml
Normal file
|
@ -0,0 +1,38 @@
|
|||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "main"
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
registry:
|
||||
image: registry:2
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Docker for QEMU
|
||||
uses: https://github.com/papodaca/install-docker-action@main
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: code.f2n.me
|
||||
username: ${{ secrets.MY_FORGEJO_USERNAME }}
|
||||
password: ${{ secrets.MY_FORGEJO_TOKEN }}
|
||||
- name: Build and push to local registry
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: code.f2n.me/finn/matrix-bot-invitation-mailer:latest
|
||||
- name: Inspect
|
||||
run: |
|
||||
docker buildx imagetools inspect code.f2n.me/finn/matrix-bot-invitation-mailer:latest
|
21
.forgejo/workflows/python-pep8.yaml
Normal file
21
.forgejo/workflows/python-pep8.yaml
Normal file
|
@ -0,0 +1,21 @@
|
|||
name: Python formatting PEP8
|
||||
run-name: ${{ forgejo.actor }} is running PEP8 check
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
Python-PEP8:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y python3-pip
|
||||
pip install flake8
|
||||
|
||||
- name: Run checking
|
||||
run: |
|
||||
flake8 --ignore=E501 --extend-exclude bin,lib .
|
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
bin/
|
||||
lib/
|
||||
include/
|
||||
__pycache__
|
||||
pyvenv.cfg
|
||||
.env
|
||||
session.txt
|
||||
tags
|
13
Dockerfile
Normal file
13
Dockerfile
Normal file
|
@ -0,0 +1,13 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
FROM python:3.12-alpine
|
||||
|
||||
WORKDIR /bot
|
||||
|
||||
RUN apk update && apk add python3-dev gcc libc-dev libffi-dev
|
||||
|
||||
COPY requirements.txt requirements.txt
|
||||
RUN pip3 install -r requirements.txt
|
||||
|
||||
COPY . .
|
||||
|
||||
ENTRYPOINT ["/bot/entrypoint.sh"]
|
15
README.md
Normal file
15
README.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Matrix Bot for sending homeserver invitation link via e-mail
|
||||
|
||||
A early stage and simlpe Matrix bot which I use in addition to [matrix-registration](https://github.com/ZerataX/matrix-registration).
|
||||
|
||||
The bot calls the Api and sends the invitation link via e-mail to a given receipient.
|
||||
|
||||
## Usage
|
||||
|
||||
Use container image or run this after cloning:
|
||||
|
||||
```
|
||||
. bin/active
|
||||
python -m matrix_bot_invitation_mailer
|
||||
```
|
||||
|
17
compose.yml
Normal file
17
compose.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
services:
|
||||
matrix-bot-invitation-mailer:
|
||||
build:
|
||||
context: .
|
||||
image: code.f2n.me/finn/matrix-bot-invitation-mailer:latest
|
||||
environment:
|
||||
- BOT_HOMESERVER
|
||||
- BOT_USERNAME
|
||||
- BOT_PASSWORD
|
||||
- REGISTRATION_API_URL
|
||||
- REGISTRATION_API_SHARED_SECRET
|
||||
- REGISTRATION_URL
|
||||
- SMTP_HOSTNAME
|
||||
- SMTP_USERNAME
|
||||
- SMTP_PASSWORD
|
||||
- MAIL_FROM_ADDRESS
|
4
data/.gitignore
vendored
Normal file
4
data/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
2
entrypoint.sh
Executable file
2
entrypoint.sh
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
python -m matrix_bot_invitation_mailer
|
0
matrix_bot_invitation_mailer/__init__.py
Normal file
0
matrix_bot_invitation_mailer/__init__.py
Normal file
113
matrix_bot_invitation_mailer/__main__.py
Normal file
113
matrix_bot_invitation_mailer/__main__.py
Normal file
|
@ -0,0 +1,113 @@
|
|||
import simplematrixbotlib as botlib
|
||||
import requests
|
||||
import os
|
||||
import logging
|
||||
import smtplib
|
||||
import datetime
|
||||
from email.mime.text import MIMEText
|
||||
from dotenv import load_dotenv
|
||||
|
||||
|
||||
load_dotenv()
|
||||
|
||||
creds = botlib.Creds(
|
||||
os.getenv("BOT_HOMESERVER"),
|
||||
os.getenv("BOT_USERNAME"),
|
||||
os.getenv("BOT_PASSWORD"),
|
||||
session_stored_file="data/session.txt"
|
||||
)
|
||||
|
||||
bot = botlib.Bot(creds)
|
||||
PREFIX = '!'
|
||||
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
@bot.listener.on_message_event
|
||||
async def echo(room, message) -> None:
|
||||
match = botlib.MessageMatch(room, message, bot, PREFIX)
|
||||
|
||||
if match.is_not_from_this_bot() and match.prefix() and match.command("echo"):
|
||||
|
||||
await bot.api.send_text_message(
|
||||
room.room_id, " ".join(arg for arg in match.args())
|
||||
)
|
||||
|
||||
|
||||
@bot.listener.on_message_event
|
||||
async def usage(room, message) -> None:
|
||||
match = botlib.MessageMatch(room, message, bot, PREFIX)
|
||||
|
||||
response = """usage:
|
||||
- **!invite** <johndoe@example.org> - sends e-mail with invitation link to given mail address
|
||||
- **everything else** - prints this help
|
||||
"""
|
||||
|
||||
if match.is_not_from_this_bot() and not match.prefix() and room.room_id:
|
||||
await bot.api.send_markdown_message(room.room_id, response)
|
||||
|
||||
|
||||
@bot.listener.on_message_event
|
||||
async def invite(room, message) -> None:
|
||||
match = botlib.MessageMatch(room, message, bot, PREFIX)
|
||||
|
||||
if match.is_not_from_this_bot() and match.prefix() and match.command("invite"):
|
||||
logging.info("preparing invite")
|
||||
# TODO: add validation
|
||||
mail_address = " ".join(arg for arg in match.args())
|
||||
|
||||
send_invitation_mail(mail_address)
|
||||
response = "mail sent"
|
||||
await bot.api.send_text_message(room.room_id, response)
|
||||
|
||||
|
||||
def send_invitation_mail(receiver_email):
|
||||
logging.info("sending email...")
|
||||
|
||||
# make reqest to obtain registration token
|
||||
headers = {
|
||||
'Content-Type': "application/json",
|
||||
'Authorization': "SharedSecret {}".format(os.getenv("REGISTRATION_API_SHARED_SECRET"))
|
||||
}
|
||||
payload = {
|
||||
"max-usage": "1",
|
||||
"expiration_date": (datetime.date.today() + datetime.timedelta(days=7)).strftime("%Y-%m-%d")
|
||||
}
|
||||
response = requests.post(os.getenv("REGISTRATION_API_URL"), headers=headers, json=payload)
|
||||
logging.info(response.text)
|
||||
logging.info(response.json())
|
||||
sender_email = os.getenv("MAIL_FROM_ADDRESS")
|
||||
|
||||
body = """Hello,
|
||||
|
||||
you have been invited to the f2n.me matrix homeserver!
|
||||
|
||||
Click the following link and create your account:
|
||||
|
||||
{}
|
||||
|
||||
The link will be valid for 7 days.""".format(os.getenv("REGISTRATION_URL") + response.json()["name"])
|
||||
msg = MIMEText(body, 'plain')
|
||||
msg['From'] = sender_email
|
||||
msg['To'] = receiver_email
|
||||
msg['Subject'] = "Your matrix homeserver invitation link"
|
||||
|
||||
try:
|
||||
# Connect to the SMTP server
|
||||
server = smtplib.SMTP(os.getenv("SMTP_HOSTNAME"), os.getenv("SMTP_PORT"))
|
||||
server.starttls() # Secure the connection
|
||||
server.login(os.getenv("SMTP_USERNAME"), os.getenv("SMTP_PASSWORD")) # Login to the server
|
||||
|
||||
# Send the email
|
||||
server.sendmail(sender_email, receiver_email, msg.as_string())
|
||||
|
||||
print("Email sent successfully")
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
finally:
|
||||
# Close the connection
|
||||
server.quit()
|
||||
|
||||
|
||||
bot.run()
|
35
requirements.txt
Normal file
35
requirements.txt
Normal file
|
@ -0,0 +1,35 @@
|
|||
aiofiles==23.2.1
|
||||
aiohttp==3.9.5
|
||||
aiohttp-socks==0.8.4
|
||||
aiosignal==1.3.1
|
||||
async-timeout==4.0.3
|
||||
attrs==23.2.0
|
||||
certifi==2024.6.2
|
||||
cffi==1.16.0
|
||||
charset-normalizer==3.3.2
|
||||
cryptography==42.0.8
|
||||
frozenlist==1.4.1
|
||||
h11==0.14.0
|
||||
h2==4.1.0
|
||||
hpack==4.0.0
|
||||
hyperframe==6.0.1
|
||||
idna==3.7
|
||||
jsonschema==4.22.0
|
||||
jsonschema-specifications==2023.12.1
|
||||
Markdown==3.6
|
||||
matrix-nio==0.24.0
|
||||
multidict==6.0.5
|
||||
pillow==10.3.0
|
||||
pycparser==2.22
|
||||
pycryptodome==3.20.0
|
||||
python-cryptography-fernet-wrapper==1.0.4
|
||||
python-dotenv==1.0.1
|
||||
python-socks==2.5.0
|
||||
referencing==0.35.1
|
||||
requests==2.32.3
|
||||
rpds-py==0.18.1
|
||||
simplematrixbotlib==2.11.0
|
||||
toml==0.10.2
|
||||
unpaddedbase64==2.1.0
|
||||
urllib3==2.2.2
|
||||
yarl==1.9.4
|
Loading…
Reference in a new issue