예제 #1
0
def unknown_user(message):
    """ Handle all messages if user is not identified """

    time.sleep(1)
    # Check if message text has '@' between some non-space symbols
    if not message.text or not re.findall(r"\S+@\S+", message.text):
        bot.send_message(message.chat.id, messages.send_email)
        return

    email = re.findall(r"\S+@\S+", message.text)[0].lower()
    # Suppose user entered email, look for it in database
    email_info = db_find_value("email", email)

    # Email not found, insert new row in DB with that email and user ID
    if not email_info:
        new_client(email, "tg_id", message.chat.id)
        initial_buttons(message)

    # Email is already used by user with other ID, ask to immediately contact us
    elif email_info['tg_id'] != "0":
        new_client("-", "tg_id", message.chat.id)
        open_dialogue("tg_id", message.chat.id)
        initial_buttons(message, messages.email_already_used)

    # Email found in DB and not used by other ID, update DB
    else:
        update_clients(["email", email], ["tg_id", message.chat.id])
        initial_buttons(message)
예제 #2
0
def vk_support(user_id, urgent=False):
    """ Handles every attempt to open support dialogue. Does not open if not urgent and not in working time """

    time.sleep(1)
    keyboard = VkKeyboard(inline=True)

    if not urgent:

        # User trying to contact support in non working time
        if not 17 <= datetime.datetime.today(
        ).hour < 22 or datetime.datetime.today().isoweekday() in [6, 7]:
            keyboard.add_button("Срочная связь")

            vk_send_message(user_id, messages.non_working,
                            keyboard.get_keyboard())

            return

    open_dialogue("vk_id", user_id)

    keyboard.add_button("Первичная настройка")
    keyboard.add_line()
    keyboard.add_button("Другое")
    keyboard.add_line()
    keyboard.add_button("ZGC SHOP")

    # Ask user to choose problem type
    msg = messages.type_support
    user_info = db_find_value('vk_id', user_id)
    sub = user_info['sub']
    if sub != '-' and int(user_info['verified']):
        msg += f"\U000026A1 Ваша подписка: {sub}"
    vk_send_message(user_id, msg, keyboard.get_keyboard())
예제 #3
0
def forward_to_support(message):
    """ Forward all clients messages to support group if dialogue is open
        Also send to support info about client's tariff """

    time.sleep(1)
    user_info = db_find_value("tg_id", message.chat.id)
    user_state = user_info['state']

    # transfer client's message to support group
    tg_to_tg(config.group_id, message)

    # Client sent a message after being reminded about the payment, open dialogue
    if user_state == "REMINDED":
        open_dialogue("tg_id", message.chat.id, state="PAY")
        if message.photo:
            filename = save_file(message,
                                 folder=config.pay_imgs_path,
                                 check=True)
            autopay(message.chat.id, 'tg_id', filename)

    # Client sent a photo after he has chosen the payment option. Consider this photo as payment screenshot
    elif user_state == "PAY":
        if message.photo:
            filename = save_file(message,
                                 folder=config.pay_imgs_path,
                                 check=True)
            autopay(message.chat.id, 'tg_id', filename)

    # Notify client that his message was received (once per dialogue)
    if user_info['received'] == "NO":
        bot.send_message(
            message.chat.id, "Ваше сообщение передано в поддержку. "
            "Мы постараемся ответить как можно быстрее!")
        update_clients(["tg_id", message.chat.id], ["received", "YES"])
예제 #4
0
def support(message, urgent=False):
    """ Handles every attempt to open support dialogue. Does not open if not urgent and not in working time """

    time.sleep(1)
    buttons = types.InlineKeyboardMarkup()

    # User trying to contact support in non working time
    if not urgent:
        if not 17 <= datetime.datetime.today(
        ).hour < 22 or datetime.datetime.today().isoweekday() in [6, 7]:
            buttons.add(
                types.InlineKeyboardButton(text="Срочная связь",
                                           callback_data="urgent"))
            bot.send_message(message.chat.id,
                             messages.non_working,
                             reply_markup=buttons)
            return

    open_dialogue("tg_id", message.chat.id)
    buttons = types.InlineKeyboardMarkup()
    buttons.add(
        types.InlineKeyboardButton(text="Первичная настройка",
                                   callback_data="install"))
    buttons.add(
        types.InlineKeyboardButton(text="Другое", callback_data="other"))
    buttons.add(
        types.InlineKeyboardButton(text="ZGC SHOP", callback_data="market"))

    # Ask user to choose problem type
    msg = messages.type_support
    user_info = db_find_value("tg_id", message.chat.id)
    sub = user_info['sub']
    if sub != '-' and int(user_info['verified']):
        msg += f"\U000026A1 Ваша подписка: {sub}"
    bot.send_message(message.chat.id, msg, reply_markup=buttons)
