diff --git a/.env.toml b/.env.toml index 0210dcb..d738f3c 100644 --- a/.env.toml +++ b/.env.toml @@ -1,12 +1,22 @@ +# bot main configuration [bot] -token = "" -environment = "" +token = "" # your bot token here +name = "" # your bot name, for webhook uri +environment = "" # "prod" or "dev" +# for server of this bot [server] host = "" -port = 443 +port = 8443 listen = "0.0.0.0" +# webhook configuration, can be same as [server], +# change if your are behind a proxy +[webhook] +host = "" +port = 443 + +# telegram webhook requires ssl [ssl] -cert = "" -priv = "" +cert = "" # path to your fullchain.pem +priv = "" # path to your priv.pem diff --git a/LICENSE b/LICENSE index 5a75dd2..8cffccc 100644 --- a/LICENSE +++ b/LICENSE @@ -1,9 +1,13 @@ -Random Public License (v1.1279127389172371293) + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 -%$%^&()*Y*(HUIBXGSHJBUOSXUIHSUCIOHU(USISC(U)))ascascascasc -OX8C()*()CS*()S*C)(SUCSO + Copyright (C) 2004 Sam Hocevar -#0) HIOSCHIOHSCi(PSc()*S()C)(S*C)( -#1) alskndialsdiasdijas -#2) POSI)SV()jksbcjkasc -#3) POSJCIOSJC(JCWJKLklandla) \ No newline at end of file + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. \ No newline at end of file diff --git a/README.md b/README.md index e331c09..140ada0 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,93 @@ # Randomology -A telegram bot to generate random stuff, I built this to chat with my friend by randomly +GitHub Actions Workflow Status Static Badge + + +A telegram bot to generate random stuff, I built this to chat with my friend randomly. +Using [pyTelegramBotAPI](https://github.com/eternnoir/pyTelegramBotAPI) for talking with telegram server. +The project structure is inspired by classic MVC web frameworks.. ## Dependency -- pyTelegrambotAPI -- pytest (dev) -- ffmpeg-python +Install system dependencies: +`ffmpeg` (for converting media), +`nginx` (optional, for hosting static resources & proxy) +``` shell +# this is an example for debian-based distros +sudo apt-get install ffmpeg +# optional but highly recommanded +sudo apt-get install nginx +``` +Use pip to install dependencies in `requirements.txt` ``` shell python3 -m pip install -r requirements.txt ``` -## Testing -run pytest +## Test && Deploy +The bot uses webhook in production environment, you will need a server reachable for telegram server and has `https` support (unless you want to use infinity polling...) +**Here we go !!!!** +### Configuration +This repo includes a config example `.env.toml`. +Copy the example config and change it to meet your own environment: +``` shell +# copy the config example, don't forget to change it +cp .env.toml env.toml +``` +in `env.toml`: +``` toml +[bot] +token = "" # your token here +name = "" # your bot name, for webhook uri +environment = "prod" # "prod" for production environment + +[server] +host = "example.com" # set your own +port = 8443 +listen = "0.0.0.0" + +[webhook] +host = "" +port = 443 +[ssl] +cert = "/path/to/fullchain.pem" +priv = "/path/to/priv.pem" +``` +### Testing +run `pytest` && check if every test passes ``` shell python3 -m pytest ``` - -## Running -In the project directory +### Hosting static resources +Static resources are hosted in `public/` and the bot-generated contents are under `storage/`, use `link_storage.sh` to create a symlic: +``` shell +./link_storage.sh +# to remove it: +# ./link_storage.sh remove +``` +copy and change the config file to configure Nginx: +``` shell +cp nginx.conf /etc/nginx/sites-available/example.com +# don't forget to change it !! +ln /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled +``` +restart `nginx.service` +### Running +In the project directory, run `python3` ``` shell python3 bot.py ``` +> if you don't have https: +telegram only allow webhooks with https, but you can still use `polling`: +in `env.toml`,set `bot.environment` to `"dev"`: + +``` toml +[bot] +environment = "dev" +``` +now you can run it ! + ## LICENSE -random LICENSE &^$%^&*()_)(*&^*) +*(&%&^*&(*&%*^(&))) + +GitHub License + + diff --git a/configs/dirs.py b/configs/dirs.py index e17d92a..f934b23 100644 --- a/configs/dirs.py +++ b/configs/dirs.py @@ -5,3 +5,7 @@ ROOT_DIR = os.path.dirname(os.path.dirname(__file__)) STORAGE_DIR = os.path.join(ROOT_DIR, "storage") AUDIO_DIR = os.path.join(STORAGE_DIR, "audio") + +PUBLIC_DIR = os.path.join(ROOT_DIR, "public") +PUBLIC_STORAGE_DIR = os.path.join(PUBLIC_DIR, "storage") +PUBLIC_AUDIO_DIR = os.path.join(PUBLIC_STORAGE_DIR, "audio") diff --git a/configs/env.py b/configs/env.py index bc8433f..1550d25 100644 --- a/configs/env.py +++ b/configs/env.py @@ -6,6 +6,11 @@ key = "token", default="") +# the bot name +BOT_NAME = env(section = "bot", + key = "name", + default = "randomology") + # environment, dev or prod BOT_ENVIRONMENT = env(section = "bot", key = "environment", @@ -26,6 +31,16 @@ key = "listen", default = "0.0.0.0") +# host for your webhook endpoint, defualt to SERVER_HOST +WEBHOOK_HOST = env(section = "webhook", + key = "host", + default = SERVER_HOST) + +# port for your webhook endpoint, defualt to SERVER_PORT +WEBHOOK_PORT = env(section = "webhook", + key = "port", + default = SERVER_PORT) + # path to your ssl cert file SSL_CERT = env(section = "ssl", key = "cert", diff --git a/link_storage.sh b/link_storage.sh new file mode 100755 index 0000000..0aa8ed2 --- /dev/null +++ b/link_storage.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +FROM=$(pwd)/storage +TO=$(pwd)/public/storage + +if [[ $1 == "remove" ]]; then + rm $TO -v +elif [[ -e $TO ]]; then + echo $TO "already exists" +else + ln -s $FROM $TO -v +fi diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..01e2d8a --- /dev/null +++ b/nginx.conf @@ -0,0 +1,27 @@ +# Nginx config template +# Don't forget to change it to meet your own env + +server { + listen 80; + listen 443 ssl; + listen [::]:443 ssl; + + server_name example.com; + + ssl_certificate /path/to/fullchain.pem; + ssl_certificate_key /path/to/privkey.pem; + + # redirect to https + if ($scheme = http) { + return 301 https://$server_name$request_uri; + } + + location / { + root /var/www/example.com/public; + } + + # your webhook + location /your-webhook-uri { + proxy_pass http://127.0.0.1:8443/your-webhook-uri/; + } +} diff --git a/public/.gitignore b/public/.gitignore new file mode 100644 index 0000000..af9bc10 --- /dev/null +++ b/public/.gitignore @@ -0,0 +1,2 @@ +storage/** +storage diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..abce8b6 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,3 @@ +# allow nobody !!!!! +User-agent: * +Disallow: / diff --git a/server.py b/server.py index 11bd70d..59712e4 100644 --- a/server.py +++ b/server.py @@ -8,24 +8,27 @@ from telebot import TeleBot -TOKEN = env.BOT_TOKEN +BOT_NAME = env.BOT_NAME -HOST = env.SERVER_HOST -PORT = env.SERVER_PORT -LISTEN = env.SERVER_LISTEN +SERVER_HOST = env.SERVER_HOST +SERVER_PORT = env.SERVER_PORT +SERVER_LISTEN = env.SERVER_LISTEN + +WEBHOOK_HOST = env.WEBHOOK_HOST +WEBHOOK_PORT = env.WEBHOOK_PORT SSL_CERT = env.SSL_CERT SSL_PRIV = env.SSL_PRIV -URL_BASE = "https://{}:{}".format(HOST, PORT) -URL_PATH = "/{}/".format(TOKEN) +URL_BASE = "https://{}:{}".format(WEBHOOK_HOST, WEBHOOK_PORT) +URL_PATH = "/{}/".format(BOT_NAME) # when in production def run(bot:TeleBot): # create the app app = fastapi.FastAPI(docs=None, redoc_url=None) - @app.post(f'/{TOKEN}/') + @app.post(f'/{BOT_NAME}/') def process_webhook(update:dict): if update: update = telebot.types.Update.de_json(update) @@ -44,8 +47,8 @@ def process_webhook(update:dict): # run the server uvicorn.run( app, - host=HOST, - port=PORT, + host=SERVER_LISTEN, + port=SERVER_PORT, ssl_certfile=SSL_CERT, ssl_keyfile=SSL_PRIV )