VK bot через VK API проблема с сообщениями
11.05.2023, 01:24. Показов 1004. Ответов 0
Добрейший вечерочек. Дело такое, я написал что-то по типу бота для рассылок. Но поперек горла встало ограничение messages от 2019г. При авторизации через логин\пароль и токен по идее токен важнее, поэтому, если у токена есть все нужные разрешения (в данном случае на отправку сообщений), то бот вполне может отправлять сообщения людям из других групп.
Принцип действия бота такой: id_group устанавливает ID группы, на которую будет направлен бот. Send - задает текст(сами вводим), который будет отправлен всем участникам выбранной по ID группы, за исключением админа, зама админа и людей с закрытыми профилями.
По идее этот бот должен быть в интерфейсе вк, через приложение, ID которого указан в коде, но почему-то не работает.
Если поможете реализовать через интерфейс, буду безмерно благодарен.
И самая главная проблема - при авторизации вызывается ошибка API auth error: This application has no right to use messages, хотя благодаря токену со всеми разрешениями такого быть не должно.
И да, я знаю, что сообщества не могут отправлять сообщения пользователю первыми, но мне нужно, что бы бот именно это и делал - рассылал сообщение почти всем участникам. Как сделать - уже не понимаю.
Пытался без авторизации, просто по токену, но тогда вылетает ошибка.
Помогите пожалуйста) уже третий день пытаюсь решить проблему
| Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
| import re
import vk_api
from vk_api.longpoll import VkLongPoll, VkEventType
from vk_api.utils import get_random_id
def auth_handler():
"""Обработчик двухфакторной аутентификации."""
# Код двухфакторной аутентификации
key = input("Введите код двухфакторной аутентификации: ")
# Если: True - сохранить, False - не сохранять.
remember_device = True
return key, remember_device
def start_bot():
global closed_profiles_count, user_message
app_id = '51640150'
login = input('YOUR_LOGIN:')
password = input('YOUR_PASSWORD')
access_token = "тут_должен_быть_токен"
vk_session = vk_api.VkApi(app_id=app_id, login=login, password=password, auth_handler=auth_handler,
token=access_token)
try:
vk_session.auth(token_only=True)
except vk_api.AuthError as error_msg:
print(error_msg)
return
bot_vk = vk_session.get_api()
group_id = None
start_message = "Guten Tag. Schreibe nach dem Befehl */send* den Text, den du an die Gruppe senden möchtest, " \
"und dann werde ich, vielleicht auf Befehl des Führers, diese erbärmliche Schrift an alle " \
"Benutzer in der Gruppe senden, die du mit dem Befehl */id_group* angeben wirst. Wichtig! Geben " \
"Sie den " \
"Text erst NACH dem Befehl */id_group* ein, sonst werde ich nicht auf Ihre unbedeutenden Hilferufe " \
"anterior.. "
try:
bot_vk.messages.send(user_id=bot_vk.session.user_id, message=start_message, random_id=get_random_id())
# Начало прослушивания входящих сообщений
longpoll = VkLongPoll(vk_session)
for event in longpoll.listen():
if event.type == VkEventType.MESSAGE_NEW and event.to_me and event.text:
# Получение текста входящего сообщения
user_message = event.text
if bot_vk.session.user_id == event.peer_id:
# Пользовательский запрос
if user_message.startswith('/send'):
if group_id is None:
bot_vk.messages.send(user_id=bot_vk.session.user_id,
message='Группа не выбрана. Используйте команду "/id_group" для '
'установки идентификатора группы.',
random_id=get_random_id())
continue
# Отправка сообщения
message_text = user_message[5:].strip()
members = bot_vk.groups.getMembers(group_id=group_id)
closed_profiles_count = 0
for user_id in members['items']:
user_info = bot_vk.users.get(user_ids=user_id, fields='is_closed, role')
is_closed = user_info[0]['is_closed']
role = user_info[0]['role']
# Проверка на закрытый профиль и роль администратора или заместителя администратора
if is_closed == 1:
closed_profiles_count += 1
continue
elif role in [1, 2]:
continue
bot_vk.messages.send(user_id=user_id, message=message_text, random_id=get_random_id())
report_message = f'Вышеуказанное сообщение отправлено ' \
f'участникам группы.\n'
report_message += f'Количество пользователей с закрытыми профилями: {closed_profiles_count}'
bot_vk.messages.send(user_id=bot_vk.session.user_id, message=report_message,
random_id=get_random_id())
elif user_message.startswith('/id_group'):
# Установка идентификатора группы
group_link = re.search(r"/id_group\s+(.*)", user_message)
if group_link:
group_link = group_link.group(1)
# Проверка ссылки на работоспособность
if not is_valid_group_link(group_link):
bot_vk.messages.send(user_id=bot_vk.session.user_id,
message='Некорректная ссылка на группу.',
random_id=get_random_id())
continue
# Получение идентификатора группы из ссылки
group_id = extract_group_id(group_link)
bot_vk.messages.send(user_id=bot_vk.session.user_id,
message=f'Идентификатор группы установлен: {group_id}',
random_id=get_random_id())
else:
bot_vk.messages.send(user_id=bot_vk.session.user_id,
message="Некорректная команда \"/id_group\". Используйте команду в "
"формате \"/id_group https://vk.com/mygroup\".",
random_id=get_random_id())
continue
elif user_message.startswith('/stop'):
bot_vk.messages.send(user_id=bot_vk.session.user_id, message='Бот остановлен.',
random_id=get_random_id())
break
else:
# Входящее сообщение от другого пользователя
pass
except vk_api.exceptions.ApiError as error:
print("Ошибка при отправке сообщений:", error)
# Проверка правильности ссылки на группу
def is_valid_group_link(link):
return re.match(r"https?://(www\.)?vk\.com/", link) is not None
# Извлечение идентификатора группы из ссылки
def extract_group_id(link):
match = re.search(r'https?://(www\.)?vk\.com/([^/?]+)', link)
if match:
return match.group(2)
else:
return None
if __name__ == '__main__':
start_bot() |
|
Добавлено через 3 часа 24 минуты
Так-с.. Я настроил двухфакторную аутентификацию и капчу, если ее надо будет пройти пользователю.
Так же я вроде сделал механизм, который позволяет боту нажимать на кнопки в профиле, тем самым обходя ошибку API auth error: This application has no right to use messages, потому что он как пользователь нажимает кнопки и вводит текст. Однако, пробиться не удалось, хотя вроде всё должно работать.
| Python | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
| import re
import time
import tkinter as tk
from io import BytesIO
import requests
import vk_api
from PIL import ImageTk, Image
from vk_api.exceptions import AuthError, Captcha
from vk_api.longpoll import VkLongPoll, VkEventType
from vk_api.utils import get_random_id
def auth_with_captcha(vk_session):
try:
vk_session.auth(token_only=True)
except Captcha as captcha:
# Отображение окна с картинкой и полем ввода текста капчи
root = tk.Tk()
root.title("VK Captcha")
# Загрузка изображения капчи
response = requests.get(captcha.get_url())
image_data = BytesIO(response.content)
image = Image.open(image_data)
photo = ImageTk.PhotoImage(image)
image_label = tk.Label(root, image=photo)
image_label.pack()
# Поле для ввода текста капчи
captcha_entry = tk.Entry(root)
captcha_entry.pack()
def submit_captcha():
captcha_key = captcha_entry.get()
captcha.try_again(captcha_key)
root.destroy() # Закрытие окна после ввода капчи
# Кнопка для отправки капчи
submit_button = tk.Button(root, text="Submit", command=submit_captcha)
submit_button.pack()
root.mainloop()
auth_with_captcha(vk_session) # Рекурсивный вызов после ввода капчи
def auth_handler():
"""Обработчик двухфакторной аутентификации."""
# Код двухфакторной аутентификации
key = input("Введите код двухфакторной аутентификации: ")
# Если: True - сохранить, False - не сохранять.
remember_device = True
return key, remember_device
def start_bot():
global closed_profiles_count, user_message
app_id = '51640150'
login = input('YOUR_LOGIN:')
password = input('YOUR_PASSWORD')
access_token = "токен"
vk_session = vk_api.VkApi(app_id=app_id, login=login, password=password, auth_handler=auth_handler,
token=access_token)
try:
vk_session.auth(token_only=True)
except AuthError as error:
if error.code == 14: # Ошибка требующая капчи
auth_with_captcha(vk_session)
else:
print(f"Auth error: {error}")
return
try:
vk_session.auth(token_only=True)
except vk_api.AuthError as error_msg:
print(error_msg)
return
bot_vk = vk_session.get_api()
group_id = None
start_message = "Guten Tag. Schreibe nach dem Befehl */send* den Text, den du an die Gruppe senden möchtest, " \
"und dann werde ich, vielleicht auf Befehl des Führers, diese erbärmliche Schrift an alle " \
"Benutzer in der Gruppe senden, die du mit dem Befehl */id_group* angeben wirst. Wichtig! Geben " \
"Sie den " \
"Text erst NACH dem Befehl */id_group* ein, sonst werde ich nicht auf Ihre unbedeutenden Hilferufe " \
"anterior.. "
try:
bot_vk.messages.send(user_id=bot_vk.session.user_id, message=start_message, random_id=get_random_id())
# Начало прослушивания входящих сообщений
longpoll = VkLongPoll(vk_session)
for event in longpoll.listen():
if event.type == VkEventType.MESSAGE_NEW and event.to_me and event.text:
# Получение текста входящего сообщения
user_message = event.text
if bot_vk.session.user_id == event.peer_id:
# Пользовательский запрос
if user_message.startswith('/send'):
if group_id is None:
bot_vk.messages.send(user_id=bot_vk.session.user_id,
message='Группа не выбрана. Используйте команду "/id_group" для '
'установки id_group', random_id=get_random_id())
continue
# Отправка сообщения
message_text = user_message[5:].strip()
members = bot_vk.groups.getMembers(group_id=group_id)
closed_profiles_count = 0
for user_id in members['items']:
user_info = bot_vk.users.get(user_ids=user_id, fields='is_closed, role')
is_closed = user_info[0]['is_closed']
role = user_info[0]['role']
# Проверка на закрытый профиль и роль администратора или заместителя администратора
if is_closed == 1:
closed_profiles_count += 1
continue
elif role in [1, 2]:
continue
try:
bot_vk.messages.send(user_id=user_id, message=message_text, random_id=get_random_id())
except Captcha as captcha_error:
captcha_sid = captcha_error.sid
captcha_img = captcha_error.get_url()
# Отправка инструкций пользователю для ввода капчи и получение ответа
captcha_key = input(
"Введите текст с картинки капчи (откройте ссылку, чтобы увидеть картинку): " + captcha_img)
time.sleep(2) # Пауза перед повторной отправкой сообщения
try:
bot_vk.messages.send(user_id=user_id, message=message_text,
random_id=get_random_id(),
captcha_sid=captcha_sid, captcha_key=captcha_key)
except Captcha:
print("Ошибка ввода капчи. Пропуск отправки сообщения пользователю:", user_id)
continue
report_message = f'Вышеуказанное сообщение отправлено ' \
f'участникам группы.\n'
report_message += f'Количество пользователей с закрытыми профилями: {closed_profiles_count}'
bot_vk.messages.send(user_id=bot_vk.session.user_id, message=report_message,
random_id=get_random_id())
elif user_message.startswith('/id_group'):
# Установка идентификатора группы
group_link = re.search(r"/id_group\s+(.*)", user_message)
if group_link:
group_link = group_link.group(1)
# Проверка ссылки на работоспособность
if not is_valid_group_link(group_link):
bot_vk.messages.send(user_id=bot_vk.session.user_id,
message='Некорректная ссылка на группу.',
random_id=get_random_id())
continue
# Получение идентификатора группы из ссылки
group_id = extract_group_id(group_link)
bot_vk.messages.send(user_id=bot_vk.session.user_id,
message=f'Идентификатор группы установлен: {group_id}',
random_id=get_random_id())
else:
bot_vk.messages.send(user_id=bot_vk.session.user_id,
message="Некорректная команда \"/id_group\". Используйте команду в "
"формате \"/id_group https://vk.com/mygroup\".",
random_id=get_random_id())
continue
elif user_message.startswith('/stop'):
bot_vk.messages.send(user_id=bot_vk.session.user_id, message='Бот остановлен.',
random_id=get_random_id())
break
except KeyboardInterrupt:
bot_vk.messages.send(user_id=bot_vk.session.user_id, message='Бот остановлен по команде пользователя.',
random_id=get_random_id())
def is_valid_group_link(link):
"""Проверяет корректность ссылки на группу."""
pattern = r"(https?:\/\/)?(www\.)?vk\.com\/([a-zA-Z0-9_]+)"
match = re.match(pattern, link)
return match is not None
def extract_group_id(link):
"""Извлекает идентификатор группы из ссылки."""
pattern = r"(https?:\/\/)?(www\.)?vk\.com\/([a-zA-Z0-9_]+)"
match = re.match(pattern, link)
if match:
return match.group(3)
return None
if __name__ == "__main__":
start_bot() |
|
0
|