Skip to content

Commit

Permalink
Add Nginx support for hosting static contents (#15)
Browse files Browse the repository at this point in the history
* try to use name as webhook url

* fixed wrong url

* add nginx conf template and separated server configs

* changed to SERVER LISTEN

* add configs and scripts for serving static assets

* fixed typo

* updated readme

* updated readme and .env.toml

* updated readme add shields.io

* updated links

* updated LICENSE
  • Loading branch information
ravachol-yang committed Mar 27, 2024
1 parent 17096ef commit 4fc6dce
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 31 deletions.
20 changes: 15 additions & 5 deletions .env.toml
Original file line number Diff line number Diff line change
@@ -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
18 changes: 11 additions & 7 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -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 <sam@hocevar.net>

#0) HIOSCHIOHSCi(PSc()*S()C)(S*C)(
#1) alskndialsdiasdijas
#2) POSI)SV()jksbcjkasc
#3) POSJCIOSJC(JCWJKLklandla)
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.
88 changes: 78 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,93 @@
# Randomology
A telegram bot to generate random stuff, I built this to chat with my friend by randomly
<a href="https://github.com/ravachol-yang/randomology/actions"><img alt="GitHub Actions Workflow Status" src="https://img.shields.io/github/actions/workflow/status/ravachol-yang/randomology/pytest.yml?style=for-the-badge&logo=github&label=tests"></a> <a href="https://t.me/randomology_bot"><img alt="Static Badge" src="https://img.shields.io/badge/telegram-grey?style=for-the-badge&logo=telegram"></a>


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 &^$%^&*()_)(*&^*)
*(&%&^*&(*&%*^(&)))

<a href="https://github.com/ravachol-yang/randomology/blob/master/LICENSE"><img alt="GitHub License" src="https://img.shields.io/github/license/ravachol-yang/randomology?style=for-the-badge"></a>


4 changes: 4 additions & 0 deletions configs/dirs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
15 changes: 15 additions & 0 deletions configs/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
12 changes: 12 additions & 0 deletions link_storage.sh
Original file line number Diff line number Diff line change
@@ -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
27 changes: 27 additions & 0 deletions nginx.conf
Original file line number Diff line number Diff line change
@@ -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/;
}
}
2 changes: 2 additions & 0 deletions public/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
storage/**
storage
3 changes: 3 additions & 0 deletions public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# allow nobody !!!!!
User-agent: *
Disallow: /
21 changes: 12 additions & 9 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
)
Expand Down

0 comments on commit 4fc6dce

Please sign in to comment.