Bridge library for VK Mini Apps to communicate with VK clients across iOS, Android, and Web platforms
—
Advertising integration including native ads, banner ads, conversion tracking, and monetization features for VK Mini Apps.
Display and manage banner advertisements within the Mini App interface.
/**
* Show banner advertisement
* @param props - Banner ad configuration
*/
function send(method: 'VKWebAppShowBannerAd', props: ShowBannerAdRequest): Promise<VKWebAppShowBannerAdResponse>;
/**
* Check banner ad availability
*/
function send(method: 'VKWebAppCheckBannerAd'): Promise<VKWebAppCheckBannerAdResponse>;
/**
* Hide currently displayed banner ad
*/
function send(method: 'VKWebAppHideBannerAd'): Promise<VKWebAppHideBannerAdResponse>;
interface ShowBannerAdRequest {
/** Banner placement location */
banner_location: BannerAdLocation;
}
enum BannerAdLocation {
TOP = 'top',
BOTTOM = 'bottom'
}
interface VKWebAppShowBannerAdResponse {
result: boolean;
}
interface VKWebAppCheckBannerAdResponse {
result: boolean;
}
interface VKWebAppHideBannerAdResponse {
result: boolean;
}Display native ads that blend with app content for better user experience.
/**
* Show native advertisements
* @param props.ad_format - Type of native ad format
* @param props.use_waterfall - Use waterfall ad loading (optional)
*/
function send(method: 'VKWebAppShowNativeAds', props: {
ad_format: EAdsFormats;
use_waterfall?: boolean;
}): Promise<{ result: true }>;
/**
* Check native ad availability
* @param props.ad_format - Type of native ad format to check
* @param props.use_waterfall - Use waterfall ad loading (optional)
*/
function send(method: 'VKWebAppCheckNativeAds', props: {
ad_format: EAdsFormats;
use_waterfall?: boolean;
}): Promise<{ result: boolean }>;
enum EAdsFormats {
REWARD = 'reward',
INTERSTITIAL = 'interstitial'
}Track user interactions and conversions for advertising optimization.
/**
* Fire retargeting pixel for user tracking
* @param props - Retargeting pixel configuration
*/
function send(method: 'VKWebAppRetargetingPixel', props: RetargetingPixelOptions): Promise<{
result: true;
}>;
/**
* Track conversion events
* @param props.pixel_code - Pixel tracking code
* @param props.conversion_event - Event identifier
* @param props.conversion_value - Event value
*/
function send(method: 'VKWebAppConversionHit', props: {
pixel_code: string;
conversion_event: string;
conversion_value: number;
}): Promise<{ result: true }>;
interface RetargetingPixelOptions {
/** Pixel tracking code */
pixel_code: string;
/** Custom parameters */
custom_params?: Record<string, string | number>;
}Usage Examples:
// Check and show banner ads
const bannerAvailable = await bridge.send('VKWebAppCheckBannerAd');
if (bannerAvailable.result) {
const bannerResult = await bridge.send('VKWebAppShowBannerAd', {
banner_location: BannerAdLocation.BOTTOM
});
console.log('Banner ad shown:', bannerResult.result);
} else {
console.log('Banner ads not available');
}
// Show rewarded video ads
const rewardedAdsAvailable = await bridge.send('VKWebAppCheckNativeAds', {
ad_format: EAdsFormats.REWARD
});
if (rewardedAdsAvailable.result) {
await bridge.send('VKWebAppShowNativeAds', {
ad_format: EAdsFormats.REWARD,
use_waterfall: true
});
// Listen for ad completion event
bridge.subscribe((event) => {
if (event.detail.type === 'VKWebAppShowNativeAdsResult') {
console.log('Rewarded ad completed - give user reward');
giveUserReward();
}
});
}
// Track conversion events
await bridge.send('VKWebAppConversionHit', {
pixel_code: 'your-pixel-code',
conversion_event: 'purchase',
conversion_value: 100
});
// Track retargeting pixel
await bridge.send('VKWebAppRetargetingPixel', {
pixel_code: 'your-retargeting-pixel',
custom_params: {
user_id: '12345',
category: 'gaming',
value: 50
}
});class AdManager {
private adShownCount = 0;
private rewardedAdCooldown = 0;
async showInterstitialAd(): Promise<boolean> {
const available = await bridge.send('VKWebAppCheckNativeAds', {
ad_format: EAdsFormats.INTERSTITIAL
});
if (available.result) {
await bridge.send('VKWebAppShowNativeAds', {
ad_format: EAdsFormats.INTERSTITIAL
});
this.adShownCount++;
return true;
}
return false;
}
async showRewardedAd(): Promise<boolean> {
if (Date.now() < this.rewardedAdCooldown) {
console.log('Rewarded ad on cooldown');
return false;
}
const available = await bridge.send('VKWebAppCheckNativeAds', {
ad_format: EAdsFormats.REWARD
});
if (available.result) {
await bridge.send('VKWebAppShowNativeAds', {
ad_format: EAdsFormats.REWARD
});
// Set cooldown (e.g., 5 minutes)
this.rewardedAdCooldown = Date.now() + 5 * 60 * 1000;
return true;
}
return false;
}
async manageBannerAds(): Promise<void> {
const available = await bridge.send('VKWebAppCheckBannerAd');
if (available.result) {
// Show banner at bottom
await bridge.send('VKWebAppShowBannerAd', {
banner_location: BannerAdLocation.BOTTOM
});
// Hide after certain actions
setTimeout(async () => {
await bridge.send('VKWebAppHideBannerAd');
}, 30000); // Hide after 30 seconds
}
}
}
const adManager = new AdManager();
// Show ads at appropriate moments
document.getElementById('show-interstitial')?.addEventListener('click', async () => {
await adManager.showInterstitialAd();
});
document.getElementById('get-reward')?.addEventListener('click', async () => {
const success = await adManager.showRewardedAd();
if (success) {
console.log('User will receive reward after ad completion');
}
});class ConversionTracker {
private pixelCode: string;
constructor(pixelCode: string) {
this.pixelCode = pixelCode;
}
async trackEvent(event: string, value: number = 0, customParams?: Record<string, any>): Promise<void> {
try {
// Track conversion
await bridge.send('VKWebAppConversionHit', {
pixel_code: this.pixelCode,
conversion_event: event,
conversion_value: value
});
// Track retargeting with custom parameters
if (customParams) {
await bridge.send('VKWebAppRetargetingPixel', {
pixel_code: this.pixelCode,
custom_params: customParams
});
}
console.log(`Tracked ${event} with value ${value}`);
} catch (error) {
console.error('Failed to track conversion:', error);
}
}
async trackPurchase(amount: number, productId: string): Promise<void> {
await this.trackEvent('purchase', amount, {
product_id: productId,
timestamp: Date.now()
});
}
async trackRegistration(userId: string): Promise<void> {
await this.trackEvent('registration', 0, {
user_id: userId,
timestamp: Date.now()
});
}
async trackLevelComplete(level: number): Promise<void> {
await this.trackEvent('level_complete', level, {
level: level,
timestamp: Date.now()
});
}
}
// Usage
const tracker = new ConversionTracker('your-pixel-code');
// Track different events
await tracker.trackPurchase(100, 'premium_month');
await tracker.trackRegistration('user123');
await tracker.trackLevelComplete(5);// Combine ads and payments for optimal revenue
class MonetizationManager {
private paymentManager: PaymentManager;
private adManager: AdManager;
private tracker: ConversionTracker;
constructor() {
this.paymentManager = new PaymentManager(51665960, 12345);
this.adManager = new AdManager();
this.tracker = new ConversionTracker('pixel-code');
}
async unlockPremiumContent(contentId: string): Promise<boolean> {
// Offer choice: pay or watch ads
const choice = await this.showMonetizationChoice();
if (choice === 'payment') {
const success = await this.paymentManager.purchaseProduct({
id: contentId,
name: 'Premium Content',
description: 'Unlock premium content',
price: 5000, // 50 rubles
category: 'consumable'
}, getCurrentUserId());
if (success) {
await this.tracker.trackPurchase(5000, contentId);
return true;
}
} else if (choice === 'ads') {
const adSuccess = await this.adManager.showRewardedAd();
if (adSuccess) {
// Wait for ad completion
return new Promise((resolve) => {
bridge.subscribe((event) => {
if (event.detail.type === 'VKWebAppShowNativeAdsResult') {
this.tracker.trackEvent('ad_reward', 0, { content_id: contentId });
resolve(true);
}
});
});
}
}
return false;
}
private async showMonetizationChoice(): Promise<'payment' | 'ads' | 'cancel'> {
// Show UI choice to user
return new Promise((resolve) => {
const modal = document.createElement('div');
modal.innerHTML = `
<div class="monetization-modal">
<h3>Unlock Premium Content</h3>
<button id="pay-button">Pay 50₽</button>
<button id="ads-button">Watch Ad</button>
<button id="cancel-button">Cancel</button>
</div>
`;
document.body.appendChild(modal);
modal.querySelector('#pay-button')?.addEventListener('click', () => {
document.body.removeChild(modal);
resolve('payment');
});
modal.querySelector('#ads-button')?.addEventListener('click', () => {
document.body.removeChild(modal);
resolve('ads');
});
modal.querySelector('#cancel-button')?.addEventListener('click', () => {
document.body.removeChild(modal);
resolve('cancel');
});
});
}
}Install with Tessl CLI
npx tessl i tessl/npm-vkontakte--vk-bridge