From 2aaf419dc6c9dabddb95b613a49a6ebda73caae4 Mon Sep 17 00:00:00 2001 From: Anton Zelinsky Date: Sun, 14 May 2023 18:18:40 +0200 Subject: [PATCH 01/29] Update front sub module --- front | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front b/front index 5348e36..50ccf3b 160000 --- a/front +++ b/front @@ -1 +1 @@ -Subproject commit 5348e3632d0db5bd29791e5a5c4f6ce6fd9a2a3f +Subproject commit 50ccf3b0981195a09bf092309e38eab13ca57fd5 From c9fbbeff730846c1d937f8ea069b94810d175519 Mon Sep 17 00:00:00 2001 From: Levon Gegamyan Date: Mon, 15 May 2023 20:03:39 +0300 Subject: [PATCH 02/29] Add user's Telegram ID to start message --- bot/common_comands.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bot/common_comands.py b/bot/common_comands.py index 86842a2..5b9ce8f 100644 --- a/bot/common_comands.py +++ b/bot/common_comands.py @@ -72,7 +72,8 @@ def start(update: Update, context: CallbackContext) -> int: text='Привет! 👋 \n\n' f'Я бот платформы интеллектуального волонтерства ProCharity. ' 'Буду держать тебя в курсе новых задач и помогу ' - 'оперативно связаться с командой поддержки.', + 'оперативно связаться с командой поддержки.\n' + f'Ваш телеграм id – {update.effective_user.id}', reply_markup=keyboard, parse_mode=ParseMode.HTML, disable_web_page_preview=True ) From ed1a994dcd13b25661841db2220324a6ba369c11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D0=B0=D1=80=D1=8C=D0=B5=D0=B2?= Date: Mon, 15 May 2023 21:09:54 +0300 Subject: [PATCH 03/29] Add button to start to messsage --- .env.dev | 17 ----------------- bot/common_comands.py | 4 ++++ 2 files changed, 4 insertions(+), 17 deletions(-) delete mode 100644 .env.dev diff --git a/.env.dev b/.env.dev deleted file mode 100644 index a141c00..0000000 --- a/.env.dev +++ /dev/null @@ -1,17 +0,0 @@ -TOKEN= -MAIL_PASSWORD= -MAIL_SERVER=smtp.gmail.com -MAIL_PORT=587 -MAIL_USE_TLS=True -MAIL_USERNAME= -MAIL_DEFAULT_SENDER= -EMAIL_PROCHARRITY= -HOST_NAME= -ACCESS_TOKEN_FOR_PROCHARITY= -USE_WEBHOOK= -TOKEN_FOR_WEBHOOKS= -POSTGRES_HOST= -POSTGRES_PORT= -POSTGRES_DB= -POSTGRES_USER= -POSTGRES_PASSWORD= \ No newline at end of file diff --git a/bot/common_comands.py b/bot/common_comands.py index 86842a2..0597aac 100644 --- a/bot/common_comands.py +++ b/bot/common_comands.py @@ -64,6 +64,10 @@ def start(update: Update, context: CallbackContext) -> int: button = [ [ InlineKeyboardButton(text='Начнем', callback_data=callback_data) + ], + [ + InlineKeyboardButton(text='Связать аккаунт с ботом', + url='https://procharity.ru/') ] ] keyboard = InlineKeyboardMarkup(button) From 4d96e4dc7a1ee37abf21e22b2f700751fe116ec7 Mon Sep 17 00:00:00 2001 From: Levon Gegamyan Date: Tue, 16 May 2023 22:47:18 +0300 Subject: [PATCH 04/29] added endpoint api/v1/send_telegram_message --- app/front/__init__.py | 3 + app/front/send_tg_message_to_user.py | 107 +++++++++++++++++++++++++++ app/front/swagger_front.py | 2 + bot/messages.py | 43 ++++++++++- 4 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 app/front/send_tg_message_to_user.py diff --git a/app/front/__init__.py b/app/front/__init__.py index f55a36c..71e7ee2 100644 --- a/app/front/__init__.py +++ b/app/front/__init__.py @@ -7,12 +7,15 @@ from . import analytics from . import send_tg_notification +from . import send_tg_message_to_user from . import users from . import download_log_files front_api.add_resource(analytics.Analytics, '/api/v1/analytics/') front_api.add_resource(send_tg_notification.SendTelegramNotification, '/api/v1/send_telegram_notification/') +front_api.add_resource(send_tg_message_to_user.SendTelegramMessage, + '/api/v1/send_telegram_message/') front_api.add_resource(users.UsersList, '/api/v1/users/') front_api.add_resource(users.UserItem, '/api/v1/users//') front_api.add_resource(download_log_files.DownloadLogs, '/api/v1/download_logs/') diff --git a/app/front/send_tg_message_to_user.py b/app/front/send_tg_message_to_user.py new file mode 100644 index 0000000..65114c4 --- /dev/null +++ b/app/front/send_tg_message_to_user.py @@ -0,0 +1,107 @@ +import datetime + +from flask import jsonify, make_response +from flask_apispec import doc, use_kwargs +from flask_apispec.views import MethodResource +from flask_jwt_extended import jwt_required, get_jwt_identity +from flask_restful import Resource +from marshmallow import fields, Schema +from sqlalchemy.exc import SQLAlchemyError + +from app import config +from app.database import db_session +from app.logger import app_logger as logger +from app.models import Notification + +from bot.messages import TelegramMessage + + +class TelegramMessageSchema(Schema): + message = fields.String(required=True) + telegram_id = fields.Integer(required=True) + + +class SendTelegramMessage(Resource, MethodResource): + + @doc(description='Sends message to the telegram user.' + 'Requires "message" and "telegram_id" parameters.', + summary='Send telegram messages to the bot chat', + tags=['Messages'], + responses={ + 200: {'description': 'The message has been sent'}, + 400: {'description': 'The message can not be empty'}, + }, + params={ + 'message': { + 'description': 'Message to user. Max len 4096', + 'in': 'query', + 'type': 'string', + 'required': True + }, + 'telegram_id': { + 'description': ( + 'Sending notification to user with this telegram id' + ), + 'in': 'query', + 'type': 'intger', + 'required': True + }, + 'Authorization': config.PARAM_HEADER_AUTH, + } + ) + @use_kwargs(TelegramMessageSchema) + @jwt_required() + def post(self, **kwargs): + message = kwargs.get('message').replace(' ', '') + telegram_id = kwargs.get('telegram_id') + + if not message or not telegram_id: + logger.info( + 'Messages: The and ' + 'parameters have not been passed' + ) + return make_response( + jsonify( + result=( + 'Необходимо указать параметры ' + ' и .' + ) + ), 400 + ) + + authorized_user = get_jwt_identity() + message = Notification(message=message, sent_by=authorized_user) + db_session.add(message) + try: + db_session.commit() + mesg = TelegramMessage(telegram_id) + + if not mesg.send_message(message=message.message): + logger.info( + 'Messages: Passed invalid parameter. ' + f'Passed: {telegram_id}' + ) + return make_response( + jsonify( + result=('Неверно указан параметр . ' + 'Сообщение не отправлено.')), 400 + ) + + message.was_sent = True + message.sent_date = datetime.datetime.now() + db_session.commit() + + except SQLAlchemyError as ex: + logger.error(f'Messages: Database commit error "{str(ex)}"') + db_session.rollback() + return make_response( + jsonify(message=f'Bad request: {str(ex)}'), 400 + ) + + logger.info(f'Messages: The message "{message.message}" ' + 'has been successfully sent to user') + return make_response( + jsonify( + result="Сообщение успешно отправлено пользователю." + ), 200 + ) diff --git a/app/front/swagger_front.py b/app/front/swagger_front.py index 5ebcaa2..d73460b 100644 --- a/app/front/swagger_front.py +++ b/app/front/swagger_front.py @@ -3,10 +3,12 @@ from app.front.download_log_files import DownloadLogs, GetListLogFiles from app.front.users import UsersList, UserItem from app.front.send_tg_notification import SendTelegramNotification +from app.front.send_tg_message_to_user import SendTelegramMessage docs.register(Analytics, blueprint='front_bp') docs.register(SendTelegramNotification, blueprint='front_bp') +docs.register(SendTelegramMessage, blueprint='front_bp') docs.register(UsersList, blueprint='front_bp') docs.register(UserItem, blueprint='front_bp') docs.register(DownloadLogs, blueprint='front_bp') diff --git a/bot/messages.py b/bot/messages.py index 7c23a53..d9f6df5 100644 --- a/bot/messages.py +++ b/bot/messages.py @@ -1,10 +1,8 @@ from telegram import Bot, ParseMode, error from telegram.error import Unauthorized -import datetime import time from dataclasses import dataclass from typing import List -import pytz from app import config from app.database import db_session @@ -107,3 +105,44 @@ def __split_chats(array, size): array = array[size:] arrs.append(array) return arrs + + +class TelegramMessage: + """ + This class describes the functionality for + working with message to user in Telegram. + """ + + def __init__(self, telegram_id: int) -> None: + self.telegram_id = telegram_id + + def send_message(self, message) -> bool: + """ + Send telegram message to user. + + :param message: Message to send + :return: + """ + + if not db_session.query( + User + ).filter(User.telegram_id == self.telegram_id): + logger.error( + f'User with telegram id "{self.telegram_id}" does not exist' + ) + return False + try: + bot.send_message( + chat_id=self.telegram_id, text=message, + parse_mode=ParseMode.HTML, disable_web_page_preview=True) + logger.info(f'Sent message to {self.telegram_id}') + return True + except error.BadRequest as ex: + logger.error(f'{str(ex.message)}, telegram_id: {self.telegram_id}') + except Unauthorized as ex: + logger.error(f'{str(ex.message)}: {self.telegram_id}') + User.query.filter_by( + telegram_id=self.telegram_id + ).update({'banned': True, 'has_mailing': False}) + db_session.commit() + return False From 082366e2bf029925790c7ec77a58567fcc258eef Mon Sep 17 00:00:00 2001 From: Levon Gegamyan Date: Wed, 17 May 2023 21:34:44 +0300 Subject: [PATCH 05/29] fix typo --- app/front/send_tg_message_to_user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/front/send_tg_message_to_user.py b/app/front/send_tg_message_to_user.py index 65114c4..802f49d 100644 --- a/app/front/send_tg_message_to_user.py +++ b/app/front/send_tg_message_to_user.py @@ -43,7 +43,7 @@ class SendTelegramMessage(Resource, MethodResource): 'Sending notification to user with this telegram id' ), 'in': 'query', - 'type': 'intger', + 'type': 'integer', 'required': True }, 'Authorization': config.PARAM_HEADER_AUTH, From 03a234d25a6b48283ea0cb405cf1d256fe411f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D0=B0=D1=80=D1=8C=D0=B5=D0=B2?= Date: Thu, 18 May 2023 21:55:14 +0300 Subject: [PATCH 06/29] fix isort --- app/front/send_tg_message_to_user.py | 5 ++--- bot/messages.py | 5 +++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/front/send_tg_message_to_user.py b/app/front/send_tg_message_to_user.py index 802f49d..5754c88 100644 --- a/app/front/send_tg_message_to_user.py +++ b/app/front/send_tg_message_to_user.py @@ -3,16 +3,15 @@ from flask import jsonify, make_response from flask_apispec import doc, use_kwargs from flask_apispec.views import MethodResource -from flask_jwt_extended import jwt_required, get_jwt_identity +from flask_jwt_extended import get_jwt_identity, jwt_required from flask_restful import Resource -from marshmallow import fields, Schema +from marshmallow import Schema, fields from sqlalchemy.exc import SQLAlchemyError from app import config from app.database import db_session from app.logger import app_logger as logger from app.models import Notification - from bot.messages import TelegramMessage diff --git a/bot/messages.py b/bot/messages.py index d9f6df5..31bf115 100644 --- a/bot/messages.py +++ b/bot/messages.py @@ -1,9 +1,10 @@ -from telegram import Bot, ParseMode, error -from telegram.error import Unauthorized import time from dataclasses import dataclass from typing import List +from telegram import Bot, ParseMode, error +from telegram.error import Unauthorized + from app import config from app.database import db_session from app.logger import bot_logger as logger From 2da260fb1af6257f0bc54273d80e81981773ca18 Mon Sep 17 00:00:00 2001 From: Levon Gegamyan Date: Fri, 19 May 2023 18:40:15 +0300 Subject: [PATCH 07/29] add extra \n --- bot/common_comands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/common_comands.py b/bot/common_comands.py index 5b9ce8f..a3ce29e 100644 --- a/bot/common_comands.py +++ b/bot/common_comands.py @@ -72,7 +72,7 @@ def start(update: Update, context: CallbackContext) -> int: text='Привет! 👋 \n\n' f'Я бот платформы интеллектуального волонтерства ProCharity. ' 'Буду держать тебя в курсе новых задач и помогу ' - 'оперативно связаться с командой поддержки.\n' + 'оперативно связаться с командой поддержки.\n\n' f'Ваш телеграм id – {update.effective_user.id}', reply_markup=keyboard, parse_mode=ParseMode.HTML, disable_web_page_preview=True From c19327ecd5a831eae4da1867487023156ce7dd48 Mon Sep 17 00:00:00 2001 From: Levon Gegamyan Date: Fri, 19 May 2023 18:50:52 +0300 Subject: [PATCH 08/29] change telegram_id from body to path parameters --- app/front/__init__.py | 2 +- app/front/send_tg_message_to_user.py | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/front/__init__.py b/app/front/__init__.py index 71e7ee2..a697a0a 100644 --- a/app/front/__init__.py +++ b/app/front/__init__.py @@ -15,7 +15,7 @@ front_api.add_resource(send_tg_notification.SendTelegramNotification, '/api/v1/send_telegram_notification/') front_api.add_resource(send_tg_message_to_user.SendTelegramMessage, - '/api/v1/send_telegram_message/') + '/api/v1/messages/') front_api.add_resource(users.UsersList, '/api/v1/users/') front_api.add_resource(users.UserItem, '/api/v1/users//') front_api.add_resource(download_log_files.DownloadLogs, '/api/v1/download_logs/') diff --git a/app/front/send_tg_message_to_user.py b/app/front/send_tg_message_to_user.py index 5754c88..8e8d37c 100644 --- a/app/front/send_tg_message_to_user.py +++ b/app/front/send_tg_message_to_user.py @@ -17,7 +17,6 @@ class TelegramMessageSchema(Schema): message = fields.String(required=True) - telegram_id = fields.Integer(required=True) class SendTelegramMessage(Resource, MethodResource): @@ -41,7 +40,7 @@ class SendTelegramMessage(Resource, MethodResource): 'description': ( 'Sending notification to user with this telegram id' ), - 'in': 'query', + 'in': 'path', 'type': 'integer', 'required': True }, @@ -50,9 +49,8 @@ class SendTelegramMessage(Resource, MethodResource): ) @use_kwargs(TelegramMessageSchema) @jwt_required() - def post(self, **kwargs): + def post(self, telegram_id, **kwargs): message = kwargs.get('message').replace(' ', '') - telegram_id = kwargs.get('telegram_id') if not message or not telegram_id: logger.info( From 64fbeb0f01e22cc7dcc8af9b1ca04bc56150229c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D0=B0=D1=80=D1=8C=D0=B5=D0=B2?= Date: Fri, 19 May 2023 19:15:31 +0300 Subject: [PATCH 09/29] fixed the "buttons" variable --- .env.dev | 17 +++++++++++++++++ bot/common_comands.py | 4 ++-- 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 .env.dev diff --git a/.env.dev b/.env.dev new file mode 100644 index 0000000..a141c00 --- /dev/null +++ b/.env.dev @@ -0,0 +1,17 @@ +TOKEN= +MAIL_PASSWORD= +MAIL_SERVER=smtp.gmail.com +MAIL_PORT=587 +MAIL_USE_TLS=True +MAIL_USERNAME= +MAIL_DEFAULT_SENDER= +EMAIL_PROCHARRITY= +HOST_NAME= +ACCESS_TOKEN_FOR_PROCHARITY= +USE_WEBHOOK= +TOKEN_FOR_WEBHOOKS= +POSTGRES_HOST= +POSTGRES_PORT= +POSTGRES_DB= +POSTGRES_USER= +POSTGRES_PASSWORD= \ No newline at end of file diff --git a/bot/common_comands.py b/bot/common_comands.py index 0597aac..0b92e20 100644 --- a/bot/common_comands.py +++ b/bot/common_comands.py @@ -61,7 +61,7 @@ def start(update: Update, context: CallbackContext) -> int: callback_data = (command_constants.COMMAND__GREETING_REGISTERED_USER if user.categories else command_constants.COMMAND__GREETING) - button = [ + buttons = [ [ InlineKeyboardButton(text='Начнем', callback_data=callback_data) ], @@ -70,7 +70,7 @@ def start(update: Update, context: CallbackContext) -> int: url='https://procharity.ru/') ] ] - keyboard = InlineKeyboardMarkup(button) + keyboard = InlineKeyboardMarkup(buttons) context.bot.send_message( chat_id=update.effective_chat.id, text='Привет! 👋 \n\n' From 9439cbe5f3fdecbbebeb4c488513a1b9cdbc0423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=9C=D0=B0=D0=BA?= =?UTF-8?q?=D0=B0=D1=80=D1=8C=D0=B5=D0=B2?= Date: Sat, 20 May 2023 21:23:43 +0300 Subject: [PATCH 10/29] fix url --- app/front/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/front/__init__.py b/app/front/__init__.py index a697a0a..f60e876 100644 --- a/app/front/__init__.py +++ b/app/front/__init__.py @@ -15,7 +15,7 @@ front_api.add_resource(send_tg_notification.SendTelegramNotification, '/api/v1/send_telegram_notification/') front_api.add_resource(send_tg_message_to_user.SendTelegramMessage, - '/api/v1/messages/') + '/api/v1/messages//') front_api.add_resource(users.UsersList, '/api/v1/users/') front_api.add_resource(users.UserItem, '/api/v1/users//') front_api.add_resource(download_log_files.DownloadLogs, '/api/v1/download_logs/') From 132caa9c9298b53486b2fadb5a127002839dd47d Mon Sep 17 00:00:00 2001 From: Levon Gegamyan Date: Sun, 21 May 2023 20:36:55 +0300 Subject: [PATCH 11/29] move has_mailing from body to path parameters --- app/front/__init__.py | 2 +- app/front/send_tg_notification.py | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/front/__init__.py b/app/front/__init__.py index f55a36c..9107e13 100644 --- a/app/front/__init__.py +++ b/app/front/__init__.py @@ -12,7 +12,7 @@ front_api.add_resource(analytics.Analytics, '/api/v1/analytics/') front_api.add_resource(send_tg_notification.SendTelegramNotification, - '/api/v1/send_telegram_notification/') + '/api/v1/send_telegram_notification/') front_api.add_resource(users.UsersList, '/api/v1/users/') front_api.add_resource(users.UserItem, '/api/v1/users//') front_api.add_resource(download_log_files.DownloadLogs, '/api/v1/download_logs/') diff --git a/app/front/send_tg_notification.py b/app/front/send_tg_notification.py index 8211905..e0cab43 100644 --- a/app/front/send_tg_notification.py +++ b/app/front/send_tg_notification.py @@ -19,7 +19,6 @@ class TelegramNotificationSchema(Schema): message = fields.String(required=True) - has_mailing = fields.String(required=True) class SendTelegramNotification(Resource, MethodResource): @@ -41,11 +40,12 @@ class SendTelegramNotification(Resource, MethodResource): 'required': True }, 'has_mailing': { - 'description': ('Sending notifications to users by the type of permission to mailing.' + 'description': ('Sending notifications to users by the type ' + 'of permission to mailing.' 'subscribed - user has enabled a mailing.' 'unsubscribed - user has disabled a mailing.' 'all - send to all users'), - 'in': 'query', + 'in': 'path', 'type': 'string', 'required': True }, @@ -54,9 +54,8 @@ class SendTelegramNotification(Resource, MethodResource): ) @use_kwargs(TelegramNotificationSchema) @jwt_required() - def post(self, **kwargs): + def post(self, has_mailing, **kwargs): message = kwargs.get('message').replace(' ', '') - has_mailing = kwargs.get('has_mailing') if not message or not has_mailing: logger.info("Messages: The and parameters have not been passed") From 912ced654254cab8ef0fa383c3275b984e8e7a9e Mon Sep 17 00:00:00 2001 From: Levon Gegamyan Date: Tue, 23 May 2023 20:48:04 +0300 Subject: [PATCH 12/29] remove "has_mailing" parameter, add "mode" to body --- app/front/__init__.py | 2 +- app/front/send_tg_notification.py | 65 +++++++++++++++++-------- bot/messages.py | 79 ++++++++++++++++++++----------- 3 files changed, 99 insertions(+), 47 deletions(-) diff --git a/app/front/__init__.py b/app/front/__init__.py index 9107e13..2d50cc3 100644 --- a/app/front/__init__.py +++ b/app/front/__init__.py @@ -12,7 +12,7 @@ front_api.add_resource(analytics.Analytics, '/api/v1/analytics/') front_api.add_resource(send_tg_notification.SendTelegramNotification, - '/api/v1/send_telegram_notification/') + '/api/v1/messages/') front_api.add_resource(users.UsersList, '/api/v1/users/') front_api.add_resource(users.UserItem, '/api/v1/users//') front_api.add_resource(download_log_files.DownloadLogs, '/api/v1/download_logs/') diff --git a/app/front/send_tg_notification.py b/app/front/send_tg_notification.py index e0cab43..41d9381 100644 --- a/app/front/send_tg_notification.py +++ b/app/front/send_tg_notification.py @@ -16,16 +16,18 @@ from bot.messages import TelegramNotification - class TelegramNotificationSchema(Schema): message = fields.String(required=True) + mode = fields.String(required=True) class SendTelegramNotification(Resource, MethodResource): - @doc(description='Sends message to the Telegram chat. Requires "message" parameter.' - ' Messages can be sent either to subscribed users or not.To do this,' - ' specify the "has_mailing" parameter.Default value "True".', + @doc(description=( + 'Sends message to the Telegram chat. Requires "message" parameter.' + ' Messages can be sent either to subscribed users or not.To do ' + 'this, specify the "mode" parameter.Default value "subscribed".' + ), summary='Send messages to the bot chat', tags=['Messages'], responses={ @@ -39,39 +41,57 @@ class SendTelegramNotification(Resource, MethodResource): 'type': 'string', 'required': True }, - 'has_mailing': { + 'mode': { 'description': ('Sending notifications to users by the type ' 'of permission to mailing.' 'subscribed - user has enabled a mailing.' 'unsubscribed - user has disabled a mailing.' 'all - send to all users'), - 'in': 'path', + 'in': 'query', 'type': 'string', 'required': True }, - 'Authorization': config.PARAM_HEADER_AUTH, # Only if request requires authorization + 'Authorization': config.PARAM_HEADER_AUTH, + # Only if request requires authorization } ) @use_kwargs(TelegramNotificationSchema) @jwt_required() - def post(self, has_mailing, **kwargs): + def post(self, **kwargs): message = kwargs.get('message').replace(' ', '') + mode = kwargs.get('mode') - if not message or not has_mailing: - logger.info("Messages: The and parameters have not been passed") - return make_response(jsonify(result="Необходимо указать параметры и ."), 400) + if not message or not mode: + logger.info( + 'Messages: The and ' + 'parameters have not been passed' + ) + return make_response( + jsonify( + result='Необходимо указать параметры и .' + ), + 400 + ) authorized_user = get_jwt_identity() message = Notification(message=message, sent_by=authorized_user) db_session.add(message) try: db_session.commit() - job_queue = TelegramNotification(has_mailing) + job_queue = TelegramNotification(mode) if not job_queue.send_notification(message=message.message): - logger.info(f"Messages: Passed invalid parameter. Passed: {has_mailing}") - return make_response(jsonify(result=f"Неверно указан параметр . " - f"Сообщение не отправлено."), 400) + logger.info( + 'Messages: Passed invalid parameter. ' + f'Passed: {mode}' + ) + return make_response( + jsonify( + result=('Неверно указан параметр . ' + 'Сообщение не отправлено.') + ), + 400 + ) message.was_sent = True message.sent_date = datetime.datetime.now() @@ -80,8 +100,15 @@ def post(self, has_mailing, **kwargs): except SQLAlchemyError as ex: logger.error(f'Messages: Database commit error "{str(ex)}"') db_session.rollback() - return make_response(jsonify(message=f'Bad request: {str(ex)}'), 400) + return make_response( + jsonify(message=f'Bad request: {str(ex)}'), 400 + ) - logger.info(f"Messages: The message '{message.message[0:30]}...' " - f"has been successfully added to the mailing list.") - return make_response(jsonify(result=f"Сообщение успешно добавлено в очередь рассылки."), 200) + logger.info(f'Messages: The message "{message.message[0:30]}..." ' + f'has been successfully added to the mailing list.') + return make_response( + jsonify( + result='Сообщение успешно добавлено в очередь рассылки.' + ), + 200 + ) diff --git a/bot/messages.py b/bot/messages.py index 7c23a53..8ed52fe 100644 --- a/bot/messages.py +++ b/bot/messages.py @@ -1,10 +1,9 @@ -from telegram import Bot, ParseMode, error -from telegram.error import Unauthorized -import datetime import time from dataclasses import dataclass from typing import List -import pytz + +from telegram import Bot, ParseMode, error +from telegram.error import Unauthorized from app import config from app.database import db_session @@ -16,7 +15,7 @@ @dataclass -class SendUserMessageContext : +class SendUserMessageContext: message: str telegram_id: int @@ -28,11 +27,12 @@ class SendUserNotificationsContext: class TelegramNotification: """ - This class describes the functionality for working with notifications in Telegram. + This class describes the functionality + for working with notifications in Telegram. """ - def __init__(self, has_mailing: str = 'subscribed') -> None: - self.has_mailing = has_mailing + def __init__(self, mode: str = 'subscribed') -> None: + self.mode = mode # TODO refactoring https://github.com/python-telegram-bot/python-telegram-bot/wiki/Avoiding-flood-limits def send_notification(self, message): @@ -43,58 +43,83 @@ def send_notification(self, message): :param telegram_chats: Users query :return: """ - if self.has_mailing not in ('all', 'subscribed', 'unsubscribed'): + if self.mode not in ('all', 'subscribed', 'unsubscribed'): return False chats_list = [] - query = db_session.query(User.telegram_id).filter(User.banned.is_(False)) + query = db_session.query( + User.telegram_id).filter(User.banned.is_(False) + ) - if self.has_mailing == 'subscribed': + if self.mode == 'subscribed': chats_list = query.filter(User.has_mailing.is_(True)) - if self.has_mailing == 'unsubscribed': + if self.mode == 'unsubscribed': chats_list = query.filter(User.has_mailing.is_(False)) - if self.has_mailing == 'all': + if self.mode == 'all': chats_list = query user_notification_context = SendUserNotificationsContext([]) for user in chats_list: - user_message_context = SendUserMessageContext(message=message, telegram_id=user.telegram_id) - user_notification_context.user_message_context.append(user_message_context) - + user_message_context = SendUserMessageContext( + message=message, + telegram_id=user.telegram_id + ) + user_notification_context.user_message_context.append( + user_message_context + ) + seconds = 1 - dispatcher.job_queue.run_once(self.send_batch_messages, seconds, context=user_notification_context, - name=f'Sending: {message[0:10]}') + dispatcher.job_queue.run_once( + self.send_batch_messages, + seconds, + context=user_notification_context, + name=f'Sending: {message[0:10]}' + ) return True def send_batch_messages(self, user_notification_context): job = user_notification_context.job user_message_context = job.context.user_message_context - for send_set in self.__split_chats(user_message_context, config.MAILING_BATCH_SIZE): - + for send_set in self.__split_chats( + user_message_context, + config.MAILING_BATCH_SIZE + ): for user_message_context in send_set: self.__send_message_context(user_message_context) time.sleep(1) - + def __send_message_context(self, user_message_context): tries = 3 for i in range(tries): try: - bot.send_message(chat_id=user_message_context.telegram_id, text=user_message_context.message, - parse_mode=ParseMode.HTML, disable_web_page_preview=True) - logger.info(f"Sent message to {user_message_context.telegram_id}") + bot.send_message( + chat_id=user_message_context.telegram_id, + text=user_message_context.message, + parse_mode=ParseMode.HTML, + disable_web_page_preview=True + ) + logger.info( + f"Sent message to {user_message_context.telegram_id}" + ) return except error.BadRequest as ex: - logger.error(f'{str(ex.message)}, telegram_id: {user_message_context.telegram_id}') + logger.error( + f'{str(ex.message)}, telegram_id: ' + f'{user_message_context.telegram_id}') if i < tries: logger.info(f"Retry to send after {i}") time.sleep(i) except Unauthorized as ex: - logger.error(f'{str(ex.message)}: {user_message_context.telegram_id}') - User.query.filter_by(telegram_id=user_message_context.telegram_id).update({'banned': True, 'has_mailing': False}) + logger.error( + f'{str(ex.message)}: {user_message_context.telegram_id}' + ) + User.query.filter_by( + telegram_id=user_message_context.telegram_id + ).update({'banned': True, 'has_mailing': False}) db_session.commit() @staticmethod From 7fe2c20ba023e51494628c1076c940a0ba8b4475 Mon Sep 17 00:00:00 2001 From: Levon Gegamyan Date: Thu, 25 May 2023 18:45:23 +0300 Subject: [PATCH 13/29] small refactor --- app/front/send_tg_notification.py | 2 +- bot/messages.py | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/front/send_tg_notification.py b/app/front/send_tg_notification.py index 41d9381..36d519c 100644 --- a/app/front/send_tg_notification.py +++ b/app/front/send_tg_notification.py @@ -51,8 +51,8 @@ class SendTelegramNotification(Resource, MethodResource): 'type': 'string', 'required': True }, - 'Authorization': config.PARAM_HEADER_AUTH, # Only if request requires authorization + 'Authorization': config.PARAM_HEADER_AUTH, } ) @use_kwargs(TelegramNotificationSchema) diff --git a/bot/messages.py b/bot/messages.py index 8ed52fe..76a030f 100644 --- a/bot/messages.py +++ b/bot/messages.py @@ -47,9 +47,7 @@ def send_notification(self, message): return False chats_list = [] - query = db_session.query( - User.telegram_id).filter(User.banned.is_(False) - ) + query = db_session.query(User.telegram_id).filter(User.banned.is_(False)) if self.mode == 'subscribed': chats_list = query.filter(User.has_mailing.is_(True)) From 7eb162ab11deacc4ebc0d81b4d6359f292904755 Mon Sep 17 00:00:00 2001 From: desm Date: Wed, 28 Jun 2023 14:27:39 +0300 Subject: [PATCH 14/29] added custom Exeption class to send_tg_message_to_user.py --- app/__init__.py | 3 +++ app/error_handlers.py | 12 ++++++++++++ app/front/send_tg_message_to_user.py | 28 ++++++++++------------------ bot/messages.py | 13 +++++++++---- 4 files changed, 34 insertions(+), 22 deletions(-) create mode 100644 app/error_handlers.py diff --git a/app/__init__.py b/app/__init__.py index 8bc9340..1100fb5 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -9,6 +9,7 @@ from app import config from app.config import TELEGRAM_TOKEN + jwt = JWTManager() mail = Mail() cors = CORS() @@ -26,12 +27,14 @@ def create_app(): from app.webhooks import swagger_webhooks from app.auth import auth_bp + from app.error_handlers import invalid_api_usage, InvalidAPIUsage from app.front import front_bp from app.webhooks import webhooks_bp app.register_blueprint(webhooks_bp) app.register_blueprint(auth_bp) app.register_blueprint(front_bp) + app.register_error_handler(InvalidAPIUsage, invalid_api_usage) jwt.init_app(app) mail.init_app(app) diff --git a/app/error_handlers.py b/app/error_handlers.py new file mode 100644 index 0000000..16cf8b9 --- /dev/null +++ b/app/error_handlers.py @@ -0,0 +1,12 @@ +class InvalidAPIUsage(Exception): + status_code = 400 + + def __init__(self, message, status_code=None): + super().__init__() + self.message = message + if status_code is not None: + self.status_code = status_code + + +def invalid_api_usage(error): + return error.message, error.status_code diff --git a/app/front/send_tg_message_to_user.py b/app/front/send_tg_message_to_user.py index 8e8d37c..6ff926c 100644 --- a/app/front/send_tg_message_to_user.py +++ b/app/front/send_tg_message_to_user.py @@ -10,6 +10,7 @@ from app import config from app.database import db_session +from app.error_handlers import InvalidAPIUsage from app.logger import app_logger as logger from app.models import Notification from bot.messages import TelegramMessage @@ -52,16 +53,14 @@ class SendTelegramMessage(Resource, MethodResource): def post(self, telegram_id, **kwargs): message = kwargs.get('message').replace(' ', '') - if not message or not telegram_id: + if not message: logger.info( - 'Messages: The and ' - 'parameters have not been passed' + 'Messages: The parameter have not been passed' ) return make_response( jsonify( result=( - 'Необходимо указать параметры ' - ' и .' + 'Необходимо указать параметр .' ) ), 400 ) @@ -72,22 +71,15 @@ def post(self, telegram_id, **kwargs): try: db_session.commit() mesg = TelegramMessage(telegram_id) - - if not mesg.send_message(message=message.message): - logger.info( - 'Messages: Passed invalid parameter. ' - f'Passed: {telegram_id}' - ) - return make_response( - jsonify( - result=('Неверно указан параметр . ' - 'Сообщение не отправлено.')), 400 - ) - + mesg.send_message(message=message.message) message.was_sent = True message.sent_date = datetime.datetime.now() db_session.commit() - + except InvalidAPIUsage as ex: + return make_response( + jsonify( + result=ex.message), ex.status_code + ) except SQLAlchemyError as ex: logger.error(f'Messages: Database commit error "{str(ex)}"') db_session.rollback() diff --git a/bot/messages.py b/bot/messages.py index 31bf115..437e7f8 100644 --- a/bot/messages.py +++ b/bot/messages.py @@ -7,6 +7,7 @@ from app import config from app.database import db_session +from app.error_handlers import InvalidAPIUsage from app.logger import bot_logger as logger from app.models import User from bot.charity_bot import dispatcher @@ -117,7 +118,7 @@ class TelegramMessage: def __init__(self, telegram_id: int) -> None: self.telegram_id = telegram_id - def send_message(self, message) -> bool: + def send_message(self, message) -> None: """ Send telegram message to user. @@ -131,19 +132,23 @@ def send_message(self, message) -> bool: logger.error( f'User with telegram id "{self.telegram_id}" does not exist' ) - return False + raise InvalidAPIUsage(f'Пользователь с таким telegram id ' + f'"{self.telegram_id}" не существует' + ) + try: bot.send_message( chat_id=self.telegram_id, text=message, parse_mode=ParseMode.HTML, disable_web_page_preview=True) logger.info(f'Sent message to {self.telegram_id}') - return True + except error.BadRequest as ex: logger.error(f'{str(ex.message)}, telegram_id: {self.telegram_id}') + raise InvalidAPIUsage('Неверно указан параметр . Сообщение не отправлено.') except Unauthorized as ex: logger.error(f'{str(ex.message)}: {self.telegram_id}') User.query.filter_by( telegram_id=self.telegram_id ).update({'banned': True, 'has_mailing': False}) db_session.commit() - return False + raise InvalidAPIUsage(f'{str(ex.message)}: {self.telegram_id}') From 5289825c281af56893f23384d26910c35b9fcec7 Mon Sep 17 00:00:00 2001 From: desm Date: Wed, 28 Jun 2023 15:16:02 +0300 Subject: [PATCH 15/29] small refactoring --- app/front/send_tg_message_to_user.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/front/send_tg_message_to_user.py b/app/front/send_tg_message_to_user.py index 6ff926c..b5be42f 100644 --- a/app/front/send_tg_message_to_user.py +++ b/app/front/send_tg_message_to_user.py @@ -70,15 +70,14 @@ def post(self, telegram_id, **kwargs): db_session.add(message) try: db_session.commit() - mesg = TelegramMessage(telegram_id) - mesg.send_message(message=message.message) + mes = TelegramMessage(telegram_id) + mes.send_message(message=message.message) message.was_sent = True message.sent_date = datetime.datetime.now() db_session.commit() except InvalidAPIUsage as ex: return make_response( - jsonify( - result=ex.message), ex.status_code + jsonify(result=ex.message), ex.status_code ) except SQLAlchemyError as ex: logger.error(f'Messages: Database commit error "{str(ex)}"') From fc7fde3603866b557a7ef7c419a69ffaa9f5017b Mon Sep 17 00:00:00 2001 From: desm Date: Thu, 29 Jun 2023 11:12:25 +0300 Subject: [PATCH 16/29] add db rollback at InvalidAPIUsage exception. --- app/front/send_tg_message_to_user.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app/front/send_tg_message_to_user.py b/app/front/send_tg_message_to_user.py index b5be42f..182dc0c 100644 --- a/app/front/send_tg_message_to_user.py +++ b/app/front/send_tg_message_to_user.py @@ -76,6 +76,7 @@ def post(self, telegram_id, **kwargs): message.sent_date = datetime.datetime.now() db_session.commit() except InvalidAPIUsage as ex: + db_session.rollback() return make_response( jsonify(result=ex.message), ex.status_code ) From 492506586e039ffe88fe93a0fcd71ed5750a5dc9 Mon Sep 17 00:00:00 2001 From: desm Date: Thu, 29 Jun 2023 15:46:11 +0300 Subject: [PATCH 17/29] add docstrings to InvalidAPIUsage class and handler. --- app/error_handlers.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/error_handlers.py b/app/error_handlers.py index 16cf8b9..9be295b 100644 --- a/app/error_handlers.py +++ b/app/error_handlers.py @@ -1,4 +1,9 @@ class InvalidAPIUsage(Exception): + """ + Special class for custom Exceptions raised where it is necessary. + If Exception is not explicitly defined raises HTTP 400 Bad Request. + Error Message is required to clarify erroneous program behavior. + """ status_code = 400 def __init__(self, message, status_code=None): @@ -9,4 +14,7 @@ def __init__(self, message, status_code=None): def invalid_api_usage(error): + """ + InvalidAPIUsage handler function. + """ return error.message, error.status_code From d6a95a47b0ea02aa03b2f058902a06763271c455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9B=D1=8B=D0=BE?= Date: Mon, 3 Jul 2023 15:52:19 +0300 Subject: [PATCH 18/29] fix token --- app/front/send_tg_message_to_user.py | 18 ++++++++++-------- docker-compose.local.yml | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/app/front/send_tg_message_to_user.py b/app/front/send_tg_message_to_user.py index 182dc0c..1c1190a 100644 --- a/app/front/send_tg_message_to_user.py +++ b/app/front/send_tg_message_to_user.py @@ -3,16 +3,15 @@ from flask import jsonify, make_response from flask_apispec import doc, use_kwargs from flask_apispec.views import MethodResource -from flask_jwt_extended import get_jwt_identity, jwt_required from flask_restful import Resource from marshmallow import Schema, fields from sqlalchemy.exc import SQLAlchemyError -from app import config from app.database import db_session from app.error_handlers import InvalidAPIUsage from app.logger import app_logger as logger from app.models import Notification +from app.webhooks.check_webhooks_token import check_webhooks_token from bot.messages import TelegramMessage @@ -21,6 +20,7 @@ class TelegramMessageSchema(Schema): class SendTelegramMessage(Resource, MethodResource): + method_decorators = {'post': [check_webhooks_token]} @doc(description='Sends message to the telegram user.' 'Requires "message" and "telegram_id" parameters.', @@ -45,11 +45,14 @@ class SendTelegramMessage(Resource, MethodResource): 'type': 'integer', 'required': True }, - 'Authorization': config.PARAM_HEADER_AUTH, - } - ) + 'token': { + 'description': 'webhooks token', + 'in': 'header', + 'type': 'string', + 'required': True + } + }) @use_kwargs(TelegramMessageSchema) - @jwt_required() def post(self, telegram_id, **kwargs): message = kwargs.get('message').replace(' ', '') @@ -65,8 +68,7 @@ def post(self, telegram_id, **kwargs): ), 400 ) - authorized_user = get_jwt_identity() - message = Notification(message=message, sent_by=authorized_user) + message = Notification(message=message) db_session.add(message) try: db_session.commit() diff --git a/docker-compose.local.yml b/docker-compose.local.yml index 1b639fc..f5648cc 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -29,7 +29,7 @@ services: expose: - "5432" ports: - - "9999:5432" + - "5432:5432" env_file: - .env.dev From 18b7748975225bc80b482f0184752b3a372ba692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9B=D1=8B=D0=BE?= Date: Mon, 3 Jul 2023 16:28:22 +0300 Subject: [PATCH 19/29] sent_by set nullable --- app/models.py | 2 +- docker-compose.local.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models.py b/app/models.py index f2dc710..f6de85d 100644 --- a/app/models.py +++ b/app/models.py @@ -122,7 +122,7 @@ class Notification(Base): message = Column(String(4096), nullable=False) was_sent = Column(Boolean, default=False) sent_date = Column(TIMESTAMP) - sent_by = Column(String(48), nullable=False) + sent_by = Column(String(48), nullable=True) def __repr__(self): return f'' diff --git a/docker-compose.local.yml b/docker-compose.local.yml index f5648cc..1b639fc 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -29,7 +29,7 @@ services: expose: - "5432" ports: - - "5432:5432" + - "9999:5432" env_file: - .env.dev From 8a57e705bb71b29cd53a4e9c2d986ec7511b870b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9B=D1=8B=D0=BE?= Date: Mon, 3 Jul 2023 17:58:18 +0300 Subject: [PATCH 20/29] create migration --- app/models.py | 2 +- ...e97f4_notification_sent_by_set_nullable.py | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 migrations/versions/0e74b21e97f4_notification_sent_by_set_nullable.py diff --git a/app/models.py b/app/models.py index f2dc710..f6de85d 100644 --- a/app/models.py +++ b/app/models.py @@ -122,7 +122,7 @@ class Notification(Base): message = Column(String(4096), nullable=False) was_sent = Column(Boolean, default=False) sent_date = Column(TIMESTAMP) - sent_by = Column(String(48), nullable=False) + sent_by = Column(String(48), nullable=True) def __repr__(self): return f'' diff --git a/migrations/versions/0e74b21e97f4_notification_sent_by_set_nullable.py b/migrations/versions/0e74b21e97f4_notification_sent_by_set_nullable.py new file mode 100644 index 0000000..3fefc4f --- /dev/null +++ b/migrations/versions/0e74b21e97f4_notification_sent_by_set_nullable.py @@ -0,0 +1,32 @@ +"""Notification sent_by set nullable + +Revision ID: 0e74b21e97f4 +Revises: 87c7d29e3ddb +Create Date: 2023-07-03 17:44:30.800774 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '0e74b21e97f4' +down_revision = '87c7d29e3ddb' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('notifications', 'sent_by', + existing_type=sa.VARCHAR(length=48), + nullable=True) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.alter_column('notifications', 'sent_by', + existing_type=sa.VARCHAR(length=48), + nullable=False) + # ### end Alembic commands ### From 0a1d431ade7fc8ca30cb38b626d6a85cfbffb581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9B=D1=8B=D0=BE?= Date: Mon, 3 Jul 2023 20:40:52 +0300 Subject: [PATCH 21/29] Delete required for message param --- app/front/send_tg_message_to_user.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/front/send_tg_message_to_user.py b/app/front/send_tg_message_to_user.py index 1c1190a..17f321d 100644 --- a/app/front/send_tg_message_to_user.py +++ b/app/front/send_tg_message_to_user.py @@ -34,8 +34,7 @@ class SendTelegramMessage(Resource, MethodResource): 'message': { 'description': 'Message to user. Max len 4096', 'in': 'query', - 'type': 'string', - 'required': True + 'type': 'string' }, 'telegram_id': { 'description': ( From a0f46b11e5b2c16df3cff3ff67c149bec5e05f19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9B=D1=8B=D0=BE?= Date: Mon, 3 Jul 2023 21:23:29 +0300 Subject: [PATCH 22/29] fix url in button link account with bot --- .env.dev | 1 + .env.example | 1 + .env.prod | 1 + bot/common_comands.py | 21 ++++++++++++--------- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.env.dev b/.env.dev index a141c00..f796bdd 100644 --- a/.env.dev +++ b/.env.dev @@ -5,6 +5,7 @@ MAIL_PORT=587 MAIL_USE_TLS=True MAIL_USERNAME= MAIL_DEFAULT_SENDER= +URL_PROCHARITY= EMAIL_PROCHARRITY= HOST_NAME= ACCESS_TOKEN_FOR_PROCHARITY= diff --git a/.env.example b/.env.example index 51cca82..36fa897 100644 --- a/.env.example +++ b/.env.example @@ -5,6 +5,7 @@ MAIL_PORT= MAIL_USE_TLS= MAIL_USERNAME= MAIL_DEFAULT_SENDER= +URL_PROCHARITY= EMAIL_PROCHARRITY= DATABASE_URL= HOST_NAME= diff --git a/.env.prod b/.env.prod index 7062768..9374b10 100644 --- a/.env.prod +++ b/.env.prod @@ -5,6 +5,7 @@ MAIL_PORT= MAIL_USE_TLS= MAIL_USERNAME= MAIL_DEFAULT_SENDER= +URL_PROCHARITY= EMAIL_PROCHARRITY= DATABASE_URL= HOST_NAME= diff --git a/bot/common_comands.py b/bot/common_comands.py index 0b92e20..1c06e18 100644 --- a/bot/common_comands.py +++ b/bot/common_comands.py @@ -1,9 +1,11 @@ +import os from telegram import (Update, InlineKeyboardMarkup, ParseMode) from telegram.ext import CallbackContext, CallbackQueryHandler, CommandHandler - from telegram import InlineKeyboardButton + +from dotenv import load_dotenv from bot.constants import states from bot.constants import command_constants from bot.constants import constants @@ -13,6 +15,8 @@ from core.services.user_service import UserService from app.database import db_session +load_dotenv() + MENU_BUTTONS = [ [ InlineKeyboardButton( @@ -62,13 +66,11 @@ def start(update: Update, context: CallbackContext) -> int: if user.categories else command_constants.COMMAND__GREETING) buttons = [ - [ - InlineKeyboardButton(text='Начнем', callback_data=callback_data) - ], - [ - InlineKeyboardButton(text='Связать аккаунт с ботом', - url='https://procharity.ru/') - ] + [InlineKeyboardButton(text='Начнем', callback_data=callback_data)], + [InlineKeyboardButton( + text='Связать аккаунт с ботом', + url=f'{os.getenv("URL_PROCHARITY")}/auth/bot_procharity.php?user_id={user.external_id}&telegram_id={user.telegram_id}' + )] ] keyboard = InlineKeyboardMarkup(buttons) context.bot.send_message( @@ -76,7 +78,8 @@ def start(update: Update, context: CallbackContext) -> int: text='Привет! 👋 \n\n' f'Я бот платформы интеллектуального волонтерства ProCharity. ' 'Буду держать тебя в курсе новых задач и помогу ' - 'оперативно связаться с командой поддержки.', + 'оперативно связаться с командой поддержки.\n\n' + f'Ваш телеграм id – {update.effective_user.id}', reply_markup=keyboard, parse_mode=ParseMode.HTML, disable_web_page_preview=True ) From e223c7306f33311f628445837eae00cb8d440963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9B=D1=8B=D0=BE?= Date: Fri, 7 Jul 2023 12:55:41 +0300 Subject: [PATCH 23/29] delete tg id in start message, add URL_PROCHARITY to develop ci --- .github/workflows/develop_bot_ci.yml | 1 + bot/common_comands.py | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/develop_bot_ci.yml b/.github/workflows/develop_bot_ci.yml index 86caa89..354e27e 100644 --- a/.github/workflows/develop_bot_ci.yml +++ b/.github/workflows/develop_bot_ci.yml @@ -100,6 +100,7 @@ jobs: echo MAIL_USE_TLS=${{ secrets.MAIL_USE_TLS }} >> .env echo MAIL_USERNAME=${{ secrets.MAIL_USERNAME }} >> .env echo MAIL_DEFAULT_SENDER=${{ secrets.MAIL_DEFAULT_SENDER }} >> .env + echo URL_PROCHARITY=${{ secrets.URL_PROCHARITY }} >> .env echo EMAIL_PROCHARRITY=${{ secrets.EMAIL_PROCHARRITY }} >> .env echo HOST_NAME=${{ secrets.HOST_NAME }} >> .env echo ACCESS_TOKEN_FOR_PROCHARITY=${{ secrets.ACCESS_TOKEN_FOR_PROCHARITY }} >> .env diff --git a/bot/common_comands.py b/bot/common_comands.py index 1c06e18..13c7aca 100644 --- a/bot/common_comands.py +++ b/bot/common_comands.py @@ -78,8 +78,7 @@ def start(update: Update, context: CallbackContext) -> int: text='Привет! 👋 \n\n' f'Я бот платформы интеллектуального волонтерства ProCharity. ' 'Буду держать тебя в курсе новых задач и помогу ' - 'оперативно связаться с командой поддержки.\n\n' - f'Ваш телеграм id – {update.effective_user.id}', + 'оперативно связаться с командой поддержки.' reply_markup=keyboard, parse_mode=ParseMode.HTML, disable_web_page_preview=True ) From 946d8a213f2674c04b4753f5a03ccd31da5182d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9B=D1=8B=D0=BE?= Date: Fri, 7 Jul 2023 13:05:29 +0300 Subject: [PATCH 24/29] add URL_PROCHARITY to bot config --- app/config.py | 2 ++ bot/common_comands.py | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/config.py b/app/config.py index 96b5c8e..1f7e6e9 100644 --- a/app/config.py +++ b/app/config.py @@ -29,6 +29,8 @@ 'lowercase': 1, 'max_length': 32, } + +URL_PROCHARITY = os.getenv('URL_PROCHARITY') # procharity send email settings PROCHARRITY_TEMPLATE = 'email_templates/send_question.html' diff --git a/bot/common_comands.py b/bot/common_comands.py index 13c7aca..410eb6c 100644 --- a/bot/common_comands.py +++ b/bot/common_comands.py @@ -1,11 +1,10 @@ -import os from telegram import (Update, InlineKeyboardMarkup, ParseMode) from telegram.ext import CallbackContext, CallbackQueryHandler, CommandHandler from telegram import InlineKeyboardButton -from dotenv import load_dotenv +from app import config from bot.constants import states from bot.constants import command_constants from bot.constants import constants @@ -15,7 +14,6 @@ from core.services.user_service import UserService from app.database import db_session -load_dotenv() MENU_BUTTONS = [ [ @@ -69,7 +67,7 @@ def start(update: Update, context: CallbackContext) -> int: [InlineKeyboardButton(text='Начнем', callback_data=callback_data)], [InlineKeyboardButton( text='Связать аккаунт с ботом', - url=f'{os.getenv("URL_PROCHARITY")}/auth/bot_procharity.php?user_id={user.external_id}&telegram_id={user.telegram_id}' + url=f'{config.URL_PROCHARITY}/auth/bot_procharity.php?user_id={user.external_id}&telegram_id={user.telegram_id}' )] ] keyboard = InlineKeyboardMarkup(buttons) From 5d98421fb5dcd75a914a2a173abad00e9414edfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9B=D1=8B=D0=BE?= Date: Fri, 7 Jul 2023 14:06:45 +0300 Subject: [PATCH 25/29] add URL_PROCHARITY to master ci --- .github/workflows/master_bot_ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/master_bot_ci.yml b/.github/workflows/master_bot_ci.yml index 7011a54..3b00f2f 100644 --- a/.github/workflows/master_bot_ci.yml +++ b/.github/workflows/master_bot_ci.yml @@ -100,6 +100,7 @@ jobs: echo MAIL_USE_TLS=${{ secrets.MAIL_USE_TLS }} >> .env echo MAIL_USERNAME=${{ secrets.MAIL_USERNAME }} >> .env echo MAIL_DEFAULT_SENDER=${{ secrets.MAIL_DEFAULT_SENDER }} >> .env + echo URL_PROCHARITY=${{ secrets.URL_PROCHARITY }} >> .env echo EMAIL_PROCHARRITY=${{ secrets.EMAIL_PROCHARRITY }} >> .env echo HOST_NAME=${{ secrets.HOST_NAME_PROD }} >> .env echo ACCESS_TOKEN_FOR_PROCHARITY=${{ secrets.ACCESS_TOKEN_FOR_PROCHARITY_PROD }} >> .env From abd15a8bc943e1d43da273e737128b61df221441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9B=D1=8B=D0=BE?= Date: Sat, 8 Jul 2023 19:45:54 +0300 Subject: [PATCH 26/29] fix start command --- bot/common_comands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/common_comands.py b/bot/common_comands.py index 410eb6c..7cb592f 100644 --- a/bot/common_comands.py +++ b/bot/common_comands.py @@ -76,7 +76,7 @@ def start(update: Update, context: CallbackContext) -> int: text='Привет! 👋 \n\n' f'Я бот платформы интеллектуального волонтерства ProCharity. ' 'Буду держать тебя в курсе новых задач и помогу ' - 'оперативно связаться с командой поддержки.' + 'оперативно связаться с командой поддержки.', reply_markup=keyboard, parse_mode=ParseMode.HTML, disable_web_page_preview=True ) From dd81c677bfdc987c9deb1cde309c98029511f3d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9B=D1=8B=D0=BE?= Date: Mon, 10 Jul 2023 15:26:47 +0300 Subject: [PATCH 27/29] add user_id to ExternalUserRegistration --- app/auth/external_users_registration.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/auth/external_users_registration.py b/app/auth/external_users_registration.py index 2c2c80b..efc56fe 100644 --- a/app/auth/external_users_registration.py +++ b/app/auth/external_users_registration.py @@ -34,13 +34,14 @@ class ExternalUserRegistration(MethodResource, Resource): @use_kwargs( {'id': fields.Int(required=True), 'id_hash': fields.Str(description='md5 hash of external_id', required=True), + 'user_id': fields.Int(required=True), 'first_name': fields.Str(required=True), 'last_name': fields.Str(required=True), 'email': fields.Str(required=True), 'specializations': fields.Str(required=True)} ) def post(self, **kwargs): - external_id = kwargs.get('id') + external_id = kwargs.get('user_id') user = ExternalSiteUser.query.options(load_only('external_id')).filter_by(external_id=external_id).first() if user: From df12c337ff251781afa16672596ab78ba309e9bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9B=D1=8B=D0=BE?= Date: Wed, 26 Jul 2023 17:56:24 +0300 Subject: [PATCH 28/29] fix external_user_registration and change logging level to DEBUG --- app/auth/external_users_registration.py | 2 +- app/logger.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/auth/external_users_registration.py b/app/auth/external_users_registration.py index efc56fe..80bdf72 100644 --- a/app/auth/external_users_registration.py +++ b/app/auth/external_users_registration.py @@ -64,7 +64,7 @@ def post(self, **kwargs): categories = [] for specialization in specializations: - user.categories.append(specialization.name) + categories.append(specialization.name) try: db_session.commit() diff --git a/app/logger.py b/app/logger.py index 7a61dc6..9b76b47 100644 --- a/app/logger.py +++ b/app/logger.py @@ -32,7 +32,7 @@ def add_handler(path_name): def app_logging(): module_logger = logging.getLogger('app') - module_logger.setLevel(logging.INFO) + module_logger.setLevel(logging.DEBUG) app_handler = add_handler('app_logs.txt') app_loggers = [ module_logger, @@ -47,7 +47,7 @@ def app_logging(): def bot_logging(): bot_logger = logging.getLogger("telegram") - bot_logger.setLevel(logging.INFO) + bot_logger.setLevel(logging.DEBUG) bot_handler = add_handler('bot_logs.txt') bot_logger.addHandler(bot_handler) app_loggers = [ @@ -63,7 +63,7 @@ def bot_logging(): def webhooks_logging(): webhooks_logger = logging.getLogger("webhooks") - webhooks_logger.setLevel(logging.INFO) + webhooks_logger.setLevel(logging.DEBUG) webhooks_handler = add_handler('webhooks_logs.txt') webhooks_logger.addHandler(webhooks_handler) From 5ac29e47263f958a48ce340b04b2957cd603dfd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=80=20?= =?UTF-8?q?=D0=9B=D1=8B=D0=BE?= Date: Thu, 3 Aug 2023 10:33:47 +0300 Subject: [PATCH 29/29] fix ExternalUserRegistration json kwargs --- app/auth/external_users_registration.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/auth/external_users_registration.py b/app/auth/external_users_registration.py index 80bdf72..b85adf2 100644 --- a/app/auth/external_users_registration.py +++ b/app/auth/external_users_registration.py @@ -32,9 +32,8 @@ class ExternalUserRegistration(MethodResource, Resource): } ) @use_kwargs( - {'id': fields.Int(required=True), + {'user_id': fields.Int(required=True), 'id_hash': fields.Str(description='md5 hash of external_id', required=True), - 'user_id': fields.Int(required=True), 'first_name': fields.Str(required=True), 'last_name': fields.Str(required=True), 'email': fields.Str(required=True),