add server

This commit is contained in:
mihalin 2021-09-09 23:35:13 +03:00
parent fc9280881c
commit c1d29f4d8c
7 changed files with 117 additions and 13 deletions

View File

@ -7,6 +7,8 @@ services:
- release.env
volumes:
- database:/var/lib/postgresql/data
networks:
- traefik
redis:
image: 'bitnami/redis:latest'
restart: unless-stopped
@ -16,11 +18,21 @@ services:
- redis-db:/bitnami/redis/data
env_file:
- release.env
networks:
- traefik
olgram:
image: ghcr.io/civsocit/olgram/bot:stable
restart: unless-stopped
networks:
- traefik
labels:
- 'com.centurylinklabs.watchtower.enable="true"'
- "traefik.enable=true"
- "traefik.http.routers.static.rule=Host(`test.civsoc.it`)"
- "traefik.http.routers.static.tls=true"
- "traefik.http.routers.static.tls.certresolver=le"
- "traefik.http.routers.static.entrypoints=websecure"
- "traefik.docker.network=traefik"
env_file:
- release.env
depends_on:
@ -32,8 +44,40 @@ services:
- /var/run/docker.sock:/var/run/docker.sock
- ./config.json:/config.json
command: --interval 30
networks:
- traefik
traefik:
image: traefik:v2.4
container_name: olgram_traefik
restart: unless-stopped
ports:
- "80:80"
- "443:443"
networks:
- traefik
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./acme:/acme
command:
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --providers.docker=true
- --providers.docker.endpoint=unix:///var/run/docker.sock
- --providers.docker.exposedByDefault=false
- --providers.docker.network=traefik
- --certificatesresolvers.le.acme.email=youmustfly@civsoc.it
- --certificatesresolvers.le.acme.storage=/acme/acme.json
- --certificatesresolvers.le.acme.tlschallenge=false
- --certificatesresolvers.le.acme.httpchallenge=true
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
volumes:
database:
redis-db:
networks:
traefik:
driver: bridge

View File

@ -1,5 +1,6 @@
#!/bin/sh
set -e
sleep 20
aerich upgrade
python main.py

View File

@ -9,6 +9,8 @@ import olgram.commands.start # noqa: F401
import olgram.commands.menu # noqa: F401
import olgram.commands.bot_actions # noqa: F401
from server.server import main as server_main
async def init_database():
await Tortoise.init(config=TORTOISE_ORM)
@ -22,6 +24,7 @@ def main():
loop.run_until_complete(init_database())
loop.create_task(dp.start_polling())
loop.create_task(server_main().start())
loop.run_forever()

View File

@ -0,0 +1,5 @@
-- upgrade --
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
ALTER TABLE "bot" ADD "code" UUID NOT NULL DEFAULT uuid_generate_v4();
-- downgrade --
ALTER TABLE "bot" DROP COLUMN "code";

View File

@ -1,6 +1,6 @@
from tortoise.models import Model
from tortoise import fields
from uuid import uuid4
from textwrap import dedent
@ -9,6 +9,7 @@ class Bot(Model):
token = fields.CharField(max_length=50, unique=True)
owner = fields.ForeignKeyField("models.User", related_name="bots")
name = fields.CharField(max_length=33)
code = fields.UUIDField(default=uuid4, index=True)
start_text = fields.TextField(default=dedent("""
Здравствуйте!
Напишите ваш вопрос и мы ответим вам в ближайшее время.

View File

@ -38,6 +38,14 @@ class ServerSettings(AbstractSettings):
def hook_port(cls) -> int:
return int(cls._get_env("WEBHOOK_PORT"))
@classmethod
def app_host(cls) -> str:
return "olgram"
@classmethod
def app_port(cls) -> int:
return 80
class BotSettings(AbstractSettings):
@classmethod

View File

@ -1,26 +1,31 @@
from aiogram import Bot
import hashlib
from aiogram import Bot as AioBot, Dispatcher
from aiogram.dispatcher.webhook import SendMessage, WebhookRequestHandler
from olgram.models.models import Bot
from aiohttp import web
import asyncio
import aiohttp
from olgram.settings import ServerSettings
def path_for_bot(token: str) -> str:
return "/" + hashlib.md5(token.encode("UTF-8")).hexdigest()
def path_for_bot(bot: Bot) -> str:
return "/" + bot.code
def url_for_bot(token: str) -> str:
return f"https://{ServerSettings.hook_host()}:{ServerSettings.hook_port()}" + path_for_bot(token)
def url_for_bot(bot: Bot) -> str:
return f"https://{ServerSettings.hook_host()}:{ServerSettings.hook_port()}" + path_for_bot(bot)
async def register_token(token: str) -> bool:
async def register_token(bot: Bot) -> bool:
"""
Зарегистрировать токен
:param token: токен
:param bot: Бот
:return: получилось ли
"""
bot = Bot(token)
res = await bot.set_webhook(url_for_bot(token))
await bot.session.close()
a_bot = AioBot(bot.token)
res = await a_bot.set_webhook(url_for_bot(bot))
await a_bot.session.close()
return res
@ -30,5 +35,42 @@ async def unregister_token(token: str):
:param token: токен
:return:
"""
bot = Bot(token)
bot = AioBot(token)
await bot.delete_webhook()
async def cmd_start(message, *args, **kwargs):
return SendMessage(chat_id=message.chat.id, text=f'Hi from webhook, bot {message.via_bot}',
reply_to_message_id=message.message_id)
class CustomRequestHandler(WebhookRequestHandler):
def get_dispatcher(self):
"""
Get Dispatcher instance from environment
:return: :class:`aiogram.Dispatcher`
"""
key = self.request.url.path[1:]
bot = await Bot.filter(code=key).first()
if not bot:
return None
dp = Dispatcher(AioBot(bot.token))
dp.register_message_handler(cmd_start, commands=['start'])
return dp
def main():
loop = asyncio.get_event_loop()
app = web.Application()
app.router.add_route('*', r"/{name}", CustomRequestHandler, name='webhook_handler')
runner = aiohttp.web.AppRunner(app)
loop.run_until_complete(runner.setup())
site = aiohttp.web.TCPSite(runner, host=ServerSettings.app_host(), port=ServerSettings.app_port())
return site