I’m trying to implement VK API, so thanks OAuth code I get a token and just add this scope offline,audio and now doing this request:
https://api.vk.com/method/account.getInfo?access_token=XXXXX&v=5.62
And go this in return:
{
"error": {
"error_code": 15,
"error_msg": "Access denied: no access to call this method",
"request_params": [
{
"key": "oauth",
"value": "1"
},
{
"key": "method",
"value": "account.getInfo"
},
{
"key": "v",
"value": "5.62"
}
]
}
}
Why, there’s a scope for this too?
Nakilon
34.5k14 gold badges106 silver badges139 bronze badges
asked Jan 19, 2017 at 16:10
Your application isn’t Standalone type or you received access token not via Implicit Flow scheme.
Note: you should set parameter redirect_uri=https://oauth.vk.com/blank.html to get access token without limitations. In other ways access token will be limited to call methods which available only for standalone applications.
answered Jan 19, 2017 at 22:32
![]()
Petr FlaksPetr Flaks
5132 gold badges7 silver badges24 bronze badges
1
Код, пожалуйте, не работает почему-то создание qr-кода и размытие, он сохраняет qr.jpg, а обратно почему-то не отправляет, код ошибки:
C:UsersUnstaPycharmProjectsuntitledvenvScriptspython.exe C:/Users/Unsta/.PyCharmCE2019.2/config/scratches/scratch_1.py
Traceback (most recent call last):
File «C:/Users/Unsta/.PyCharmCE2019.2/config/scratches/scratch_1.py», line 178, in
main()
File «C:/Users/Unsta/.PyCharmCE2019.2/config/scratches/scratch_1.py», line 132, in main
send_image(event.user_id, ‘На основе Вашего текста «‘ + qr_text + ‘» был сгенерирован QR-код!’, [‘qr.jpg’])
File «C:/Users/Unsta/.PyCharmCE2019.2/config/scratches/scratch_1.py», line 41, in send_image
uploaded_photos = upload.photo_messages(photos)
File «C:UsersUnstaPycharmProjectsuntitledvenvlibsite-packagesvk_apiupload.py», line 93, in photo_messages
url = self.vk.photos.getMessagesUploadServer()[‘upload_url’]
File «C:UsersUnstaPycharmProjectsuntitledvenvlibsite-packagesvk_apivk_api.py», line 681, in call
return self._vk.method(self._method, kwargs)
File «C:UsersUnstaPycharmProjectsuntitledvenvlibsite-packagesvk_apivk_api.py», line 646, in method
raise error
vk_api.exceptions.ApiError: [15] Access denied: no access to call this method
Process finished with exit code 1
Сам код:
import os, qrcode, requests
import vk_api
from vk_api.longpoll import VkLongPoll, VkEventType
from vk_api.keyboard import VkKeyboard, VkKeyboardColor
from vk_api.utils import get_random_id
from PIL import Image, ImageFilter
from caesar import *
from vigenere import *
vk = vk_api.VkApi(token=’12777***’)
keyboard = VkKeyboard(one_time=False)
keyboard.add_button(‘Шифровка’, color=VkKeyboardColor.POSITIVE)
keyboard.add_button(‘Дешифровка’, color=VkKeyboardColor.NEGATIVE)
keyboard.add_line()
keyboard.add_button(‘Шифр Цезаря’, color=VkKeyboardColor.DEFAULT)
keyboard.add_button(‘Шифр Виженера’, color=VkKeyboardColor.DEFAULT)
keyboard.add_line()
keyboard.add_button(‘Текст’, color=VkKeyboardColor.DEFAULT)
keyboard.add_button(‘Ключ’, color=VkKeyboardColor.DEFAULT)
keyboard.add_line()
keyboard.add_button(‘Результат Шифрования/Дешифрования’, color=VkKeyboardColor.PRIMARY)
keyboard.add_line()
keyboard.add_button(‘Сгенерировать QR-код’, color=VkKeyboardColor.DEFAULT)
keyboard.add_line()
keyboard.add_button(‘Получить размытые фото’, color=VkKeyboardColor.DEFAULT)
longpoll = VkLongPoll(vk)
def send_message(user_id, message):
vk.method(‘messages.send’, {‘user_id’: user_id, ‘message’: message, ‘keyboard’: keyboard.get_keyboard(), ‘random_id’: get_random_id()})
def send_image(user_id, txt_message, photos=[]):
upload = vk_api.VkUpload(vk)
uploaded_photos = upload.photo_messages(photos)
attachments = []
for photo in uploaded_photos:
attachments.append(‘photo{}_{}’.format(photo[‘owner_id’], photo[‘id’]))
vk.method(‘messages.send’, {‘user_id’: user_id, ‘attachment’: ‘,’.join(attachments), ‘message’: txt_message, ‘keyboard’: keyboard.get_keyboard(), ‘random_id’: get_random_id()})
def blur_image(image, counter):
blured_image = Image.open(image).filter(ImageFilter.GaussianBlur(12))
blured_image.save(str(counter) + ‘_blured.jpg’)
def get_image_size(sizes, size_type):
for size in sizes:
if size[‘type’] == size_type:
return size
def download_image(fileLink, counter):
with open(str(counter) + ‘_saved.jpg’, ‘wb’) as handle:
res = requests.get(fileLink, stream = True)
if not res.ok:
print(res)
for block in res.iter_content(1024):
if not block:
break
handle.write(block)
def parse_json_format(attachments):
urls = dict()
for attach in attachments:
photo_id = attach[‘photo’][‘id’]
size = None
for size_type in [‘w’ , ‘y’, ‘z’, ‘x’, ‘m’, ‘s’]:
size = get_image_size(attach[‘photo’][‘sizes’], size_type)
if size is not None:
break
url = size[‘url’]
urls[photo_id] = url
return urls
def main():
mode = ‘Шифровка’
cipher = ‘Шифр Цезаря’
text = ‘python’
key = ‘3’
qr_text = »
photos_id = []
for event in longpoll.listen():
if event.type == VkEventType.MESSAGE_NEW:
if event.to_me:
if event.attachments != {}:
k = list(event.attachments.keys())
counter = 0
for item_type, item_value in event.attachments.items():
if item_value == 'photo':
photos_id.append(event.attachments[k[k.index(item_type) + 1]])
jsonoutput = vk.method('messages.getHistory', {'user_id': event.peer_id, 'count': 1})['items'][0]['attachments']
urls = parse_json_format(jsonoutput)
for photo_id in photos_id:
pid = int(photo_id.split(str(event.user_id) + '_')[1])
if pid in urls:
counter += 1
download_image(urls[pid], counter)
if event.text == 'Получить размытые фото':
counter = 0
for root, dirs, files in os.walk("."):
for filename in files:
if '_saved' in filename:
counter += 1
blur_image(filename, counter)
send_image(event.user_id, 'Размытое фото ' + str(counter) + ':', [filename[0:-9] + 'blured.jpg'])
os.remove(filename)
os.remove(filename[0:-9] + 'blured.jpg')
if 'qr=' in event.text:
qr_text = event.text[3:len(event.text)]
send_message(event.user_id, 'Текст для генерации QR-кода = ' + qr_text)
if 'text=' in event.text:
text = event.text[5:len(event.text)]
send_message(event.user_id, 'Текст = ' + text)
if 'key=' in event.text:
key = event.text[4:len(event.text)]
send_message(event.user_id, 'Ключ = ' + key)
if event.text == 'Сгенерировать QR-код':
if qr_text == '':
send_message(event.user_id, 'Пример ввода текста для генерации QR-кода: qr=word')
else:
qr = qrcode.make(qr_text)
qr.save('qr.jpg')
send_image(event.user_id, 'На основе Вашего текста "' + qr_text + '" был сгенерирован QR-код!', ['qr.jpg'])
os.remove('qr.jpg')
if event.text == 'Шифровка':
mode = 'Шифровка'
send_message(event.user_id, 'Режим работы = Шифрование')
if event.text == 'Дешифровка':
mode = 'Дешифровка'
send_message(event.user_id, 'Режим работы = Дешифрование')
if event.text == 'Текст':
send_message(event.user_id, 'Пример ввода: text=python')
if event.text == 'Ключ':
send_message(event.user_id, 'Пример ввода: key=4')
if event.text == 'Шифр Цезаря':
cipher = 'Шифр Цезаря'
send_message(event.user_id, 'Шифр = метод Цезаря')
if event.text == 'Шифр Виженера':
cipher = 'Шифр Виженера'
send_message(event.user_id, 'Шифр = метод Виженера')
if event.text == 'Результат Шифрования/Дешифрования':
send_message(event.user_id, 'Метод = ' + cipher + 'nРежим работы = ' + mode + 'nТекст = ' + text + 'nКлюч = ' + key)
if cipher == 'Шифр Цезаря':
if mode == 'Шифровка' and key.isdigit():
send_message(event.user_id, 'Результат: ' + encrypt_caesar(text, int(key)))
if mode == 'Дешифровка' and key.isdigit():
send_message(event.user_id, 'Результат: ' + decrypt_caesar(text, int(key)))
if not key.isdigit():
send_message(event.user_id, 'Ключ должен быть числовым!')
if cipher == 'Шифр Виженера':
if mode == 'Шифровка' and not key.isdigit():
if ' ' not in text and ' ' not in key:
send_message(event.user_id, 'Результат: ' + encrypt_vigenere(text, key))
else:
send_message(event.user_id, 'Текст/Ключ содержит пробелы!')
if mode == 'Дешифровка' and not key.isdigit():
if ' ' not in text and ' ' not in key:
send_message(event.user_id, 'Результат: ' + decrypt_vigenere(text, key))
else:
send_message(event.user_id, 'Текст/Ключ содержит пробелы!')
if key.isdigit():
send_message(event.user_id, 'Ключ должен быть буквенным!')
if name == ‘main‘:
main()
zelenin писал(а):а что это? это Implicit flow?
У меня 4 файла — index.php , auth.php, VK.php, config.php и send.php
С нарытого мною материала — ориентируюсь на standalone приложение. Встает вопрос — каким образом авторизировать пользователя, не сбрасывая токен, либо же это остается неизбежным?
index.php:
Код: Выделить всё
<?php require_once 'config.php';?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="style.css" type="text/css">
<title>Тестовый сайт</title>
</head>
<body>
<div id="container">
<h2>Контент сайта</h2>
<p>
<strong><a href="auth.php">Авторизация</a></strong>
</p>
<?php if(isset($_SESSION['user'])):
$user = $_SESSION['user']->response[0];?>
<img src="<? echo $user->photo_medium;?>">
<?php echo $user->first_name;?> <?php echo $user->last_name;?>
<form action="send.php" method="post">
<textarea name = "description"></textarea>
<button>Отправить</button>
</form>
<?php endif;?>
<?php if(isset($_SESSION['access_token'])):
$access_token = $_SESSION['access_token']; ?>
<?php endif;?>
</div>
</body>
</html>
auth.php:
Код: Выделить всё
require_once 'config.php';
$ob = new VK( APP_ID_STAND_ALONE, APP_SECRET_STAND_ALONE );
if(!isset($_GET['code'])) {
$request_params = [
'client_id' => APP_ID_STAND_ALONE,
'scope' => 'offline',
'redirect_uri' => $ob::REDIRECT_URI,
'response+type' => 'code',
];
// printArr($request_params);
$url = $ob::URL_AUTH.'?'. http_build_query($request_params);
$ob->redirect($ob::URL_AUTH.'?'. http_build_query($request_params));
}
if($_GET['code']) {
$ob->setCode($_GET['code']);
$res = $ob->getToken();
if($res){
$ob->getUser();
}
else {
echo '<pre>';
printArr($_SESSION['error']);
echo '</pre>';
exit();
}
}
if(isset($_GET['error'])) {
exit($_GET['error_description']);
}
if($_GET['error']) {
exit($_GET['error']);
}
VK.php
Код: Выделить всё
class VK {
// возвращаемый код
private $code;
// токен
private $access_token;
// id пользователя
private $uid;
private $app_id;
private $secret;
/** константы */
const APP_ID = 5571602;
// секретный id
const APP_SECRET = '*************';
// страница редиректа
const REDIRECT_URI = 'http://qas.loc/auth.php';
// ссылка на получение токена
const URL_ACCESS_TOKEN = 'https://oauth.vk.com/access_token';
// ссылка для авторизации
const URL_AUTH = 'http://oauth.vk.com/authorize';
// запрос на метод
const URL_METHOD = 'https://api.vk.com/method';
const SINGLE_TOKEN = '595fd636419b4bc2f1dc218612756bb47829290e73bc3f72664107207287aa9c09be1048ee064fad20a41';
public function __construct( $app_id, $secret) {
$this->app_id = $app_id;
$this->secret = $secret;
}
public function setToken($access_token) {
$this->access_token = $access_token;
$_SESSION['access_token'] = $access_token;
}
public function setUid($uid) {
$this->uid = $uid;
}
public function setCode($code) {
$this->code = $code;
}
public function redirect($url){
header('HTTP/1.1 301 Moved Permanently');
header('Location:'.$url);
exit();
}
public function getToken(){
if(!$this->code){
die('Неверный код');
}
$curl = curl_init();
$permissions = [
'notify ', 'friends', 'photos', 'audio',
'video', 'docs', 'notes', 'pages',
'status', 'wall', 'groups', 'messages',
'email', 'notifications', 'stats',
'ads', 'market', 'offline'
];
$request_params = [
'client_id' => $this->app_id,
'client_secret' => $this->secret,
'code' => $this->code,
'redirect_uri' => self::REDIRECT_URI,
'scope' => implode(',', $permissions),
'display' => 'page',
// 'response_type' => 'token',
];
$url = self::URL_ACCESS_TOKEN.'?'. http_build_query($request_params);
// exit($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
// exit($result);
curl_close($curl);
$ob = json_decode($result);
if(isset($ob->access_token)) {
$this->setToken($ob->access_token);
$this->setUid($ob->user_id);
return true;
}
elseif($ob->error) {
$_SESSION['error'] = "ERRORRRR";
return false;
}
}
public function getUser(){
if(!$this->access_token) {
exit('Wrong code');
}
if(!$this->uid) {
exit('Wrong code');
}
$fields = [
'first_name','last_name','nickname','screen_name','sex','bdate','city','country','timezone',
'photo','photo_medium','photo_big','has_mobile','rate','contact','education', 'online', 'counters'
];
$request_params = [
'uids' => $this->uid,
'fields' => implode(',', $fields),
'access_token' => $this->access_token,
];
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, self::URL_METHOD."/users.get?". http_build_query($request_params));
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER,TRUE);
$result = curl_exec($curl);
curl_close($curl);
$_SESSION['user'] = json_decode($result);
$this->wallPost();
$this->redirect('http://qas.loc');
}
public function wallPost($description = false){
$access_token = $this->access_token;
$message = 'HELLO';
// $access_token = $_SESSION['access_token'];
$request_params = [
'owner_id' => 126135230,
'random_id' => mt_rand( 20, 99999999 ), // 22557780 362586227
'message' => $message,
'v' => '5.52',
'access_token' => $access_token,
];
$url = self::URL_METHOD.'/message.send?'. http_build_query($request_params);
$this->redirect('http://qas.loc');
}
public function sendMessage($description = false){
$access_token = $this->access_token;
$description = 'HELLO';
// $access_token = $_SESSION['access_token'];
$request_params = [
'user_id' => 22557780,
'random_id' => mt_rand( 20, 99999999 ), // 22557780 362586227
'peer_id' => 22557780,
'domain' => 'mozart',
'chat_id' => 36,
'message' => $description,
'v' => '5.52',
'access_token' => $access_token
];
$url = 'https://api.vk.com/method/messages.send?'. http_build_query($request_params);
printArr(json_decode(file_get_contents($url)));
die();
$this->redirect('http://qas.loc');
}
send.php
Код: Выделить всё
require_once 'config.php';
if(isset($_POST)){
$description = $_POST['description'];
$ob = new VK(APP_ID_STAND_ALONE, APP_SECRET_STAND_ALONE);
// $ob->sendMessage($description);
$ob->wallPost($description);
}
Вы писали про Implicit Flow для получения ключа доступа пользователя:
Это реализовано в файле: auth.php
Не понимаю различия — токен приложениия stand-alone и токен, который получает прользователь при авторизации.
В моем случае ни сообщения , ни записи на стену не отправляются. Что я делаю не так?
Код:
import vk_api
from vk_api.bot_longpoll import VkBotLongPoll, VkBotEventType
from config import tok
vk_session = vk_api.VkApi(token = tok)
longpoll = VkBotLongPoll(vk_session, 207817235)
def sender(id, text):
vk_session.method(‘messages.get’, {‘chat_id’ : id, ‘message’ : text, ‘random_id’ : 0})
for event in longpoll.listen():
if event.type == VkBotEventType.MESSAGE_NEW:
if event.from_chat:
id = event.chat_id
msg = event.object.message.lower()
if msg == ‘Привет’:
sender(id, ‘Приветсвую!’)
пишу его на Sublime Text
вот полная ошибка при билде
Traceback (most recent call last):
File “D:MyBot VKmain.py”, line 6, in <module>
longpoll = VkBotLongPoll(vk_session, 207817235)
File “C:UsersWWWAppDataLocalProgramsPythonPython310libsite-packagesvk_apibot_longpoll.py”, line 219, in __init__
self.update_longpoll_server()
File “C:UsersWWWAppDataLocalProgramsPythonPython310libsite-packagesvk_apibot_longpoll.py”, line 232, in update_longpoll_server
response = self.vk.method(‘groups.getLongPollServer’, values)
File “C:UsersWWWAppDataLocalProgramsPythonPython310libsite-packagesvk_apivk_api.py”, line 668, in method
raise error
vk_api.exceptions.ApiError: Access denied: no access to call this method
ЧТО ДЕЛАТЬ?)