Exemple #1
0
 def start_vote(msg):
     is_multipoll = False
     _ = msg.text.split(' ')
     _.pop(0)
     if len(_):
         if _[0] == "end":
             #stop_vote
             pass
         else:
             txt = ' '.join(_)
             if '"' in txt:
                 _test = StringIO(txt)
                 """Documentation:
                 `Note The reader is hard-coded to recognise either '\r' or '\n' as end-of-line, and ignores lineterminator. This behavior may change in the future.`
                 Well, shit.
                 """
                 _params = csv.reader(_test, delimiter="\n", quotechar='"', lineterminator="�")
                 params = []
                 for pew in _params:
                     params.append(list(filter(None, pew))[0])
             else:
                 params = txt.split("\n")
             voting_text = params.pop(0)
             try_ttl = params.pop(-1)
             try:
                 ttl = int(try_ttl)
             except:
                 params.append(try_ttl)
                 ttl = 5 #minutes)
             if not create_poll(msg.chat.id, voting_text, params, ttl, is_multipoll):
                 bot.send_message(msg.chat.id, "Cant start vote: not enough parameters.")
    def whoru(msg):
        if _mode == "force":
            t = (msg.text or '').split('@')[0]
            if t in ['!start', '/start']:
                #do registration
                try:
                    chat = register_chat(msg.chat.id)
                    print("New chat:", msg.chat.id)
                except:
                    bot.send_message(
                        msg.chat.id,
                        "Already registered. Use `!help` or /help for help.")
            else:
                chat = (get_chat(msg.chat.id))
                if not chat:
                    print("Unknown chat", msg.chat.id, "-- eating all.")
                else:
                    msg.chat.gatekeeper_chat_data = chat
                    return
            return -256

        elif _mode == "auto":
            chat = get_chat(msg.chat.id)
            if not chat:
                print("Unknown chat", msg.chat.id, "-- registering chat.")
                chat = register_chat(msg.chat.id)
            msg.chat.gatekeeper_chat_data = chat
Exemple #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"])
Exemple #4
0
def notify_clients(type_id, id, time_left, notified_clients):
    """ Check if time_left is 3 days or 1 day in seconds (minus 18 hours so we remind at 18:00 Beijing).
     Gap is 59 seconds because cycle repeats every 60 seconds, so it will not repeat on 1-60 'borders' """

    if id == "0":
        return

    message = ""

    if 194341 <= time_left <= 194400:  # 3 days left
        message = messages.left3days
    elif 21541 <= time_left <= 21600:  # 1 day left
        message = messages.left1day
    elif -64859 <= time_left <= -64800:  # Tariff expired
        message = messages.left_today

    if message:
        time.sleep(1)
        if type_id == "tg_id":
            buttons = types.InlineKeyboardMarkup()
            buttons.add(types.InlineKeyboardButton(text="\U0001F4B4 Оплата", callback_data="pay"))
            bot.send_message(int(id), message, reply_markup=buttons)
        elif type_id == "vk_id":
            keyboard = VkKeyboard(inline=True)
            keyboard.add_button("\U0001F4B4Оплата")
            vk_send_message(id, message, keyboard.get_keyboard())
        elif type_id == "fb_id":
            fb_bot.send_text_message(int(id), message)

        update_clients([type_id, id], ['state', 'REMINDED'])
        notified_clients.add(get_info("email", type_id, id))

        print(f"{datetime.datetime.today().date()} Notification sent to {type_id} {id}\n")
Exemple #5
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)
Exemple #6
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)
        def handle_command(msg):
            segs = shlex.split(msg.text)
            segs.pop(0)
            if len(segs) >= 1:
                action = segs[0]
                reaction = None
                trigger = None
                if len(segs) >= 2:
                    trigger = segs[1]
                if len(segs) >= 3:
                    reaction = segs[2]

                if action == "add" and trigger and reaction:
                    add_reaction(msg.chat.id, trigger, reaction)
                    pass
                elif action == "del" and trigger and reaction:
                    delete_trigger(msg.chat.id, trigger, reaction)
                    pass
                elif action == "del" and trigger:
                    #remove reaction completely
                    reaction = trigger
                    delete_reaction(msg.chat.id, reaction)
                elif action == "list":
                    reactions = get_chat_reactions(msg.chat.id)
                    result = ""
                    if len(reactions):
                        for reaction, trigger in reactions.items():
                            result += reaction + ":\n"
                            for t in trigger.split('|'):
                                result += "  " + t + "\n"
                    else:
                        result = "No reactions for this channel."
                    bot.send_message(msg.chat.id, result)
