Пример #1
0
class VkHandler(object):
    _auth_consts = None
    _vk_session = None
    _vk_api = None
    _vk_upload = None

    _kernel = None
    _picture_dir = None

    @logger.class_construct
    def __init__(self):
        self._auth_consts = json_handler.auth_constants
        self._vk_session = VkApi(
            token=self._auth_consts['api_token'],
            app_id=self._auth_consts['app_id'],
            client_secret=self._auth_consts['client_secret'])
        self._vk_api = self._vk_session.get_api()
        self._vk_upload = VkUpload(self._vk_session)
        self._kernel = Kernel()
        self._picture_dir = os.environ[
            'BISMARCK_HOME'] + os.sep + "pictures" + os.sep

    def handler(self):
        longpoll = VkLongPoll(self._vk_session)
        for event in longpoll.listen():

            if event.type == VkEventType.MESSAGE_NEW:
                logger.debug("New message: '" + str(event.text) + "'")

                if (event.from_user and not event.from_me) or \
                        (event.from_chat and event.text.find('id336383265') != -1) or event.from_group:
                    logger.info("New message: '" + str(event.text) + "'")

                    answer = self._kernel.talk(str(event.text),
                                               event.from_user)

                    if event.from_user:
                        peer_id = event.user_id
                    elif event.from_chat:
                        peer_id = 2000000000 + event.chat_id
                    else:
                        peer_id = 0 - event.group_id

                    if isinstance(answer, tuple):
                        message, picture = answer
                        picture = self._picture_dir + picture
                        picture_id = self._vk_upload.photo_messages(
                            photos=picture)
                        attachment = "photo{}_{}".format(
                            picture_id[0]['owner_id'], picture_id[0]['id'])
                        self._vk_api.messages.send(peer_id=peer_id,
                                                   message=message,
                                                   random_id=randint(
                                                       0, 1000000000000000),
                                                   attachment=attachment)
                    else:
                        self._vk_api.messages.send(peer_id=peer_id,
                                                   message=answer,
                                                   random_id=randint(
                                                       0, 1000000000000000))
Пример #2
0
class Vk(VkApiGroup):

    vk = None

    def __init__(self, token):
        super().__init__(token=token)
        # self.method = VkApiMethod(self)
        self.upload = VkUpload(self)

    def get_long_poll(self, token):
        return self.method(Methods.GET_LP, {'access_token': token})

    def send_message(self, message: Message):
        # @debug m = message.dict()
        return self.method(Methods.SEND, message.dict())

    def upload_message_document(self, filename: str, peer_id):
        return self.upload.document_message([filename],
                                            'video',
                                            peer_id=peer_id)

    def upload_message_photo(self, filename: str, peer_id):
        return self.upload.photo_messages([filename], peer_id=peer_id)

    @staticmethod
    def str_dict(dictionary):
        result = ''
        for i in dictionary:
            result += str(i) + ','
        result = result[:len(result) - 1]
        return result
Пример #3
0
def _send_photo_path(vk, id, text, photo_path, delete=True, keyboard=None):
    upload = VkUpload(vk)
    uploaded = upload.photo_messages(photo_path)
    if path.exists(photo_path) and delete:
        os.remove(photo_path)
    photo = 'photo' + str(uploaded[0]['owner_id']) + '_' + str(uploaded[0]['id'])
    send_message({"vk": vk, "id": id, "message": text, "sleep_time": 0, "attachment": photo, "keyboard": keyboard})
Пример #4
0
def upload_photo(vk, photo):
    upload = VkUpload(vk)
    response = upload.photo_messages(photo)[0]

    owner_id = response['owner_id']
    photo_id = response['id']
    access_key = response['access_key']

    return owner_id, photo_id, access_key
Пример #5
0
 def photo_msg(self,
               peer_id,
               path_to_photo,
               message: str = None,
               many=False):
     # TODO переделать совместно с созданием фоток
     upload = VkUpload(self.__vk_api)
     resp = upload.photo_messages(peer_id=0, photos=path_to_photo)
     self.__vk_api.messages.send(
         user_ids=peer_id,
         attachment=
         f"photo{resp[0]['owner_id']}_{resp[0]['id']}_{resp[0]['access_key']}",
         message=message,
         random_id=get_random_id())
