@textback/notification-widget
Version:
TODO: Give a short introduction of your project. Let this section explain the objectives or the motivation behind this project.
196 lines (169 loc) • 5.56 kB
JavaScript
import UUID from 'uuid-js';
import loadScript from '../utils/loadScript.js';
import apiErrorHandler from '../utils/apiErrorHandler.js';
import Channel from './channel.js';
import VKModal from './vk-modal/vk-modal.js';
import constants from "../utils/constants";
const VK_API_VERSION = '5.131';
const LOGIN_TIMEOUT = 4096;
function loadVkLib(){
return new Promise((resolve, reject) => {
if (window.VK && window.VK.Auth) {
resolve('vk cache');
}
else {
loadScript('//vk.com/js/api/openapi.js')
.then(function () {
resolve('vk load');
}, function (err) {
reject(err);
});
}
});
}
function initVK(apiId) {
return new Promise((resolve, reject) => {
if (apiId) {
if (!window.VK._apiId) {
window.VK.init({apiId});
}
window.VK.Auth.getLoginStatus(resolve);
} else {
reject('noVKApiId');
}
});
}
function handleVKLoadingError(error) {
console.error('Failed to load VK openapi.js. VK channel will be unavailable');
return null;
}
// isVkAppUsed :: Object -> Boolean
const isVkAppUsed = config => {
return config.useVkApp
? config.useVkApp
: false;
};
export default class VKChannel extends Channel {
constructor(channelData = {}, deeplink, widget) {
super(channelData, deeplink, widget);
this.isDoubleCheck = widget.config.isDoubleCheck;
this.vkApiId = this.widget.config.vkApiId;
this.initPromise = null;
this.vkPluginContainerId = null;
this.authorized = false;
this.landingUrl = this.config.additionalProperties ? this.config.additionalProperties.landingUrl : undefined;
if (this.enabled) {
this.vkPluginContainerId = UUID.create(4).hex;
if (!this.widget.useVKApi) {
this.initPromise = loadVkLib()
.catch(err => this.__handleVKLoadingError(err));
} else {
this.initPromise = loadVkLib()
.then(() => initVK(this.vkApiId))
.then(() => {
this.authorized = !!(window.VK.Auth.getSession());
})
.catch(err => this.__handleVKLoadingError(err));
}
}
}
subscribe() {
super.subscribe();
return this.landingUrl ?
window.open(this.landingUrl, '_blank')
:
(isVkAppUsed(this.widget.config)
? window.open(`https://vk.com/app${this.widget.config.vkApiId}_-${this.config.id}#r=subscribe_${this.deeplink}&accountId=${this.widget.config.accountId}&channelId=${this.channelId}`, 'vk')
: this.subscribeViaPlugin());
}
subscribeViaApi() {
let promise = null;
if (!this.authorized) {
promise = this.__login().then( res => this.__allowMessagesFromGroup() );
} else {
promise = this.__allowMessagesFromGroup();
}
return promise;
}
__allowMessagesFromGroup () {
window.VK.Api.call(
'messages.allowMessagesFromGroup',
{
group_id: this.id,
v: VK_API_VERSION,
},
res => {
const vkSession = window.VK.Auth.getSession();
const vkUserId = vkSession.mid;
if (res.response === 1) {
this.__textbackSubscribe(vkUserId);
} else {
console.log('VK res error:', res);
}
}
);
}
__login () {
return new Promise(resolve => {
window.VK.Auth.login(res => {
resolve(res);
}, LOGIN_TIMEOUT);
});
}
__textbackSubscribe (vkUserId, channelWidgetIdx) {
//we shall parse deeplink from server webhook. This method looks like artifact from age without webhhoks.
if(!this.isDoubleCheck) return null;
return fetch(`${this.widget.initialConfig.apiPath}/endUserNotifications/subscriptions`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
'accountId': this.widget.config.accountId,
'insecureContext': this.widget.insecureContext,
'secureContextToken': this.widget.secureContextToken,
'address': {
'channel': 'vk',
'channelId': this.config.channelId,
'accountId': this.widget.config.accountId,
'remoteAddress': vkUserId,
'chatId': vkUserId
},
deepLinkId: this.deeplink.replace('subscribe_',''),
widgetId: this.widget.id,
'user': {
'id': this.widget.widgetUserId
}
})
}).then(apiErrorHandler);
}
__handleVKLoadingError(err) {
super.reportError('Failed to load VK openapi.js. VK channel will be unavailable.', err);
return null;
}
subscribeViaPlugin() {
const modal = new VKModal(this.vkPluginContainerId);
this.renderVKSubscriptionButton();
modal.onClose = () => {
if (this.vkSubscribeHandler) {
window.VK.Observer.unsubscribe('widgets.allowMessagesFromCommunity.allowed', this.vkSubscribeHandler);
this.vkSubscribeHandler = null;
}
};
}
renderVKSubscriptionButton(height = 30, containerId = this.vkPluginContainerId) {
if (this.vkSubscribeHandler) {
window.VK.Observer.unsubscribe('widgets.allowMessagesFromCommunity.allowed', this.vkSubscribeHandler);
this.vkSubscribeHandler = null;
}
const options = {
height,
key: this.deeplink
};
window.VK.Widgets.AllowMessagesFromCommunity(containerId, options, this.id);
if (!this.config.disableAllowMessageEvents) {
this.vkSubscribeHandler = this.__textbackSubscribe.bind(this);
window.VK.Observer.subscribe('widgets.allowMessagesFromCommunity.allowed', this.vkSubscribeHandler);
}
}
}