Exemple #8
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)
 def vertical(msg):
     msgs = msg.text.split(" ")
     msgs.pop(0)
     message = " ".join(msgs)
     if len(message):
         bot.send_message(msg.chat.id,
                          "```\n" + do_vertical(message) + "```",
                          parse_mode="Markdown")
 def alertsoff(msg):
     if not msg.from_user:
         bot.send_message(msg.chat.id, "Works only in groups.")
         return
     segs = shlex.split(msg.text)
     segs.pop(0)
     if len(segs):
         for seg in segs:
             delete_trigger(msg.chat.id, seg, "@" + msg.from_user.username)
Exemple #11
0
def coop(message):
    """ Handles cooperation button """

    time.sleep(1)
    buttons = types.InlineKeyboardMarkup()
    buttons.add(
        types.InlineKeyboardButton(text="Сделать предложение",
                                   url='https://zgcvpn.ru/partnership'))
    bot.send_message(message.chat.id, messages.coop, reply_markup=buttons)
def helpmsg(message):
    response = []
    for name, plugin in loaded.items():
        if hasattr(plugin, "helpmsg"):
            result = plugin.helpmsg()
            if result:
                response.append(result)
    bot.send_message(message.chat.id,
                     "\n".join(response),
                     parse_mode="Markdown")
Exemple #13
0
def forward_fb_to_tg(message, review=False):
    """ Send client message to support with client tariff info"""

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

    # Get user info by FB ID
    req = requests.get(
        f"https://graph.facebook.com/{user_id}?fields=first_name,last_name&access_token={config.fb_access_token}")
    user_info = json.loads(req.text)

    # Upper part of the message with emoji and name of the user
    top = "\U0001F4E2 Отзыв\n" if review else f"\U0001F4AC {user_info['first_name']} {user_info['last_name']}\n"

    # Bottom part of the message with id and social network name, so we can reply back
    bottom = f"{str(user_id)} Facebook"

    text = message['message'].get('text') or ''
    attachments = message['message'].get('attachments')

    if attachments:

        # Check if already sent caption
        caption_send = 0

        for att in attachments:
            message = top

            # Send photo only with ID info caption, without message text
            if not caption_send:
                message += text + "\n"

                # Change this so we don't send the same caption with other photo
                caption_send = 1

            message += "\n"

            # Add client tariff info
            if not info_soon_check(user_id, 'vk_id'):
                message += "\n" + client_info_msg("fb_id", user_id)

            message += bottom

            if att['type'] == 'image':
                bot.send_photo(config.group_id, att['payload']['url'], message)
    else:
        message = top + text + "\n\n"

        # Add client tariff info
        if not info_soon_check(user_id, 'fb_id'):
            message += "\n" + client_info_msg("fb_id", user_id)

        message += bottom

        bot.send_message(config.group_id, message)
Exemple #14
0
def set_topic(chat_id, topic):
    bot = helpers.bot.instance()
    set_setting(chat_id, 'old_topic', get_setting(chat_id, 'topic'))
    set_setting(chat_id, 'topic', topic)
    try:
        bot.set_chat_title(chat_id, topic)
    except Exception as e:
        if "rights to change" in str(e):
            bot.send_message(chat_id, "Promote me to change the topic.");
        print(e)
    pass
Exemple #15
0
def shop(message):
    """ Handles zgc shop button """

    time.sleep(1)
    buttons = types.InlineKeyboardMarkup()
    buttons.add(
        types.InlineKeyboardButton(text="\U0001F6D2 ZGC SHOP",
                                   url='https://market.zgc.su'))
    buttons.add(
        types.InlineKeyboardButton(text="\U00002753 Связаться с поддержкой",
                                   callback_data='market'))
    bot.send_message(message.chat.id, messages.shop, reply_markup=buttons)