예제 #5
0
def start(message):
    """ Ask user to send his email address if not identified. Otherwise send default message with reply keyboard """

    time.sleep(1)
    if not db_find_value("tg_id", message.chat.id):
        bot.send_message(message.chat.id, messages.send_email)
    else:
        initial_buttons(message)
예제 #6
0
def message_handler(message):
    """ Check if user ID in base or ask for email, transfer message to TG group if identified client """

    time.sleep(1)
    user_id = message['sender']['id']

    # Do not react on our own messages
    if user_id == config.fb_group_id:
        return

    text = message['message'].get('text') if message.get('message') else ""
    payload = message['postback'].get('payload') if message.get('postback') else None
    user_info = db_find_value("fb_id", user_id)

    # User ID not found in DB
    if not user_info:

        # Check if message text has '@' between some non-space symbols
        if not text or not re.findall(r"\S+@\S+", text):
            fb_bot.send_text_message(user_id, messages.send_email)
            return

        # Suppose user entered email, look for it in database
        email = re.findall(r"\S+@\S+", text)[0].lower()
        email_info = db_find_value("email", email)

        # Email not found, insert new row in DB with that email and user ID
        if not email_info:
            new_client(email, "fb_id", user_id)
            send_initial_buttons(user_id)

        # Email is already used by user with other ID, ask to immediately contact us
        elif email_info['fb_id'] != "0":
            new_client("-", "fb_id", user_id)
            open_dialogue("fb_id", user_id)
            fb_bot.send_text_message(user_id, messages.email_already_used)

        # Email found in DB and not used by other ID, update DB
        else:
            update_clients(["email", email], ["fb_id", user_id])
            send_initial_buttons(user_id)

        return

    # User pushed buttons
    if payload in ["pay", "trial", "sup", "turk", "urgent", "other", "rub", "yuan", "install", "sup_other",
                   "wish", "2", "4", "5"]:
        buttons_handler(user_id, payload)

        return

    user_state = user_info['state']
    # User identified, dialogue is open, transfer message to support
    if user_state in ["OPEN", "REMINDED", "PAY"]:
        forward_fb_to_tg(message)

        # Notify user that we received his message (once per dialogue)
        if user_info['received']:
            fb_bot.send_text_message(user_id, "Ваше сообщение передано в поддержку. "
                                              "Мы постараемся ответить как можно быстрее!")
            update_clients(["fb_id", user_id], ["received", "YES"])

        if user_state == "REMINDED":
            open_dialogue("fb_id", user_id)

        return

    # User identified, dialogue is closed, ask him to use buttons
    elif user_state == "CLOSED":
        send_initial_buttons(user_id, reply=True)
        return

    # User pushed the feedback button after previous support conversation was closed.
    # Suppose user entering one-message review
    elif user_state == "ONE MESSAGE":
        time_past = int(time.time()) - int(user_info['review_time'])

        if time_past // 3600 >= 24:
            fb_bot.send_text_message(user_id, messages.buttons_menu)

        else:
            forward_fb_to_tg(message, review=True)
            fb_bot.send_text_message(user_id, "Спасибо за отзыв!")

        update_clients(["fb_id", user_id], ["state", "CLOSED"])
