vkui-connect-helper
Описание
Библиотека-обёртка вокруг vk-bridge, которая при недоступности модуля VK Bridge будет выполнять все те же самые вызовы иными способами.
Таким образом, разработчик практически на живых данных без необходимости создавать объекты-пустышки получает возможность отладки прямо в окне браузера за пределами сайта VK.
- Не отвлекают уведомления и интерфейс сайта
- Возможность использовать hot reload
- Возможность использовать имитацию мобильного интерфейса в Chrome DevTools
- Нет лишних вызовов в Network, относящихся к ВКонтакте, а не к вашему приложению
- Возможность использовать расширения для разработки, такие как Vue DevTools и React DevTools
Установка и подключение
npm install --save @denisnp/vkui-connect-helper
import VKC from '@denisnp/vkui-connect-helper';
Инициализация
VKC.init(options); // эта функция автоматически вызывает VKWebAppInit
options
Поле | Тип | Описание | Обязательное ли | По-умолачнию |
---|---|---|---|---|
appId |
string или int | Идентификатор приложения VK Apps. Сюда не нужно вводить id Standalone-приложения, в котором вы получили токен. | да | 0 |
accessToken |
string | Токен разработчика для вызова методов, полученный с помощью Standalone API, см. ниже подробнее. |
да для работы в браузере с GetUserInfo и CallAPIMethod
|
empty string |
communityToken |
string | Токен сообщества для работы соответствующих событий | нет | empty string |
mode |
MODE_PROD, MODE_AUTO, MODE_DEV | Режим работы библиотеки, смотрите ниже в примере инициализации. | нет | MODE_AUTO |
apiVersion |
string | Версия API ВКонтакте для передачи в вызовы методов. | нет | 5.120 |
enableLog |
boolean | Вести ли лог вызовов к VKConnect в консоли. | нет | true |
corsAddress |
string | Адрес сервера для обхода CORS к api.vk.com, см. ниже подробнее. |
нет | https://cors-anywhere.herokuapp.com/ |
asyncStyle |
boolean | Использовать ли специальный синтаксис для получения ошибок в режиме async/await , см. подробнее ниже. |
нет | false |
defaultScope |
string |
scope который будет передаваться в VK API для автоматический авторизации, если вы хотите сразу вызывать методы API без предварительной отправки события VKWebAppGetAuthToken
|
empty string |
|
disableAutoTheme |
boolean | Если true , то будет выключен автоматический перехват события VKWebAppUpdateConfig для установки альтернативной темы (при использовании VKUI ) |
нет | true |
Пример инициализации
Режим | Описание |
---|---|
MODE_DEV |
Режим, в котором библиотека будет считать, что модуля VKUIConnect нет, все запросы пойдут напрямую через API, а неподдерживаемые события не будут работать. Для реализации каких-то событий кроме списка поддерживаемых вы можете использовать фунцию VKC.define , см ниже подробнее. |
MODE_PROD |
Режим, в котором библиотека будет все события пытаться отправлять через VKUIConnect. Если он не подключен, программа перестанет выполняться в этом месте (промис от VKUIConnect не вызовет ни успех, ни ошибку). Собственно, это поведение и вдохновило меня на написание vkui-connect-helper. |
MODE_AUTO |
Настройка по-умолчанию, программа сама определит, в каком режиме работать по наличию переданного accessToken , поэтому важно передавать его только из переменных окружения на комьпютере разработчика и не держать в коде клиента. |
import VKC, { MODE_PROD, MODE_AUTO } from '@denisnp/vkui-connect-helper';
VKC.init({
appId: 123456,
accessToken: process.env.REACT_APP_VK_TOKEN, // инструкция по получению такого ключа ниже
corsAddress: 'https://my-own-server.ru/cors/', // https://github.com/marcus2vinicius/cors-anywhere
asyncStyle: true, // см ниже
});
Работа с библиотекой
Promise-режим
Библиотека почти повторяет интерфейс vkui-connect. То есть в обычном режиме можно вызвать в любом месте функцию VKC.send(event, params)
или VKC.sendPromise(event, params)
(в библиотеке эти функции эквивалентны) и получить в ответ Promise
. Например:
VKC.send('VKWebAppGetUserInfo', {})
.then((userData) => {
// делаем что нужно с данными пользователя
// userData = { first_name: ..., last_name: ..., ... }
})
.catch((error) => {
// произошла ошибка при вызове события
// error = { ...some error data... }
});
Async-режим
Мы всегда можем использовать синтаксис async/await
для получения результата, но в такой ситуации для поимки ошибки нам придётся оборачивать код в try/catch
. Чтобы избежать этого, в функцию VKC.init()
можно передать параметр asyncMode: true
. Тогда результат работы методов будет такой:
VKC.init({
...
asyncStyle: true,
});
// some async block
const [data, error] = await VKC.send('VKWebAppCallAPIMethod', { method: 'friends.get' });
if (data) {
// в объекте data всегда успешный ответ от метода
// при этом error = null
} else {
// если data = null, значит произошла ошибка, можно её вывести
console.log(error);
}
Вызов методов API
События VKWebAppGetUserInfo
и VKWebAppCallAPIMethod
в отсутствии VKUIConnect производят запрос к https://api.vk.com
. Для правильности работы этих методов нужно передать в options
параметр accessToken
, который в целях разработки можно получить, создав Standalone-приложение.
После создания Standaone-приложения вызовите в браузере следующую ссылку:
https://oauth.vk.com/authorize?client_id=CLIENT_ID&display=page&redirect_uri=&scope=SCOPE&response_type=token&v=5.92&state=123456
Где
-
CLIENT_ID
— это app_id только что созданного приложения -
SCOPE
— желаемые уровни доступа для разработки, напримерfriends,offline,wall
ВНИМАНИЕ! Никому не давайте этот токен. Не допускайте, чтобы токен попал в production-сборку приложения или в публичный репозиторий. Лучше всего настроить webpack использовать переменные окружения соответствующим образом.
CORS
На сайте api.vk.com
не прописаны нужные заголовки, поэтому вызывать методы из браузера вне ВК придётся с помощью CORS-прокси. Быстрый и удобный прокси с открытым исходным кодом есть вот тут: https://github.com/marcus2vinicius/cors-anywhere, а его демонстрационная версия доступна по адресу https://cors-anywhere.herokuapp.com/. Настоятельно рекомендую вам поднять копию у себя, потому что при частых запросах демо-прокси будет вас отключать.
В параметр corsAddress
передаётся строка, которая будет подставлена перед полным адресом вызова. Например:
https://api.vk.com/method/users.get?user_ids=1
Будет заменено на:
https://cors-anywhere.herokuapp.com/https://api.vk.com/method/users.get?user_ids=1
Не забывайте про /
в конце corsAddress
.
Поддерживаемые события
Идеология этой библиотеки в том, чтобы создать ситуацию, максимально близкую к живым данным. На текущий момент реализована поддержка следующих событий:
-
VKWebAppInit
— отправляется автоматически при инициализации библиотеки -
VKWebAppGetUserInfo
— получает данные владельца токена с помощью API -
VKWebAppGetAuthToken
— в DEV-режиме это событие ничего не делает, но вызов его обязателен, о чём библиотека предупреждает, чтобы не забыть вызвать его в основном режиме. Обратите внимание,scope
, который передан сюда, будет актуален только в PROD-режиме. В DEV-режиме будет использоватьсяscope
, полученный при создании токена -
VKWebAppCallAPIMethod
— вызывает настоящий метод API ВК, возвращает результат или ошибку -
VKWebAppGetGeodata
— вызывает функцию браузера о получении координат, после ответа пользователя возвращает результат или ошибку -
VKWebAppCopyText
— текст копируется в буфер обмена браузерным методом -
VKWebAppGetCommunityAuthToken
— возвращается токен, переданный вoptions.communityToken
-
VKWebAppShare
— открывается переданная ссылка в новом окне -
VKWebAppShowCommunityWidgetPreviewBox
— код виджета проверяется на валидность и выводится в консоль -
VKWebAppShowWallPostBox
— вызывается метод APIwall.post
с вашимoptions.accessToken
-
VKWebAppAllowNotifications
— вызывается браузерный метод запроса уведомлений, результат всегдаtrue
-
VKWebAppStorageGetKeys
— весь блок Storage работает сlocalStorage
-
VKWebAppStorageGet
— весь блок Storage работает сlocalStorage
-
VKWebAppStorageSet
— весь блок Storage работает сlocalStorage
-
VKWebAppShowStoryBox
— выдаёт данные Истории в консоль
Проверить наличие поддержки нужного события можно с помощью
VKC.supports('VKWebAppGetUserInfo'); // возвращает true
Собственные функции для реакции на события
Можно задать собственную функцию для ответа на событие, если встроенная вас не устраивает, или если событие ещё не поддерживается библиотекой. Функция должна возвращать Promise. На вход она принимает:
-
params
— объект который будет потом передан в событие -
options
— текущие опции библиотеки Обратите внимание, после загрузки библиотеки переданный в инициализацию параметрMODE_AUTO
меняется либо наMODE_DEV
, либо наMODE_PROD
.
import { MODE_DEV } from '@denisnp/vkui-connect-helper';
VKC.define('VKWebAppGetEmail', (params, options) => {
// в options.mode хранится текущий режим MODE_DEV или MODE_PROD
return new Promise((resolve, reject) => {
if (options.mode === MODE_DEV) {
resolve({
type: 'VKWebAppGetEmailResult',
data: {
email: 'blahblah@mail.com',
sign: ''
},
});
}
});
});
Шорткаты
Для некоторых распространённых событий есть шорткаты
Авторизация
Библиотека сама примет и сохранит access_token
, полученный при авторизации. В дальнейшем вы сможете вызывать методы API без передачи в параметры access_token
.
VKC.auth(scope); // аналог VKC.send('VKWebAppGetAuthToken', { scope: ... } );
// Не забываем, что это промис, и нужно обработать ответ:
VKC.auth('friends,photos').then((authData) => {
if (authData.data.scope.indexOf('friends') >= 0) {
// пользователь дал нам друзей
}
});
Есть специальная константа SCOPE_EMPTY
, которая показывает скоуп "Общая информация".
import { SCOPE_EMPTY } from '@denisnp/vkui-connect-helper';
Вызов API
Если была вызвана авторизация, то становится доступна отправка события VKWebAppCallAPIMethod
. Можно не передавать в параметры поля v
и access_token
, библиотека сделает это за вас.
// в async-режиме
const [result, fail] = await VKC.api('friends.get', { fields: 'sex' }); // это аналог вызова VKC.send('VKWebAppCallAPIMethod'...)
if (result) {
const firstFriendSex = result.data.items[0].sex;
}
Вызов с автоматической авторизацией
Если была передана options.defaultScope
то перед вызовом API библиотека пытается авторизоваться автоматически с этим scope
. Если нужно авторизовывать пользователя по частям, то можно добавить нужный scope
третьим параметром в VKC.api()
:
// VKC.api(method, params, scope);
const [result, fail] = await VKC.api('photos.get', { album_id: 'wall' }, 'photos');
Загрузка фото на стену
const [result, fail] = await VKC.uploadWallPhoto(file, groupId, caption, scope);
В поле file
нужно передавать результат работы <input type="file"/>
. В result
приходит ответ от метода photos.saveWallPhoto
, если всё прошло хорошо. Поле scope
нужно для того, чтобы использовать автоматическую авторизацию, если это требуется.
Подписка на события
Функция полностью аналогична такой функции в VKBridge
VKC.subscribe((e) => {
const { type, data } = e.detail;
if (type === 'VKWebAppOpenCodeReaderResult') {
// Reading result of the Code Reader
console.log(data.code_data);
}
});
Прочие вызовы
В целом экземпляр VKBridge можно вызвать с помощью
const bridge = VKC.bridge();
bridge.send(...);
Поддержка остальных событий и участие в разработке
Если кто-то возьмётся за реализацию ещё каких-то событий, присылайте пулл-реквесты. Не забывайте проверить свой код на соответствие правилам, в этом проекте я использую code-style от Airbnb с отступом 4 пробела.
npm run lint
Напоминаю, что идея библиотеки в приближённости к настоящим данным. И, если некоторые значения получить из ВК в принципе невозможно (например, email пользователя), то вместо других можно написать работоспособную замену.