Exemple #16
0
def blog(message):
    """ Handles blog button """

    time.sleep(1)
    buttons = types.InlineKeyboardMarkup()
    buttons.add(
        types.InlineKeyboardButton(text="Блог",
                                   url='https://market.zgc.su/zgcvpnblog'))
    bot.send_message(
        message.chat.id,
        "Узнайте как заблокировать рекламу, какие появились сервера и многое другое",
        reply_markup=buttons)
Exemple #17
0
def tm(message):
    """ Handles for Turkmenistan button """

    time.sleep(1)
    buttons = types.InlineKeyboardMarkup()
    buttons.add(
        types.InlineKeyboardButton(text="Сайт обслуживания", url='tm.zgc.su'))
    buttons.add(
        types.InlineKeyboardButton(
            text="Как подключить?",
            url='https://sites.google.com/view/zgcvpn/try?authuser=0'))
    bot.send_message(message.chat.id, messages.turk, reply_markup=buttons)
Exemple #18
0
def trial(message):
    """ Handles free trial button """

    time.sleep(1)
    buttons = types.InlineKeyboardMarkup()
    buttons.add(
        types.InlineKeyboardButton(text="\U0001F4B4 Оплата",
                                   callback_data="pay"))
    buttons.add(
        types.InlineKeyboardButton(text="\U00002753 Связаться с поддержкой",
                                   callback_data="sup"))
    bot.send_message(message.chat.id,
                     messages.trial_text,
                     reply_markup=buttons,
                     parse_mode='Markdown')
Exemple #19
0
def pay(message):
    """ Handles payment button """

    time.sleep(1)
    open_dialogue("tg_id", message.chat.id, state="PAY")

    buttons = types.InlineKeyboardMarkup()
    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(message.chat.id, messages.pay_type, reply_markup=buttons)
Exemple #20
0
def initial_buttons(message, send_text=messages.buttons_menu):
    """ Send user message with default reply keyboard"""

    time.sleep(1)
    markup_buttons = types.ReplyKeyboardMarkup(resize_keyboard=True)
    item_pay = types.InlineKeyboardButton("\U0001F4B4 Оплата")
    item_shop = types.InlineKeyboardButton("\U0001F6D2 ZGC SHOP")
    item_trial = types.InlineKeyboardButton("\U0001F193 Пробный период")
    item_promo = types.InlineKeyboardButton("\U0001F4F0 Узнать больше")
    item_turk = types.InlineKeyboardButton(
        "\U0001F1F9\U0001F1F2Для Туркменистана")
    item_coop = types.InlineKeyboardButton("\U0001F91D Сотрудничество")
    item_connection = types.InlineKeyboardButton(
        "\U00002753 Связаться с поддержкой")
    markup_buttons.add(item_pay, item_trial, item_turk, item_promo, item_shop,
                       item_coop, item_connection)
    bot.send_message(message.chat.id, send_text, reply_markup=markup_buttons)
Exemple #21
0
def one_message_pass(message):
    """ User pushed the feedback button after previous support conversation was closed.
        Suppose user entering one-message review """

    time.sleep(1)
    time_past = int(time.time()) - int(
        get_info("review_time", "tg_id", message.chat.id))

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

    else:
        tg_to_tg(config.group_id, message, review=True)
        bot.send_message(message.chat.id, "Спасибо за отзыв!")

    update_clients(["tg_id", message.chat.id], ["state", "CLOSED"])
Exemple #22
0
def create_poll(chat_id, poll_text, answers, ttl, is_multipoll=False):
    if not len(answers):
        return
    bot = helpers.bot.instance()
    poll_id = db.query("insert into polls(chat_id, text, answers, ttl, is_multi) VALUES (:chat_id, :text, :answers, :ttl, :is_multi)", {'chat_id':chat_id, 'text':poll_text, 'answers':json.dumps(answers), 'ttl':ttl * 60, 'is_multi':is_multipoll}, get_id=True)
    sent = bot.send_message(chat_id, compose_body(poll_text, answers), reply_markup=generate_markup(poll_id, answers), parse_mode="Markdown")
    db.query("update polls set message_id = ? where id = ?", [sent.message_id, poll_id])
    return poll_id