예제 #7
0
def vk_message_handler(event):
    """ Check if user id in base or ask for email, transfer message to TG group if identified client """

    user_id = event.user_id
    text = event.message
    user_info = db_find_value("vk_id", user_id)

    # User ID not found in DB
    if not user_info:

        # Check if message text has '@' between some non-space symbols
        if not text or not re.findall(r"\S+@\S+", text):
            vk_send_message(user_id, messages.send_email, reply_keyboard())
            return

        # Suppose user entered email, look for it in database
        email = re.findall(r"\S+@\S+", text)[0].lower()
        email_info = db_find_value("email", email)

        # Email not found, insert new row in DB with that email and user ID
        if not email_info:
            new_client(email, "vk_id", user_id)
            vk_send_message(user_id, messages.buttons_menu, reply_keyboard())

        # Email is already used by user with other ID, ask to immediately contact us
        elif email_info['vk_id'] != "0":
            new_client("-", "vk_id", user_id)
            open_dialogue("vk_id", user_id)
            vk_send_message(user_id, messages.email_already_used,
                            reply_keyboard())

        # Email found in DB and not used by other ID, update DB
        else:
            update_clients(["email", email], ["vk_id", user_id])
            vk_send_message(user_id, messages.buttons_menu, reply_keyboard())

        return

    # User pushed button
    if text in [
            "\U0001F4B4Оплата", "\U0001F193Попробовать",
            "\U0001F1F9\U0001F1F2Туркменистан", "\U0001F4F0Узнать больше",
            "\U0001F6D2ZGC SHOP", "\U0001F91DСотрудничество",
            "\U00002753Связаться с поддержкой", "Срочная связь",
            "В рублях ₽ или в гривнах ₴", "В юанях ¥", "Первичная настройка",
            "Другое", "\U0001F92C 1", "\U00002639 2", "\U0001F610 3",
            "\U0001F642 4", "\U0001F600 5", "\U0001F4A1 Оставить пожелание",
            "ZGC SHOP", "Связаться с поддержкой"
    ]:
        buttons_handler(user_id, text)

        return

    user_state = user_info['state']
    # User identified, dialogue is open, transfer message to support
    if user_state in ["OPEN", "REMINDED", "PAY"]:
        forward_vk_to_tg(event, user_state=user_state)

        # Notify user that we received his message (once per dialogue)
        if user_info['received'] == 'NO':
            vk_send_message(
                user_id, "Ваше сообщение передано в поддержку. "
                "Мы постараемся ответить как можно быстрее!", reply_keyboard())
            update_clients(["vk_id", user_id], ["received", "YES"])

        if user_state == "REMINDED":
            open_dialogue("vk_id", user_id, state="PAY")

        return

    # User identified, dialogue is closed, ask him to use buttons
    if user_state == "CLOSED":
        vk_send_message(user_id, messages.push_buttons, reply_keyboard())

        return

    # User pushed the feedback button after previous support conversation was closed.
    # Suppose user entering one-message review
    if user_state == "ONE MESSAGE":
        time_past = int(time.time()) - int(user_info['review_time'])

        # If user pushed the button more than a day ago, don't send his message to support
        if time_past // 3600 >= 24:
            vk_send_message(user_id, messages.buttons_menu)

        # Send review to support
        else:
            forward_vk_to_tg(event, review=True, user_state=user_state)
            vk_send_message(user_id, "Спасибо за отзыв!")

        update_clients(["vk_id", user_id], ["state", "CLOSED"])