Пример #6
0
    def picture_send(username1, userid1):

        file_path = profile_create(username1)
        upload = VkUpload(vk_session)

        photo = upload.photo_messages(file_path)
        owner_id = photo[0]['owner_id']
        photo_id = photo[0]['id']
        access_key = photo[0]['access_key']

        attachment = f'photo{owner_id}_{photo_id}_{access_key}'

        vk_session.method(
            'messages.send', {
                'user_id': userid1,
                'message': 'бе',
                'random_id': 0,
                'attachment': attachment
            })
Пример #7
0
class Bot:
    def __init__(self, token: str, group_id: int, testers=None):
        """
        основной класс бота

        :param token: токен группы со всеми разрешениями
        :param group_id: id группы к которой привязн токен
        :param testers: список из id тестеров
        """

        self.group_id = group_id
        self.testers = testers
        self.vk_session = vk_api.VkApi(token=token,
                                       api_version='5.85',
                                       scope='MESSAGE, DOCS, PHOTOS, OFFLINE')

        self.upload = VkUpload(self.vk_session)  # self.vk_session_me
        self.longpoll = VkBotLongPoll(self.vk_session, self.group_id, wait=25)

        self.vk = self.vk_session.get_api()

        self.cmd_keyboard = self.c_keyboard(list(list_cmd.keys()))
        self.exit_keyboard = self.c_keyboard(list('выйти'))
        self.first_run = True

        self.outgoing_mess_queue = Queue()

    def send(self, user_id, message, **kwargs):
        self.vk.messages.send(user_id=user_id, message=message, **kwargs)

    def c_keyboard(self, key_list, one_time=False):
        """
        генерирует клавиатуру (из переданного списка) с 3мя кнопками в одной строке

        :param key_list: список кнопок, которые хоти видеть
        :param one_time: True если хотим видеть одноразовый вызов клавиатуры

        :return: объект VkKeyboard для последующего вызова
        """

        color = VkKeyboardColor.DEFAULT
        keyboard = VkKeyboard(one_time=one_time)
        len_key_list = len(key_list)
        for item in key_list:
            # TODO цвета как-нибудь бы передать
            if item == 'выйти':
                # color = VkKeyboardColor.NEGATIVE
                keyboard.add_button(item,
                                    color=VkKeyboardColor.NEGATIVE,
                                    payload='')
            else:
                keyboard.add_button(item, color=color, payload='')

            if (key_list.index(item) +
                    1) % 3 == 0 and key_list.index(item) != len_key_list - 1:
                keyboard.add_line()
        return keyboard

    def run(self):
        """
        запускает бесконечный цикл в котором слушаем сервер,
        при получении инфы от сервера запускаем поток с обработчиком

        :return:
        """
        queue_thread = threading.Thread(
            target=self.outgoing_mess_queue_handler)
        queue_thread.start()

        log.debug('слушаем сервер')
        for event in self.longpoll.listen():
            if event.type == VkBotEventType.MESSAGE_NEW and event.obj.text:  # and event.to_me and event.text
                text = event.obj.text
                user_id = event.obj.peer_id
                handler = threading.Thread(
                    target=self.handler_mess,
                    args=(user_id, text))  # event.user_id, event.text
                handler.start()
                log.debug('запущен поток для обработки')
            time.sleep(0.05)

    def start(self):
        """
        команда для старта бота
        при старте оповещает тестеров, что бот запустился

        :return:
        """

        log.debug('старт бота')
        if self.testers and self.first_run:
            log.debug('оповещание тестеров')
            self.first_run = False
            [
                self.send(user_id=t_id, message='йа запустилсо ┐( ˘_˘)┌')
                for t_id in self.testers
            ]

        try:
            self.run()
        except Exception as e:
            log.exception(e)
            self.start()

    def outgoing_mess_queue_handler(self):
        """
        обработчик исходящих сообщений
        в очередь скидываются результаты работы функции handler_mess для ответа юзеру

        :return:
        """
        while True:
            try:
                user_id, mess, attach, key_list = self.outgoing_mess_queue.get(
                    timeout=0.1)
            except Empty:
                time.sleep(0.1)
                continue

            # чтобы загружать файлы ВК в прикреплёнке не в функции обработчике, а в основном теле
            # необходимо в аттач складывать dict('тип ВК прикрепления' = [массив ссылок на файлы, ...], ...)
            if attach:
                all_attach = list()
                photo = 'photo'
                doc = 'doc'

                if photo in attach.keys():
                    log.debug(f'{user_id} есть фото в аттаче')
                    for f in attach[photo]:
                        data = self.upload.photo_messages(photos=f,
                                                          peer_id=user_id)[0]
                        log.debug(f'{user_id} загружено фото: {f}')
                        att = 'photo{}_{}'.format(data['owner_id'], data['id'])
                        all_attach.append(att)

                if doc in attach.keys():
                    log.debug(f'{user_id} есть документ в аттаче')
                    for d in attach[doc]:
                        data = self.upload.document_message(
                            d, title=f'doc_{user_id}', peer_id=user_id)[0]
                        log.debug(f'{user_id} загружен документ: {d}')
                        att = 'doc{}_{}'.format(data['owner_id'], data['id'])
                        all_attach.append(att)

                attach = all_attach

            # после того как получим нормальный сформированный аттач и текст для ответа
            # создадим клаву и отправим все это
            keyboard = self.c_keyboard(
                key_list) if key_list else self.cmd_keyboard
            self.send(user_id=user_id,
                      message=mess,
                      keyboard=keyboard.get_keyboard(),
                      attachment=attach)

    def handler_mess(self, user_id, text):
        """
        обработчик входящих сообщений
        в папке /command/ лежат файлы с обработчиками комманд
        my_func переопределяет функцию из list_cmd


        :param user_id: кто написал сообщение
        :param text: текст сообщения

        :return:
        """

        # можно пометить сразу, что прочитали, но тогда при долгом ответе покажется, что мы зависли :)
        # self.vk.messages.markAsRead(peer_id=user_id)

        log.debug('запрос к БДшке')
        bot = psql.get_bot_or_create(user_id,
                                     username='',
                                     about='',
                                     cmd='бот',
                                     status=' ')
        # text = text.lower()

        if bot.cmd != 'бот':
            # если текущая команда пользователя != дефолтной, т.е. он находится в какой-то другой
            # то вызываем тот обработчик, на котором он находится
            log.debug(f'{user_id} текущее состояние: {bot.cmd}')
            my_func = list_cmd[bot.cmd]
        else:
            # если у пользователя нет текущей команды (т.е. дефолтная), то смотрим какие есть у нас
            if text in list_cmd.keys():
                # если такая есть, то вызываем ее
                log.debug(f'{user_id} вызвал команда: {text}')
                my_func = list_cmd[text]
            else:
                # если у нас нет такой команды, то намекаем, что надо выбрать из того, что есть (дефолтная клава)
                log.debug(f'{user_id} вызвал не существующую команду: {text}')
                self.send(user_id=user_id,
                          message='выбирай',
                          keyboard=self.cmd_keyboard.get_keyboard())
                return

        my_func(user_id, text, bot, self.outgoing_mess_queue)

        return
Пример #8
0
                    message='da'
                   )
            if r'kartinochka with luv' in str(event):

                #for name
                id_mes = event.message['from_id']
                user = vk_session.method("users.get", {'user_ids': id_mes})
                name = user[0]['first_name'].lower()
                id = user[0]['id']
                u2 = vk_session.method('users.get', {'user_ids': id_mes,'fields': 'sex'})
                sex = u2[0]['sex']
                print(u2[0]['sex'])

                # for photo
                img, eleven_meme = add_text_on_photo.give_photo(id, name)
                photo = upload.photo_messages(img)
                owner_id = photo[0]['owner_id']
                photo_id = photo[0]['id']
                access_key = photo[0]['access_key']
                attachment = f'photo{owner_id}_{photo_id}_{access_key}'

                #message
                if sex == 2:
                    vk.messages.send(
                        key=('__'),
                        server="__",
                        ts="31",
                        keyboard=keyboard.get_keyboard(),
                        chat_id=event.chat_id,
                        random_id=get_random_id(),
                        message='https://www.youtube.com/watch?v=SWDTdXH6oF0'