Exemple #23
0
 def on_post(self, request, response):
     raw_json = request.stream.read()
     data = CaseInsensitiveDict(json.loads(raw_json))
     status = send_message(data["message"])
     sucess = bool(status)
     response.body = json.dumps({"sucess": sucess})
     if sucess:
         response.status = falcon.HTTP_201
     else:
         response.status = falcon.HTTP_200
Exemple #24
0
def tg_to_tg(to_id, message, from_support=False, review=False):
    """ Transfers messages from client to support and back
        Used instead of TG API forward_message method to be able to reply every client, even those who restricted forwarding """

    text = message.text or message.caption or ''

    # Add info about client to message
    if not from_support:

        # Upper part of the message with emoji and name
        header = f"\U0001F4E2 Отзыв\n" if review \
            else f"\U0001F4AC{message.from_user.first_name} {message.from_user.last_name}\n"

        # Bottom part of the message with id and social network name, so we can reply back
        check = "\U00002705" if get_info("verified", "tg_id",
                                         message.chat.id) else ''
        bottom = f"{message.chat.id} Telegram{check}"
        text = header + text + "\n\n"
        # Add client tariff info
        if not info_soon_check(message.chat.id, 'tg_id'):
            text += "\n" + client_info_msg("tg_id", message.chat.id)
        text += bottom

    if message.text:
        bot.send_message(to_id, text)
        time.sleep(1)
    if message.photo:
        photo_max_res = sorted(message.photo,
                               key=lambda x: x.height)[-1].file_id
        bot.send_photo(to_id, photo_max_res, caption=text)
        time.sleep(1)
    if message.video:
        bot.send_video(to_id, message.video.file_id, caption=text)
    if message.document:
        bot.send_document(to_id, message.document.file_id, caption=text)
    if message.voice:
        bot.send_voice(to_id, message.voice.file_id)
        # Voice message has no caption, so send empty text message with top+bottom borders to be able to reply
        # Same for audio and stickers
        if not from_support:
            bot.send_message(to_id, text)

    if message.audio:
        bot.send_audio(to_id, message.audio.file_id)
        if not from_support:
            bot.send_message(to_id, text)

    if message.sticker:
        bot.send_sticker(to_id, message.sticker.file_id)
        if not from_support:
            bot.send_message(to_id, text)