예제 #8
0
def mail_edit(message):
    """ Allows bot owner to edit database, deleting row with wrong email and copying IDs to row with correct email
        Start with bot command '/почта', then reply to every bot message """

    time.sleep(1)
    if message.text == "/почта":
        temp["true_email"] = ""
        temp["wrong_email"] = ""
        bot.send_message(message.chat.id, messages.edit_wrong_mail)
        return

    reply_text = message.reply_to_message.text

    # First, you must enter wrong email address, existing in DB
    if reply_text == messages.edit_wrong_mail:
        wrong_email_info = db_find_value("email", message.text.lower())

        # Wrong email not found in DB
        if not wrong_email_info:
            bot.send_message(message.chat.id, "Такой почты нет в базе!")
            return

        # Save email info to temp
        temp['wrong_email'] = list(wrong_email_info.values())

        # Message for the next step
        bot.send_message(message.chat.id, messages.edit_true_mail)

    # Second, you must enter correct email address, existing in DB
    elif reply_text == messages.edit_true_mail:

        # No info about wrong email in temp
        if not temp['wrong_email']:
            bot.send_message(message.chat.id, "Не указан неверный email")
            return

        true_email_info = db_find_value("email", message.text.lower())

        # Correct email not found in DB
        if not true_email_info:
            bot.send_message(message.chat.id, "Такой почты нет в базе!")
            return

        temp['true_email'] = list(true_email_info.values())
        t = temp['true_email']
        w = temp['wrong_email']

        # Send two messages with DB info about wrong and correct email so we can check everything
        bot.send_message(
            message.chat.id,
            f"Данные неправильной почты:\nemail = {w[0]}\ndate = {w[1]}\n"
            f"tariff = {w[2]}\nsub = {w[3]}\ntg_id = {w[4]}\nvk_id = {w[5]}\nfb_id = {w[6]}"
        )

        bot.send_message(
            message.chat.id,
            f"Данные правильной почты:\nemail = {t[0]}\ndate = {t[1]}\n"
            f"tariff = {t[2]}\nsub = {t[3]}\ntg_id = {t[4]}\nvk_id = {t[5]}\nfb_id = {t[6]}"
        )

        # Return if wrong and correct emails have different IDs for the same messenger (tg/vk/fb)
        if w[4] != "0" != t[4] and w[4] != t[4] \
                or w[5] != "0" != t[5] and w[5] != t[5] \
                or w[6] != "0" != t[6] and w[6] != t[6]:
            bot.send_message(
                message.chat.id,
                "У этих почт разные айди для одного способа связи, надо разбираться\n"
            )
            return

        # Send message, asking to confirm editing
        bot.send_message(message.chat.id, messages.edit_confirm)

    elif reply_text == messages.edit_confirm:

        # Editing confirmed
        if message.text.lower() == "да":
            t = temp['true_email']
            w = temp['wrong_email']

            # No info about wrong or correct email in temp
            if not t or not w:
                bot.send_message(message.chat.id, "Не указаны почты")
                return

            # Record this change to log
            with open("edit_log.txt", "a+") as file:
                file.write(
                    f"---------------------------\n{datetime.datetime.today()}\n"
                    f"wrong email = {w[0]}\ntrue email = {t[0]}\n")

            tg_id, vk_id, fb_id = w[4], w[5], w[6]
            t_mail = t[0]

            update_clients(["email", t_mail], ["state", "CLOSED"],
                           ["rate", "5"], ["review_time", "0"])

            # Check if ID that we want to copy != 0 and not the same with correct email ID
            if tg_id not in ["0", t[4]]:
                update_clients(["email", t_mail], ["tg_id", tg_id])
                print(f"Заменили tg_id {t[4]} на {tg_id}\n")

            if vk_id not in ["0", t[5]]:
                update_clients(["email", t_mail], ["vk_id", vk_id])
                print(f"Заменили vk_id {t[5]} на {vk_id}\n")

            if fb_id not in ["0", t[6]]:
                update_clients(["email", t_mail], ["fb_id", fb_id])
                print(f"Заменили fb_id {t[6]} на {fb_id}\n")

            bot.send_message(message.chat.id, delete_client("email", w[0]))
            print(f"Удалили запись с почтой {w[0]}")
            temp['wrong_email'], temp['true_email'] = "", ""

        # Editing cancelled
        elif message.text.lower() == "нет":
            bot.send_message(message.chat.id, "Замена почты отменена")
            temp['wrong_email'], temp['true_email'] = "", ""
        else:
            bot.send_message(message.chat.id, "Не понял, повторите")
