squashed
This commit is contained in:
commit
2ee1722836
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
local.env
|
||||
**/*.pyc
|
||||
test/
|
||||
newsmaker.session
|
||||
newsmaker.session-journal
|
||||
newsmaker.session.bup
|
27
.vscode/launch.json
vendored
Normal file
27
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
|
||||
|
||||
{
|
||||
"name": "Python Debugger: main.py",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "src/main.py",
|
||||
"console": "integratedTerminal",
|
||||
"envFile": "${workspaceFolder}/local.env"
|
||||
},
|
||||
{
|
||||
"name": "Python Debugger: signin.py",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"program": "src/signin.py",
|
||||
"console": "integratedTerminal",
|
||||
"envFile": "${workspaceFolder}/local.env"
|
||||
}
|
||||
]
|
||||
}
|
13
Dockerfile
Normal file
13
Dockerfile
Normal file
@ -0,0 +1,13 @@
|
||||
FROM python:3.10
|
||||
|
||||
RUN apt-get install libpq-dev -y
|
||||
|
||||
ADD requirements.txt requirements.txt
|
||||
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
ADD src /app
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENTRYPOINT [ "python", "./main.py" ]
|
44
docker-compose.yaml
Normal file
44
docker-compose.yaml
Normal file
@ -0,0 +1,44 @@
|
||||
version: '3.3'
|
||||
|
||||
networks:
|
||||
jedoist:
|
||||
external: true
|
||||
|
||||
services:
|
||||
|
||||
bot:
|
||||
# build: ./
|
||||
image: localhost:5001/jedoist:${APP_VERSION}
|
||||
environment:
|
||||
- BOT_TOKEN=${BOT_TOKEN}
|
||||
- VK_CLIENT_ID=${VK_CLIENT_ID}
|
||||
- VK_SECRET_KEY=${VK_SECRET_KEY}
|
||||
- BOT_OWNER_ID=258985362
|
||||
- DB_HOST=jedoist-db
|
||||
- DB_NAME=jedoist-db
|
||||
- DB_USER=${DB_USER}
|
||||
- DB_PASS=${DB_PASS}
|
||||
- VOICES_PATH=${VOICES_PATH}
|
||||
- CONFIG_FILE=/mnt/config.json
|
||||
restart: always
|
||||
depends_on:
|
||||
- bot-db
|
||||
networks:
|
||||
- jedoist
|
||||
volumes:
|
||||
- ${CONFIG_FILE}:/mnt/config.json
|
||||
|
||||
bot-db:
|
||||
image: postgres:14
|
||||
container_name: jedoist-db
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_USER: ${DB_USER}
|
||||
POSTGRES_PASSWORD: ${DB_PASS}
|
||||
POSTGRES_DB: jedoist-db
|
||||
networks:
|
||||
- jedoist
|
||||
volumes:
|
||||
- ${DB_VOLUME}:/var/lib/postgresql/data
|
||||
ports:
|
||||
- 5432:5432
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
aiohttp==3.9.5
|
||||
telethon==1.36.0
|
11
src/bot/__init__.py
Normal file
11
src/bot/__init__.py
Normal file
@ -0,0 +1,11 @@
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Get the current script's directory
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# Get the parent directory by going one level up
|
||||
parent_dir = os.path.dirname(current_dir)
|
||||
|
||||
# Add the parent directory to sys.path
|
||||
sys.path.append(parent_dir)
|
124
src/bot/bot.py
Normal file
124
src/bot/bot.py
Normal file
@ -0,0 +1,124 @@
|
||||
from settings import config
|
||||
import logging
|
||||
import re
|
||||
from telethon import TelegramClient, events
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
class Bot():
|
||||
|
||||
def __init__(self,
|
||||
session_file: str,
|
||||
config_file: str,
|
||||
api_id: str,
|
||||
api_hash: int,
|
||||
owner_id: int) -> None:
|
||||
self.__config_file = config_file
|
||||
self.__config = None
|
||||
self.__me = None
|
||||
self.__owner_id = owner_id
|
||||
self.__reload()
|
||||
self.__bot = TelegramClient(session_file, api_id, api_hash)
|
||||
|
||||
@self.__bot.on(events.NewMessage(incoming=True, pattern='!whoami'))
|
||||
async def onMessageWhoami(event):
|
||||
await event.reply("{0}".format(event.chat_id))
|
||||
await self.__bot.send_read_acknowledge(event.chat_id, event.message)
|
||||
raise events.StopPropagation
|
||||
|
||||
@self.__bot.on(events.NewMessage(incoming=True, pattern="!reload"))
|
||||
async def onMessageReload(event):
|
||||
self.__reload()
|
||||
await event.reply("Reloaded")
|
||||
await self.__bot.send_read_acknowledge(event.chat_id, event.message)
|
||||
raise events.StopPropagation
|
||||
|
||||
@self.__bot.on(events.NewMessage(incoming=True, pattern="!chats"))
|
||||
async def onMessageChats(event):
|
||||
await self.__send_all_chats_to_owner()
|
||||
await self.__bot.send_read_acknowledge(event.chat_id, event.message)
|
||||
raise events.StopPropagation
|
||||
|
||||
@self.__bot.on(events.ChatAction)
|
||||
async def onChatAction(event):
|
||||
if event.user_left and event.user.id == self.__me:
|
||||
await self.__bot.send_message(owner_id, "Я вышел из чата: {0}".format(event.chat_id))
|
||||
if event.user_joined and event.user.id == self.__me:
|
||||
await self.__bot.send_message(owner_id, "Я вошел в чат: {0}".format(event.chat_id))
|
||||
|
||||
@self.__bot.on(events.NewMessage(incoming=True))
|
||||
async def onNewMessage(event):
|
||||
if event.message is None:
|
||||
return
|
||||
chat_id = event.chat_id
|
||||
message = event.message
|
||||
logger.debug("Received message in chat {0}: {1}".format(chat_id, message.text if not message == None else "<No Text>"))
|
||||
await self.__process_message(event, chat_id, message)
|
||||
|
||||
def start(self) -> None:
|
||||
self.__bot.start()
|
||||
self.__bot.loop.run_until_complete(self.__identity())
|
||||
self.__bot.run_until_disconnected()
|
||||
|
||||
def __reload(self) -> None:
|
||||
self.__config = config.Config(filename=self.__config_file)
|
||||
|
||||
async def __send_all_chats_to_owner(self) -> None:
|
||||
text = ""
|
||||
async for dialog in self.__bot.iter_dialogs():
|
||||
text = text + "{0} - {1}\n".format(dialog.id, dialog.name)
|
||||
await self.__bot.send_message(self.__owner_id, text)
|
||||
|
||||
async def __process_message(self, event, chat_id, message):
|
||||
configs = self.__config.get_on_message_for_chat_id(chat_id)
|
||||
if configs == None:
|
||||
return
|
||||
if not isinstance(configs, list):
|
||||
return
|
||||
for config in configs:
|
||||
filter = config['filter'] if 'filter' in config else None
|
||||
action = config['action'] if 'action' in config else None
|
||||
action_type = action['type'] if 'type' in action else None
|
||||
if action == None or action_type == None:
|
||||
return
|
||||
if not filter == None:
|
||||
if await self.__needs_skip(filter, message):
|
||||
return
|
||||
if action_type == 'forward':
|
||||
destination = action['chatId'] if 'chatId' in action else None
|
||||
if destination == None:
|
||||
return
|
||||
await event.forward_to(destination)
|
||||
|
||||
async def __needs_skip(self, filter: dict, message) -> bool:
|
||||
filter_type = filter['type'] if 'type' in filter else None
|
||||
filter_value = filter['value'] if 'value' in filter else None
|
||||
if filter_type == None or filter_value == None:
|
||||
return True
|
||||
text = str(message.text)
|
||||
if text == None:
|
||||
if not message.reply_to == None:
|
||||
reply = await self.__get_reply(message.chat_id, message)
|
||||
return await self.__needs_skip(filter, reply)
|
||||
return True
|
||||
if filter_type == 'contain':
|
||||
if text.find(filter_value) == -1:
|
||||
if not message.reply_to == None:
|
||||
reply = await self.__get_reply(message.chat_id, message)
|
||||
return await self.__needs_skip(filter, reply)
|
||||
return True
|
||||
elif filter_type == 'regexp':
|
||||
if not re.match(filter_value, text):
|
||||
if not message.reply_to == None:
|
||||
reply = await self.__get_reply(message.chat_id, message)
|
||||
return await self.__needs_skip(filter, reply)
|
||||
return True
|
||||
return False
|
||||
|
||||
async def __get_reply(self, chat_id, message):
|
||||
return await self.__bot.get_messages(chat_id, ids=message.reply_to.reply_to_msg_id)
|
||||
|
||||
async def __identity(self) -> None:
|
||||
me = await self.__bot.get_me()
|
||||
self.__me = me.id
|
20
src/main.py
Normal file
20
src/main.py
Normal file
@ -0,0 +1,20 @@
|
||||
import os
|
||||
from bot.bot import Bot
|
||||
import logging
|
||||
|
||||
logging.basicConfig(format="%(asctime)s | %(name)s | %(levelname)s | %(message)s")
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
if __name__ == "__main__":
|
||||
session_file = os.environ['SESSION_FILE']
|
||||
api_id = os.environ['TG_APP_ID']
|
||||
api_hash = os.environ['TG_APP_HASH']
|
||||
owner_id = int(os.environ['TG_OWNER_ID'])
|
||||
config_file = os.environ['CONFIG_FILE']
|
||||
bot = Bot(session_file=session_file,
|
||||
api_id=api_id,
|
||||
api_hash=api_hash,
|
||||
config_file=config_file,
|
||||
owner_id=owner_id)
|
||||
bot.start()
|
11
src/settings/__init__.py
Normal file
11
src/settings/__init__.py
Normal file
@ -0,0 +1,11 @@
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Get the current script's directory
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# Get the parent directory by going one level up
|
||||
parent_dir = os.path.dirname(current_dir)
|
||||
|
||||
# Add the parent directory to sys.path
|
||||
sys.path.append(parent_dir)
|
21
src/settings/config.py
Normal file
21
src/settings/config.py
Normal file
@ -0,0 +1,21 @@
|
||||
import json
|
||||
from typing import Optional
|
||||
|
||||
class Config():
|
||||
|
||||
def __init__(self, filename: str) -> None:
|
||||
self.__filename = filename
|
||||
self.__config = {}
|
||||
self.__read()
|
||||
|
||||
def get_on_message_for_chat_id(self, chat_id: int) -> Optional[dict]:
|
||||
chat_id_str = str(chat_id)
|
||||
if 'onMessage' in self.__config:
|
||||
on_message = self.__config['onMessage']
|
||||
if chat_id_str in on_message:
|
||||
return on_message[chat_id_str]
|
||||
return None
|
||||
|
||||
def __read(self) -> None:
|
||||
with open(self.__filename, 'r') as f:
|
||||
self.__config = json.load(f)
|
10
src/signin.py
Normal file
10
src/signin.py
Normal file
@ -0,0 +1,10 @@
|
||||
import os
|
||||
from telethon import TelegramClient
|
||||
|
||||
# Use your own values from my.telegram.org
|
||||
api_id = os.environ['TG_APP_ID']
|
||||
api_hash = os.environ['TG_APP_HASH']
|
||||
|
||||
# The first parameter is the .session file name (absolute paths allowed)
|
||||
with TelegramClient('newsmaker.session', api_id, api_hash) as client:
|
||||
client.loop.run_until_complete(client.send_message('me', 'Hello, myself!'))
|
Loading…
Reference in New Issue
Block a user