Exemple #25
0
def buttons_handler(user_id, payload):
    """ Handles all available buttons """

    time.sleep(1)
    if payload == "pay":
        open_dialogue("fb_id", user_id, state="PAY")

        buttons = [Button(title='Рубли ₽ / Гривны ₴', type='postback', payload='rub'),
                   Button(title='Юани ¥', type='postback', payload='yuan'),
                   Button(title='\U00002753Поддержка', type='postback', payload='sup')]

        fb_bot.send_button_message(user_id, messages.pay_type, buttons)

    elif payload == "trial":

        buttons = [Button(title='\U0001F4B4Оплата', type='postback', payload='pay'),
                   Button(title='\U00002753Поддержка', type='postback', payload='sup')]

        fb_bot.send_button_message(user_id, messages.trial_text_vk, buttons)

    elif payload == "turk":

        buttons = [Button(title="Сайт обслуживания", type='web_url', url="http://tm.zgc.su"),
                   Button(title="Как подключить?", type='web_url',
                          url="https://sites.google.com/view/zgcvpn/try?authuser=0")]
        fb_bot.send_button_message(user_id, messages.turk, buttons)

    elif payload == "sup":
        support(user_id)

    elif payload == "urgent":
        support(user_id, urgent=True)

    elif payload == "other":

        buttons= [Button(title='\U0001F193Попробовать', type='postback', payload='trial'),
                  Button(title='\U0001F1F9\U0001F1F2Туркменистан', type='postback', payload='turk'),
                  Button(title='\U0001F6D2ZGC SHOP', type='web_url', url='https://market.zgc.su')]
        fb_bot.send_button_message(user_id, messages.buttons_menu, buttons)

    elif payload == "rub":
        fb_bot.send_text_message(user_id, messages.rub_text_vk)

    elif payload == "yuan":
        fb_bot.send_text_message(user_id, messages.yuan_text_vk)

    elif payload == "install":
        fb_bot.send_text_message(user_id, messages.first_install)

    elif payload == "sup_other":
        fb_bot.send_text_message(user_id, messages.support_vk)

    # If user rated quality less than 5 and pushed feedback button, open dialogue for one message only
    elif payload == "wish":
        fb_bot.send_text_message(user_id, messages.get_better)
        update_clients(["fb_id", user_id], ["state", "ONE MESSAGE"], ["review_time", f"{int(time.time())}"])

    # Buttons to rate the quality of support
    elif payload in ["2", "4", "5"]:

        # User has already rated
        if get_info("rate", "fb_id", user_id) != "0":
            fb_bot.send_text_message(user_id, "Вы уже поставили оценку, спасибо!")
            return

        # Ask user to make review if he gave the highest rate
        if payload == "5":
            buttons = [Button(title="\U0001F49B Отзыв", type='web_url',
                              url=config.review_link)]

            fb_bot.send_button_message(user_id, "Если вам понравился наш сервис - оставьте отзыв, "
                                                "и мы предоставим вам 10 дней бесплатного VPN!\n\n"
                                                "Когда оставите отзыв свяжитесь с нами для получения бонуса",
                                       buttons)

        # Ask user to write feedback
        else:
            buttons = [Button(title='\U0001F4A1 Пожелание', type='postback', payload='wish')]
            fb_bot.send_button_message(user_id, "Мы можем что-то улучшить в обслуживании?", buttons)

        bot.send_message(config.group_id, f"Клиент `{user_id}` поставил вам {payload}", parse_mode='Markdown')
        update_clients(["fb_id", user_id], ["rate", payload])
