Теперь Кью работает в режиме чтения

Мы сохранили весь контент, но добавить что-то новое уже нельзя

Как правильно написать код на пайтон для моей задачи?

PythonЯзыки программирования
марина к.
Python Q
  · 655
На Кью задали 1 похожий вопрос
Увлекаюсь програмированием  · 1 дек 2021
Я пишу бота, и у меня возникла проблема: никак не могу написать код для пересыла сообщения пользователя другому пользователю, администратору например
Вот мой код: https://pastebin.com/rCP1rQDb,
мне нужно, чтобы при нажатии кнопки "Ошибка" пользователь писал текст и этот текст пересылался администратору.
Помогите пожалуйста, гуглил, изучал, так ничего и не понял. Осталось сделать только это и мой школьный проект готов)
Еще подскажите пожалуйста хороший БЕСПЛАТНЫЙ хост для моего бота
Привет. Все таки, необходимо более глубже подходить к задаче, если есть какие-либо нестандартные условия. отсылка СМС администратору либо отправка почтового сообщения и т.д.. Действительно эти подходы немного сложнее, но и функционал получится богаче.
Как бы там небыло, все таки начинайте изучать VK API.
Да, сложнее, но вы сможете создавать полноценный бот.
По поводу хостинга их ооочень много, один из них
Посмотрите если понравится.
Возможно, при оперированием API позволяет получить достаточно сложные системы.
С уважением
@Жуков Игорь, Спасибо вам большое за ответ, начну изучать Vk api)
И все же асинхронная функция Vkbottle работает намного быстрее, чем тот же Vk api, и хотелось бы решить мою проблему в Vkbottle
В Vkbottle тоже есть подходящие классы, которые обрабатывают сообщения от пользователей, но вот как их применять в своем проекте, я не понимаю. Смотрел видеоролики, читал документацию официальную, так и не понял...
@марина к., Если будет время набросаю Вам класс работы с VK Api
@Жуков Игорь, хорошо, буду ждать, спасибо вам огромное
@марина к., Добрый день
По вашему вопросу
....И все же асинхронная функция Vkbottle работает намного быстрее, чем тот же Vk api.... Данное утверждение ошибочно во многих смыслах. Все таки подробнее изучите и не путайте Vk api и асинхронная функция Vkbottle.
Данный пример просто демонстрирует использование
aiohttp
asyncio
на данных библиотеках базируется Ваш Vkbottle. Прошу Вас изучить их подробно.
Далее прошу Вас создать 2 py файла
В main.py поместите код
import asyncio

from asyncvkapi import AsyncVKApi

token_id = '**************************'
group_id = 100000001
bot = AsyncVKApi(token_id)


# И так на каждое сообщение или событие. для каждого варианта свои вункции и вариант в Декораторе
# Все это будет работать при минимальных описаниях. для полноценного бота надо использовать БД
@bot.command(text="ошибка")
async def test(ctx):
    await ctx.bot.send(ctx.message.user_id, 'рассматриваем вашу ошибку"')
    user_id = ctx.message.user_id

    # если есть администратор и у вас есть его ИД user_id = то можете ему пересылать сообщения если все настройки VK
    # и доступ позволяют это сделать

    def check(ctx):
        return user_id == ctx.message.user_id and ctx.message.text == '123'

    try:
        ctx = await ctx.bot.wait_for(check, timeout=10)
        await ctx.bot.send(ctx.message.user_id, 'Ответ')

    except asyncio.TimeoutError:
        await ctx.bot.send(ctx.message.user_id, 'истекло время')


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    bot.run_bot(group_id)
а вот второй файл
from random import randint

import aiohttp
import asyncio


class ApiVKException(Exception):
    def __init__(self, method, error):
        super(Exception, self).__init__()
        self.method = method
        self.code = error['error_code']
        self.error = error

    def __str__(self):
        return '[{}] {}'.format(self.error['error_code'],
                                self.error['error_message'])