예제 #9
0
def react(call):
    """ Handles all callback buttons """

    time.sleep(1)
    buttons = types.InlineKeyboardMarkup()
    user_info = db_find_value('tg_id', call.message.chat.id)

    if call.data == "rub":
        tariff_id = user_info['tariff']
        msg = messages.rub_text

        # If user has active tariff, send button allowing to extend his current tariff
        # Temporarily off
        if False and tariff_id in ['1', '2', '3', '22', '23']:
            buttons.add(
                types.InlineKeyboardButton(text="Продлить текущий тариф",
                                           callback_data=f"Р-{tariff_id}"))
            msg += f"\n\nВаш текущий тариф: {tariff_id}"
            bot.send_message(call.message.chat.id,
                             msg,
                             parse_mode='Markdown',
                             reply_markup=buttons)
        else:
            bot.send_message(call.message.chat.id, msg, parse_mode='Markdown')

    elif call.data == "yuan":
        bot.send_message(call.message.chat.id,
                         messages.yuan_text,
                         parse_mode='Markdown')
    elif call.data == "install":
        bot.send_message(call.message.chat.id, messages.first_install)
    elif call.data == "other":
        bot.send_message(call.message.chat.id,
                         messages.support,
                         parse_mode='Markdown')
    elif call.data == "market":
        open_dialogue("tg_id", call.message.chat.id)
        bot.send_message(
            call.message.chat.id,
            'Здравствуйте! Укажите, пожалуйста, продукт и вопросы по нему')
    elif call.data == "urgent":
        support(call.message, urgent=True)
    elif call.data == "sup":
        support(call.message)

    # If user rated quality less than 5 and pushed feedback button, open dialogue for one message only
    elif call.data == "get_better":
        update_clients(["tg_id", call.message.chat.id],
                       ["state", "ONE MESSAGE"],
                       ["review_time", f"{int(time.time())}"])
        bot.send_message(call.message.chat.id, messages.get_better)

    elif call.data == "pay":
        buttons.add(
            types.InlineKeyboardButton(text="В рублях или в гривнах",
                                       callback_data="rub"))
        buttons.add(
            types.InlineKeyboardButton(text="В юанях", callback_data="yuan"))
        buttons.add(
            types.InlineKeyboardButton(
                text="\U00002753 Связаться с поддержкой", callback_data="sup"))
        bot.send_message(call.message.chat.id,
                         messages.pay_type,
                         reply_markup=buttons)

    elif call.data in ["1", "2", "3", "4", "5"]:

        # User has already rated
        if get_info("rate", "tg_id", call.message.chat.id) != "0":
            bot.send_message(call.message.chat.id,
                             "Вы уже поставили оценку, спасибо!")
            return

        rating = call.data

        # Ask user to make review if he gave the highest rate
        if rating == "5":
            buttons.add(
                types.InlineKeyboardButton(text="\U0001F49B Оставить отзыв",
                                           url=config.review_link))
            bot.send_message(
                call.message.chat.id,
                "Если вам понравился наш сервис - оставьте отзыв, "
                "и мы предоставим вам 10 дней бесплатного VPN!\n\n"
                "_Когда оставите отзыв свяжитесь с нами для получения бонуса_",
                reply_markup=buttons,
                parse_mode='Markdown')
        # Ask user to write feedback
        else:
            buttons.add(
                types.InlineKeyboardButton(
                    text="\U0001F4A1 Оставить пожелание",
                    callback_data="get_better"))
            bot.send_message(call.message.chat.id,
                             "Мы можем что-то улучшить в обслуживании?",
                             reply_markup=buttons)

        bot.send_message(
            config.group_id,
            f"Клиент `{call.message.chat.id}` поставил вам {rating}",
            parse_mode='Markdown')
        update_clients(["tg_id", call.message.chat.id], ["rate", rating])

    # User chose tariff he wants to buy, send him buttons to choose tariff duration in days (ascending order)
    # Temporarily off
    elif False and re.fullmatch(r'[РЮ]-[123]+', call.data):
        currency, tariff_id = call.data.split('-')
        tariffs_list = get_tariffs(['tariff', tariff_id],
                                   ['currency', currency])
        for price, tariff_id, days, currency, desc in sorted(
                tariffs_list, key=lambda x: int(x[2])):
            # Telegram does not support prices lower than 60 rub.
            if int(price) < 60:
                continue
            # Choose correct form of 'день' word
            if days[-1] == '1':
                day_word = 'день'
            elif days[-1] in '234':
                day_word = 'дня'
            else:
                day_word = 'дней'
            buttons.add(
                types.InlineKeyboardButton(
                    text=f"{days} {day_word}",
                    callback_data=f"{currency}-{tariff_id}-{days}"))
        bot.send_message(
            call.message.chat.id,
            f"Выберите, на сколько дней вы хотите продлить тариф {tariff_id}",
            reply_markup=buttons)

    # User chose tariff duration in days, send him payment button
    # Temporarily off
    elif False and re.fullmatch(r'[РЮ]-[123]+-[0-9]+', call.data):
        currency, tariff_id, days = call.data.split('-')
        specific_tariff = get_tariffs(['tariff', tariff_id],
                                      ['currency', currency],
                                      ['days', days])[0]
        price = int(specific_tariff[0])
        prices = [
            types.LabeledPrice(label=f'Тариф {tariff_id} на {days} дней',
                               amount=price * 100)
        ]
        bot.send_invoice(call.message.chat.id,
                         title=f"Тариф {tariff_id}",
                         description='Plati',
                         provider_token=config.pay_token,
                         currency='rub',
                         prices=prices,
                         start_parameter='payment',
                         invoice_payload='HAPPY FRIDAYS COUPON')
예제 #10
0
    bot.send_message(message.chat.id, send_text, reply_markup=markup_buttons)


@bot.message_handler(commands=["start"])
def start(message):
    """ Ask user to send his email address if not identified. Otherwise send default message with reply keyboard """

    time.sleep(1)
    if not db_find_value("tg_id", message.chat.id):
        bot.send_message(message.chat.id, messages.send_email)
    else:
        initial_buttons(message)


@bot.message_handler(func=lambda message: message.chat.id != config.group_id
                     and not db_find_value("tg_id", message.chat.id),
                     content_types=[
                         'text', 'photo', 'video', 'voice', 'audio', 'sticker',
                         'document'
                     ])
def unknown_user(message):
    """ Handle all messages if user is not identified """

    time.sleep(1)
    # Check if message text has '@' between some non-space symbols
    if not message.text or not re.findall(r"\S+@\S+", message.text):
        bot.send_message(message.chat.id, messages.send_email)
        return

    email = re.findall(r"\S+@\S+", message.text)[0].lower()
    # Suppose user entered email, look for it in database