Exemple #26
0
def buttons_handler(user_id, button_text):
    """ Handles all available buttons """

    if button_text == "\U0001F4B4Оплата":
        open_dialogue("vk_id", user_id, state="PAY")

        keyboard = VkKeyboard(inline=True)
        keyboard.add_button("В рублях ₽ или в гривнах ₴")
        keyboard.add_line()
        keyboard.add_button("В юанях ¥")
        keyboard.add_line()
        keyboard.add_button("\U00002753Связаться с поддержкой")

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

    elif button_text == "В рублях ₽ или в гривнах ₴":
        vk_send_message(user_id, messages.rub_text_vk, reply_keyboard())

    elif button_text == "В юанях ¥":
        vk_send_message(user_id, messages.yuan_text_vk, reply_keyboard())

    elif button_text == "\U0001F193Попробовать":
        keyboard = VkKeyboard(inline=True)

        keyboard.add_button("\U0001F4B4Оплата")
        keyboard.add_line()
        keyboard.add_button("\U00002753Связаться с поддержкой")

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

    elif button_text == "\U00002753Связаться с поддержкой":
        vk_support(user_id)

    elif button_text == "Срочная связь":
        vk_support(user_id, urgent=True)

    elif button_text == "Первичная настройка":
        vk_send_message(user_id, messages.first_install, reply_keyboard())

    elif button_text == "Другое":
        vk_send_message(user_id, messages.support_vk, reply_keyboard())

    elif button_text == "ZGC SHOP":
        open_dialogue("vk_id", user_id)
        vk_send_message(
            user_id,
            "Здравствуйте! Укажите, пожалуйста, продукт и вопросы по нему",
            reply_keyboard())

    elif button_text == "\U0001F4F0Узнать больше":
        keyboard = VkKeyboard(inline=True)

        keyboard.add_openlink_button("Блог",
                                     "https://market.zgc.su/zgcvpnblog")

        vk_send_message(
            user_id,
            "Узнайте как заблокировать рекламу, какие появились сервера и многое другое",
            keyboard.get_keyboard())

    elif button_text == "\U0001F1F9\U0001F1F2Туркменистан":
        keyboard = VkKeyboard(inline=True)

        keyboard.add_openlink_button("Сайт обслуживания", "http://tm.zgc.su")
        keyboard.add_line()
        keyboard.add_openlink_button(
            "Как подключить?",
            "https://sites.google.com/view/zgcvpn/try?authuser=0")

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

    elif button_text == "\U0001F6D2ZGC SHOP":
        keyboard = VkKeyboard(inline=True)

        keyboard.add_openlink_button("\U0001F6D2 ZGC SHOP",
                                     "https://market.zgc.su")
        keyboard.add_line()
        keyboard.add_button("Связаться с поддержкой")

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

    elif button_text == "Связаться с поддержкой":
        open_dialogue("vk_id", user_id)
        vk_send_message(
            user_id,
            "Здравствуйте! Укажите, пожалуйста, продукт и вопросы по нему",
            reply_keyboard())

    elif button_text == "\U0001F91DСотрудничество":
        keyboard = VkKeyboard(inline=True)

        keyboard.add_openlink_button("Сделать предложение",
                                     "https://zgcvpn.ru/partnership")

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

    # If user rated quality less than 5 and pushed feedback button, open dialogue for one message only
    elif button_text == "\U0001F4A1 Оставить пожелание":
        vk_send_message(user_id, messages.get_better)
        update_clients(["vk_id", user_id], ["state", "ONE MESSAGE"],
                       ["review_time", f"{int(time.time())}"])

    # Buttons to rate the quality of support
    elif button_text in [
            "\U0001F92C 1", "\U00002639 2", "\U0001F610 3", "\U0001F642 4",
            "\U0001F600 5"
    ]:
        keyboard = VkKeyboard(inline=True)

        # User has already rated
        if get_info("rate", "vk_id", user_id) != "0":
            vk_send_message(user_id, "Вы уже поставили оценку, спасибо!")
            return

        rating = button_text[-1]

        # Ask user to make review if he gave the highest rate
        if rating == "5":
            keyboard.add_openlink_button("\U0001F49B Оставить отзыв",
                                         config.review_link)

            vk_send_message(
                user_id, "Если вам понравился наш сервис - оставьте отзыв, "
                "и мы предоставим вам 10 дней бесплатного VPN!\n\n"
                "Когда оставите отзыв свяжитесь с нами для получения бонуса",
                keyboard=keyboard.get_keyboard())

        # Ask user to write feedback
        else:
            keyboard.add_button("\U0001F4A1 Оставить пожелание")
            vk_send_message(user_id,
                            "Мы можем что-то улучшить в обслуживании?",
                            keyboard=keyboard.get_keyboard())

        time.sleep(1)
        bot.send_message(config.group_id,
                         f"Клиент `{user_id}` поставил вам {rating}",
                         parse_mode='Markdown')
        update_clients(["vk_id", user_id], ["rate", rating])