class Msg:
    def __init__(self, event):
        self.user_id = event['from_id']
        self.text = event['text']


class Ctx:
    def __init__(self, msg, bot):
        [self.bot](http://self.bot) = bot
        self.message = msg


def get_random_id():
    return randint(1, 10000000)


class AsyncVKApi:
    def __init__(self, token, version=5.131):
        self.token = token
        self.base_url = '[https://api.vk.com/method/](https://api.vk.com/method/)'
        self.version = version

        self.wait = 30
        self.key = None
        self.server = None
        self.ts = None

        [self.events](http://self.events) = []
        self.listeners = []
        self.commands = []
        # self.__extensions = {}

    def command(self, text):
        def decorator(fn):
            new_command = {
                'execute': fn,
                'text': text
            }

            def wrapper(ctx):
                fn(ctx)

            self.commands.append(new_command)
            return wrapper

        return decorator

    async def wait_for(self, check, timeout=60):
        future = self.loop.create_future()
        self.listeners.append((future, check))
        return await asyncio.wait_for(future, timeout)

    # Старт
    def run_bot(self, group_id):
        [asyncio.run](http://asyncio.run)(self.update_bot_longpool(group_id))
        [asyncio.run](http://asyncio.run)(self.start_loop())

    async def send(self, peer_id, msg, keyboard=None, attachment=None):
        base_url = self.base_url + 'messages.send'
        params = {'access_token': self.token,
                  'v': self.version,
                  'user_id': peer_id,
                  'message': msg,
                  'random_id': get_random_id(), }
        if keyboard:
            params['keyboard'] = keyboard

        if attachment:
            params['attachment'] = attachment

        async with aiohttp.ClientSession() as session:
            async with [session.post](http://session.post)(base_url, data=params) as resp:
                print(await resp.json())

    async def update_bot_longpool(self, group_id, update_ts=True):
        resoinse_option = await self.method('groups.getLongPollServer', {'group_id': group_id})
        self.key = resoinse_option['key']
        self.server = resoinse_option['server']

        if update_ts:
            self.ts = resoinse_option['ts']

        self.group_id = group_id

    async def start_loop(self):
        self.loop = asyncio.get_event_loop()
        print('Ready')
        async for ctx in self.listen():
            self.dispatch(ctx)

    async def method(self, method_name, args=None):
        base_url = self.base_url + method_name
        params = {'access_token': self.token, 'v': self.version}
        if args:
            params = {**params, **args}

        async with aiohttp.ClientSession() as session:
            async with [session.post](http://session.post)(base_url, data=params) as resp:
                response = await resp.json()

                # Ошибка
                print(response)

                if 'error' in response.keys():
                    error = ApiVKException(method_name, {'error_message': response, 'error_code': response["error"]["error_code"]})
                    raise error

                return response['response']

    def dispatch(self, ctx):
        # dispatch new event for listeners if has
        for listener in self.listeners:
            if not listener[0].cancelled():
                if listener[1](ctx):
                    listener[0].set_result(ctx)
                    self.listeners.remove(listener)
                    return
            else:
                self.listeners.remove(listener)

        # else if no listeners
        asyncio.create_task(self.on_message(ctx))

    # Сравнение с атрибутом декоратора text
    async def on_message(self, ctx):
        for command in self.commands:
            text_command = ctx.message.text.lower()
            if text_command.startswith(command['text']):
                await command['execute'](ctx)

    async def listen(self):
        """ Слушать сервер """
        while True:
            async for ctx in self.check():
                yield ctx

    async def check(self):
        """ Настройки """
        values = {
            'act': 'a_check',
            'key': self.key,
            'ts': self.ts,
            'wait': self.wait,
        }
        async with aiohttp.ClientSession() as session:
            async with [session.post](http://session.post)(self.server, params=values, timeout=self.wait + 20) as resp:
                response = await resp.json()
                if 'failed' not in response:
                    self.ts = response['ts']
                    new_events = [raw_event for raw_event in response['updates']]
                    new_events = filter(lambda event: event['type'] == 'message_new', new_events)
                    for event in new_events:
                        new_msg = Msg(event['object']['message'])
                        yield Ctx(new_msg, self)

                elif response['failed'] == 1:
                    self.ts = response['ts']

                elif response['failed'] == 2:
                    await self.update_bot_longpool(self.group_id, update_ts=False)

                elif response['failed'] == 3:
                    await self.update_bot_longpool(self.group_id, update_ts=False)
Вот будет реагировать и отсылать сообщения для сообщества или пользователя, смотря куда что вы подключите.
Меня нет в Контакте, поэтому пришлось создавать профиль, что занимает время.
Класс можете править как хотите главное понять смысл его работы
@Жуков Игорь, вы не представляете как я долго искал данного ответа, спасибо вам огромное))
@Жуков Игорь, а вот еще такой вопросик при запуске кода из файла main.py выходит ошибка, что нет такого модуля asyncvkapi
Я пытался найти в просторах интерната такой модуль и установить его, но безуспешно или я что то делаю не так!?
@Жуков Игорь,  у меня как-то получилось сделать, но вот возникли еще небольшие проблемки: я использовал метод users.get() и в нем должна хранится информация о пользователе (имя, фамилия, адишник, короткое имя и тд) мне нужно отправить короткое имя пользователя, но когда я пытаюсь это сделать у меня выводит None, а если я хочу вывести просто id то все хорошо получатся, но он получается не кликабельный, мне нужен кликабельный
from [vkbottle.bot](http://vkbottle.bot) import Bot, Message
from vkbottle import Keyboard, KeyboardButtonColor, \
                        Text, OpenLink, Location, EMPTY_KEYBOARD
from vkbottle_types import BaseStateGroup
from vkbottle import CtxStorage



bot = Bot(token="")
ctx = CtxStorage()

class RegData(BaseStateGroup):

    OSHY = 0


@bot.on.message(lev="Ошибка")
async def oshi_handler(message: Message):
    keyboard = Keyboard(one_time=True).add(Text("Назад в меню", {"cmd": "menu"}))
    await message.answer("❌ Это форма для отправки ошибок, багов, проблем, предложений и тд.\n\n\
❗ Подробно опиши ошибку, с которой ты столкнулся.\n\
👁‍🗨 Лучше чтобы был скрин", keyboard=keyboard)
    await bot.state_dispenser.set(message.peer_id, RegData.OSHY)
    return "Что то там...1"




@bot.on.message(state=RegData.OSHY)
async def oshi_handler(message: Message):
    userq = await bot.api.users.get(message.from_id)
    ctx.set("oshy", message.text)                                                                                            
    txtq = ctx.get("oshy")
    await bot.api.messages.send(peer_id=291080599, message=f"Новая ошибка от {userq[0].first_name} {userq[0].last_name} Vkid: {userq[0].domain}: \n{txtq}", random_id=0) #вот тут domain должен вывести короткое имя, но выводит None, а если я пишу id то все работает
    return "Спасибо за обнаружение ошибки.."


@bot.on.message()
async def MessagesLongpollParams(message: Message):
    keyboard = Keyboard(one_time=True)
    keyboard.add(Text("Меню", {"cmd": "menu"}), color=KeyboardButtonColor.NEGATIVE)
    await message.answer("Я тебя не понимаю.\n\n Перейди в меню и выбери из пунктов, что ты хочешь узнать.", keyboard=keyboard)



bot.run_forever()
Я - программист, который знает немного о циклах и условиях.  · 5 дек 2021
Невозможно "правильно" написать код: можно только правильно решить задачу. Путей решить одну и ту же задачу, особенно елси она сложная, огромное количество. Для начала любую задачу надо декмпозировать: то есть вы берете и разбиваете задачу на части, чтобы каждая часть была понятной. После этого для каждой части (подзадачи) пишете код. Если вы любите ООП, то для каждой... Читать далее