import logging from os.path import basename import sentry_sdk from envparse import env from telegram import Message, ReplyKeyboardMarkup, ReplyKeyboardRemove, Update from telegram.ext import CommandHandler, MessageHandler, Updater from telegram.ext.filters import BaseFilter, Filters from . import celery as tasks from .helpers import download, get_subject, reply from .models import User, create_tables, get_user_instance env.read_envfile() logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') if env('SENTRY_DSN', default=None) is not None: sentry_sdk.init(env('SENTRY_DSN')) @reply def start(bot, update: Update, user: User, render): update.message.reply_text(text=render('hello_message')) @reply def resend(bot, update: Update, user, render): tasks.send_confirmation_mail.delay(user.pk) update.message.reply_text(text=render('confirmation_message_is_sent'), reply_markup=ReplyKeyboardRemove()) @reply def reset_email(bot, update: Update, user, render): user.email = None user.is_confirmed = False user.save() update.message.reply_text(text=render('email_is_reset'), reply_markup=ReplyKeyboardRemove()) @reply def confirm_email(bot, update: Update, user, render): key = update.message.text.strip() if user.confirmation != key: update.message.reply_text(text=render('confirmation_failure')) return user.is_confirmed = True user.save() update.message.reply_text(text=render('email_is_confirmed')) @reply def send_text_message(bot, update: Update, user: User, render, **kwargs): text = update.message.text subject = get_subject(text) update.message.reply_text(text=render('message_is_sent')) tasks.send_text.delay( user_id=user.pk, subject=subject, text=text, ) @reply def send_photo(bot, update: Update, user: User, render): file = update.message.photo[-1].get_file() photo = download(file) subject = 'Photo note to self' text = '' if update.message.caption is not None: text = update.message.caption.strip() if text: subject = 'Photo: {}'.format(get_subject(text)) update.message.reply_text(text=render('photo_is_sent')) tasks.send_file.delay( user_id=user.pk, file=photo, filename=basename(file.file_path), subject=subject, text=text, ) @reply def send_voice(bot, update: Update, user: User, render): update.message.reply_text(text='Sorry, voice messages are not supported right now') @reply def prompt_for_setting_email(bot, update: Update, user: User, render): update.message.reply_text(text=render('please_send_email')) @reply def send_confirmation(bot, update: Update, user: User, render): email = update.message.text.strip() if User.select().where(User.email == email): update.message.reply_text(text=render('email_is_occupied')) return user.email = email user.save() tasks.send_confirmation_mail.delay(user.pk) update.message.reply_text(text=render('confirmation_message_is_sent')) @reply def prompt_for_confirm(bot, update: Update, user: User, render): reply_markup = ReplyKeyboardMarkup([['Resend confirmation email'], ['Change email']]) update.message.reply_text(render('waiting_for_confirmation'), reply_markup=reply_markup) class ConfirmedUserFilter(BaseFilter): def filter(self, message: Message): user = get_user_instance(message.from_user, message.chat_id) return user.is_confirmed class UserWithoutEmailFilter(BaseFilter): def filter(self, message: Message): user = get_user_instance(message.from_user, message.chat_id) return user.email is None class NonConfirmedUserFilter(BaseFilter): def filter(self, message: Message): user = get_user_instance(message.from_user, message.chat_id) return user.email is not None and user.is_confirmed is False updater = Updater(token=env('BOT_TOKEN')) dispatcher = updater.dispatcher dispatcher.add_handler(CommandHandler('start', start)) dispatcher.add_handler(CommandHandler('reset', reset_email)) dispatcher.add_handler(MessageHandler(UserWithoutEmailFilter() & Filters.text & Filters.regex('@'), send_confirmation)) # looks like email, so send confirmation to it dispatcher.add_handler(MessageHandler(NonConfirmedUserFilter() & Filters.text & Filters.regex('Resend confirmation email'), resend)) # resend confirmation email dispatcher.add_handler(MessageHandler(NonConfirmedUserFilter() & Filters.text & Filters.regex('Change email'), reset_email)) # change email dispatcher.add_handler(MessageHandler(NonConfirmedUserFilter() & Filters.text & Filters.regex(r'\w{8}\-\w{4}\-\w{4}\-\w{4}\-\w{12}'), confirm_email)) # confirm email dispatcher.add_handler(MessageHandler(UserWithoutEmailFilter(), prompt_for_setting_email)) dispatcher.add_handler(MessageHandler(NonConfirmedUserFilter(), prompt_for_confirm)) dispatcher.add_handler(MessageHandler(ConfirmedUserFilter() & Filters.text, send_text_message)) dispatcher.add_handler(MessageHandler(ConfirmedUserFilter() & Filters.photo, send_photo)) dispatcher.add_handler(MessageHandler(ConfirmedUserFilter() & Filters.voice, send_voice)) if __name__ == '__main__': create_tables() updater.start_polling()