Exemple #27
0
def forward_vk_to_tg(event, review=False, user_state='OPEN'):
    """ Send client message to support with attachments and client tariff info """

    time.sleep(1)
    user = vk.users.get(user_id=event.user_id)

    # Upper part of the message with emoji and name of the user
    top = "\U0001F4E2 Отзыв\n" if review else f"\U0001F4AC {user[0]['first_name']} {user[0]['last_name']}\n"

    # Bottom part of the message with id and social network name, so we can reply back
    check = "\U00002705" if get_info("verified", "vk_id",
                                     event.user_id) else ''
    bottom = f"{str(event.user_id)} Vkontakte{check}"
    attachments = vk.messages.getById(
        message_ids=event.message_id)['items'][0]['attachments']

    if attachments:

        # Checker to avoid sending more than one caption
        caption_sent = False

        # Checker to make sure attachment successfully sent to support
        attachment_sent = False

        for att in get_attachments(event.message_id):
            if att.get('filter') == 'photo':

                # Send photo only with ID info caption, without message text
                if caption_sent:
                    message = top + "\n" + bottom
                    bot.send_photo(config.group_id,
                                   att.get('url'),
                                   caption=message)
                    continue

                # Make sure we get string type anyway
                text = event.message or ""

                message = top + text + "\n\n"

                # Add client tariff info
                if not info_soon_check(event.user_id, 'vk_id'):
                    message += client_info_msg("vk_id", event.user_id)

                message += bottom
                bot.send_photo(config.group_id,
                               att.get('url'),
                               caption=message)
                attachment_sent = True

                # Change this so we don't send the same caption with other photo
                caption_sent = True

                # Autoprocess payment using OCR
                if user_state == 'PAY':
                    autopay(event.user_id,
                            'vk_id',
                            att.get('url'),
                            is_url=True)

        # notify support that user attached unsupported filetype
        if not attachment_sent:
            text = event.message or ""
            message = top + text + "\n_ОТ БОТА: клиент приложил в сообщение вконтакте файл, " \
                                   "который нельзя отправить в телеграм_\n\n"

            if not info_soon_check(event.user_id, 'vk_id'):
                message += client_info_msg("vk_id", event.user_id)

            message += bottom
            bot.send_message(config.group_id, message, parse_mode='Markdown')

    else:
        message = top + event.message + "\n\n"

        # Add client tariff info
        if not info_soon_check(event.user_id, 'vk_id'):
            message += "\n" + client_info_msg("vk_id", event.user_id)

        message += bottom
        bot.send_message(config.group_id, message)
Exemple #28
0
def support_group(message):
    """ Handle all messages in support group """

    time.sleep(1)

    # Bot info message
    if message.text and message.text.lower() == "/info":
        bot.send_message(config.group_id, messages.info)

    # Message is reply to some message
    if message.reply_to_message:
        client_text = message.reply_to_message.text or message.reply_to_message.caption

        if not client_text:
            pass

        # Reply object message was forwarded from tg
        elif client_text and client_text.endswith(
                "Telegram") or client_text.endswith("Telegram\U00002705"):

            tg_id = client_text.split()[-2]

            # User id does not fit 'one or more numeral' regexp
            if not re.fullmatch(r"[0-9]+", str(tg_id)):
                bot.send_message(
                    config.group_id, "Не удалось отправить сообщение. "
                    "Скорее всего это закрытый аккаунт без айди в подписи")
                return

            # Close dialogue
            if message.text and message.text.lower() in [
                    "пока", "/пока", "off", "конец", "/q"
            ]:
                close_dialogue("tg_id", tg_id)
            # Close payment dialogue
            elif message.text and message.text.lower() in ["/оплата", "оп"]:
                close_dialogue("tg_id", tg_id, pay=True)
            # Close dialogue silently
            elif message.text and message.text.lower() == "/закрыть":
                close_dialogue("tg_id", tg_id, silent=True)
            # Check if message was forwarded by bot, not by other user
            elif message.reply_to_message.from_user.id == config.bot_id:
                copy_send_message(
                    tg_id, message.chat.id,
                    message.message_id)  # Finally, send answer to client :)
                open_dialogue("tg_id", tg_id)

        # Reply object message was forwarded from VK
        elif client_text and client_text.endswith(
                "Vkontakte") or client_text.endswith("Vkontakte\U00002705"):
            vk_id = client_text.split()[-2]

            if message.text and message.text.lower() in [
                    "пока", "off", "конец", "/q"
            ]:
                close_dialogue("vk_id", vk_id)
            elif message.text and message.text.lower() in ["/оплата", "оп"]:
                close_dialogue("vk_id", vk_id, pay=True)
            elif message.text and message.text.lower() == "/закрыть":
                close_dialogue("vk_id", vk_id, silent=True)
            else:
                tg_to_vk(message, vk_id)
                open_dialogue("vk_id", vk_id)

        # Reply object message was forwarded from FB
        elif client_text and client_text.endswith("Facebook"):
            fb_id = client_text.split()[-2]

            if message.text and message.text.lower() in [
                    "пока", "/пока", "off", "конец", "/q"
            ]:
                close_dialogue("fb_id", fb_id)
            elif message.text and message.text.lower() in ["/оплата", "оп"]:
                close_dialogue("fb_id", fb_id, pay=True)
            elif message.text and message.text.lower() == "/закрыть":
                close_dialogue("fb_id", fb_id, silent=True)
            else:
                tg_to_fb(message, fb_id)

        # my code
        elif client_text and client_text.endswith("Web_client"):
            import data_structs as ds
            import helpers

            replied_message = message.reply_to_message.text

            reply_email = helpers.get_email_from_message(replied_message)

            ws_message = json.dumps({'from': 'bot', 'message': message.text})

            import asyncio

            asyncio.run(ds.send_ws_msg(reply_email, ws_message))

    # Message is not reply to some message
    else:

        # Message text is dialogue closing command
        if message.text and message.text.lower().split()[0] in [
                "пока", "/пока", "off", "конец", "/q"
        ]:

            # If not replying to some message, closing message must be exactly 2 words
            # and contain ID of user whose dialogue we want to close
            if len(message.text.lower().split()) != 2:
                bot.send_message(
                    message.chat.id,
                    "Отправьте команду и айди через пробел, например:\n"
                    "Пока 1234567")
                return

            # We don't know which messenger this id belongs to, so just try to close this ID for every type
            for id_type in ["tg_id", "vk_id", "fb_id"]:
                close_dialogue(id_type, message.text.lower().split()[1])

        elif message.text and message.text.lower().split()[0] in [
                "/оплата", "оп"
        ]:
            if len(message.text.lower().split()) != 2:
                bot.send_message(
                    message.chat.id,
                    "Отправьте команду и айди через пробел, например:\n"
                    "/оплата 1234567")
                return

            for id_type in ["tg_id", "vk_id", "fb_id"]:
                close_dialogue(id_type,
                               message.text.lower().split()[1],
                               pay=True)

        elif message.text and message.text.lower().split()[0] == "/закрыть":
            if len(message.text.lower().split()) != 2:
                bot.send_message(
                    message.chat.id,
                    "Отправьте команду и айди через пробел, например:\n"
                    "/закрыть 1234567")
                return

            for id_type in ["tg_id", "vk_id", "fb_id"]:
                close_dialogue(id_type,
                               message.text.lower().split()[1],
                               silent=True)
Exemple #29
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, "Не понял, повторите")
Exemple #30
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')
Exemple #31
0
def mailing(message):
    """ Sends a message to clients with selected tariffs """

    time.sleep(1)
    txt = message.text or message.caption

    if txt == "/рассылка":
        bot.send_message(message.chat.id, messages.mailing_tariffs)
        return

    client_text = message.reply_to_message.text

    if client_text == messages.mailing_tariffs:
        temp['tariffs'] = [i.lower() for i in txt.split()]
        bot.send_message(message.chat.id, messages.mailing_message)

    elif client_text == messages.mailing_message:
        temp['message_id'] = message.message_id
        temp['mail_text'] = txt
        bot.send_message(
            message.chat.id,
            f"Следующие тарифы: {', '.join(temp['tariffs'])}\n"
            f"Получат сообщение:\n{txt}\n\n"
            f"Продолжить? Да/Нет ответом.\n"
            f"Чтобы отправить ТОЛЬКО в телеграм или вконтакте, ответьте тг/вк")

    elif client_text.startswith("Следующие тарифы:"):
        if txt.lower() in ["да", "вк", "тг"]:

            if not temp['tariffs'] or not temp['mail_text']:
                bot.send_message(message.chat.id, "Не выбраны тарифы/текст!")
                return
            if txt.lower() == "вк":
                spam(temp['tariffs'],
                     temp['mail_text'],
                     message.chat.id,
                     VK_only=True)
            elif txt.lower() == 'тг':
                spam(temp['tariffs'],
                     temp['mail_text'],
                     message.chat.id,
                     TG_only=True)
            else:
                spam(temp['tariffs'], temp['mail_text'], message.chat.id)
            bot.send_message(message.chat.id, "Рассылка отправлена")

        elif txt.lower() == "нет":
            bot.send_message(message.chat.id, "Рассылка отменена")
            temp['tariffs'], temp['mail_text'] = [], ''

        else:
            bot.send_message(message.chat.id, "Не понял, повторите")