or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advertising-monetization.mdapplication-lifecycle.mdauthentication.mdcore-bridge.mddevice-features.mdgeolocation.mdindex.mdlaunch-parameters.mdmiddleware.mdpayments-commerce.mdqr-barcode-scanning.mdsocial-features.mdstorage-data.mdui-display.mduser-data.md

advertising-monetization.mddocs/

0

# Advertising & Monetization

1

2

Advertising integration including native ads, banner ads, conversion tracking, and monetization features for VK Mini Apps.

3

4

## Capabilities

5

6

### Banner Advertising

7

8

Display and manage banner advertisements within the Mini App interface.

9

10

```typescript { .api }

11

/**

12

* Show banner advertisement

13

* @param props - Banner ad configuration

14

*/

15

function send(method: 'VKWebAppShowBannerAd', props: ShowBannerAdRequest): Promise<VKWebAppShowBannerAdResponse>;

16

17

/**

18

* Check banner ad availability

19

*/

20

function send(method: 'VKWebAppCheckBannerAd'): Promise<VKWebAppCheckBannerAdResponse>;

21

22

/**

23

* Hide currently displayed banner ad

24

*/

25

function send(method: 'VKWebAppHideBannerAd'): Promise<VKWebAppHideBannerAdResponse>;

26

27

interface ShowBannerAdRequest {

28

/** Banner placement location */

29

banner_location: BannerAdLocation;

30

}

31

32

enum BannerAdLocation {

33

TOP = 'top',

34

BOTTOM = 'bottom'

35

}

36

37

interface VKWebAppShowBannerAdResponse {

38

result: boolean;

39

}

40

41

interface VKWebAppCheckBannerAdResponse {

42

result: boolean;

43

}

44

45

interface VKWebAppHideBannerAdResponse {

46

result: boolean;

47

}

48

```

49

50

### Native Advertising

51

52

Display native ads that blend with app content for better user experience.

53

54

```typescript { .api }

55

/**

56

* Show native advertisements

57

* @param props.ad_format - Type of native ad format

58

* @param props.use_waterfall - Use waterfall ad loading (optional)

59

*/

60

function send(method: 'VKWebAppShowNativeAds', props: {

61

ad_format: EAdsFormats;

62

use_waterfall?: boolean;

63

}): Promise<{ result: true }>;

64

65

/**

66

* Check native ad availability

67

* @param props.ad_format - Type of native ad format to check

68

* @param props.use_waterfall - Use waterfall ad loading (optional)

69

*/

70

function send(method: 'VKWebAppCheckNativeAds', props: {

71

ad_format: EAdsFormats;

72

use_waterfall?: boolean;

73

}): Promise<{ result: boolean }>;

74

75

enum EAdsFormats {

76

REWARD = 'reward',

77

INTERSTITIAL = 'interstitial'

78

}

79

```

80

81

### Analytics & Tracking

82

83

Track user interactions and conversions for advertising optimization.

84

85

```typescript { .api }

86

/**

87

* Fire retargeting pixel for user tracking

88

* @param props - Retargeting pixel configuration

89

*/

90

function send(method: 'VKWebAppRetargetingPixel', props: RetargetingPixelOptions): Promise<{

91

result: true;

92

}>;

93

94

/**

95

* Track conversion events

96

* @param props.pixel_code - Pixel tracking code

97

* @param props.conversion_event - Event identifier

98

* @param props.conversion_value - Event value

99

*/

100

function send(method: 'VKWebAppConversionHit', props: {

101

pixel_code: string;

102

conversion_event: string;

103

conversion_value: number;

104

}): Promise<{ result: true }>;

105

106

interface RetargetingPixelOptions {

107

/** Pixel tracking code */

108

pixel_code: string;

109

/** Custom parameters */

110

custom_params?: Record<string, string | number>;

111

}

112

```

113

114

**Usage Examples:**

115

116

```typescript

117

// Check and show banner ads

118

const bannerAvailable = await bridge.send('VKWebAppCheckBannerAd');

119

120

if (bannerAvailable.result) {

121

const bannerResult = await bridge.send('VKWebAppShowBannerAd', {

122

banner_location: BannerAdLocation.BOTTOM

123

});

124

125

console.log('Banner ad shown:', bannerResult.result);

126

} else {

127

console.log('Banner ads not available');

128

}

129

130

// Show rewarded video ads

131

const rewardedAdsAvailable = await bridge.send('VKWebAppCheckNativeAds', {

132

ad_format: EAdsFormats.REWARD

133

});

134

135

if (rewardedAdsAvailable.result) {

136

await bridge.send('VKWebAppShowNativeAds', {

137

ad_format: EAdsFormats.REWARD,

138

use_waterfall: true

139

});

140

141

// Listen for ad completion event

142

bridge.subscribe((event) => {

143

if (event.detail.type === 'VKWebAppShowNativeAdsResult') {

144

console.log('Rewarded ad completed - give user reward');

145

giveUserReward();

146

}

147

});

148

}

149

150

// Track conversion events

151

await bridge.send('VKWebAppConversionHit', {

152

pixel_code: 'your-pixel-code',

153

conversion_event: 'purchase',

154

conversion_value: 100

155

});

156

157

// Track retargeting pixel

158

await bridge.send('VKWebAppRetargetingPixel', {

159

pixel_code: 'your-retargeting-pixel',

160

custom_params: {

161

user_id: '12345',

162

category: 'gaming',

163

value: 50

164

}

165

});

166

```

167

168

## Monetization Strategies

169

170

### Ad-Based Revenue

171

172

```typescript

173

class AdManager {

174

private adShownCount = 0;

175

private rewardedAdCooldown = 0;

176

177

async showInterstitialAd(): Promise<boolean> {

178

const available = await bridge.send('VKWebAppCheckNativeAds', {

179

ad_format: EAdsFormats.INTERSTITIAL

180

});

181

182

if (available.result) {

183

await bridge.send('VKWebAppShowNativeAds', {

184

ad_format: EAdsFormats.INTERSTITIAL

185

});

186

this.adShownCount++;

187

return true;

188

}

189

190

return false;

191

}

192

193

async showRewardedAd(): Promise<boolean> {

194

if (Date.now() < this.rewardedAdCooldown) {

195

console.log('Rewarded ad on cooldown');

196

return false;

197

}

198

199

const available = await bridge.send('VKWebAppCheckNativeAds', {

200

ad_format: EAdsFormats.REWARD

201

});

202

203

if (available.result) {

204

await bridge.send('VKWebAppShowNativeAds', {

205

ad_format: EAdsFormats.REWARD

206

});

207

208

// Set cooldown (e.g., 5 minutes)

209

this.rewardedAdCooldown = Date.now() + 5 * 60 * 1000;

210

return true;

211

}

212

213

return false;

214

}

215

216

async manageBannerAds(): Promise<void> {

217

const available = await bridge.send('VKWebAppCheckBannerAd');

218

219

if (available.result) {

220

// Show banner at bottom

221

await bridge.send('VKWebAppShowBannerAd', {

222

banner_location: BannerAdLocation.BOTTOM

223

});

224

225

// Hide after certain actions

226

setTimeout(async () => {

227

await bridge.send('VKWebAppHideBannerAd');

228

}, 30000); // Hide after 30 seconds

229

}

230

}

231

}

232

233

const adManager = new AdManager();

234

235

// Show ads at appropriate moments

236

document.getElementById('show-interstitial')?.addEventListener('click', async () => {

237

await adManager.showInterstitialAd();

238

});

239

240

document.getElementById('get-reward')?.addEventListener('click', async () => {

241

const success = await adManager.showRewardedAd();

242

if (success) {

243

console.log('User will receive reward after ad completion');

244

}

245

});

246

```

247

248

### Conversion Tracking Framework

249

250

```typescript

251

class ConversionTracker {

252

private pixelCode: string;

253

254

constructor(pixelCode: string) {

255

this.pixelCode = pixelCode;

256

}

257

258

async trackEvent(event: string, value: number = 0, customParams?: Record<string, any>): Promise<void> {

259

try {

260

// Track conversion

261

await bridge.send('VKWebAppConversionHit', {

262

pixel_code: this.pixelCode,

263

conversion_event: event,

264

conversion_value: value

265

});

266

267

// Track retargeting with custom parameters

268

if (customParams) {

269

await bridge.send('VKWebAppRetargetingPixel', {

270

pixel_code: this.pixelCode,

271

custom_params: customParams

272

});

273

}

274

275

console.log(`Tracked ${event} with value ${value}`);

276

} catch (error) {

277

console.error('Failed to track conversion:', error);

278

}

279

}

280

281

async trackPurchase(amount: number, productId: string): Promise<void> {

282

await this.trackEvent('purchase', amount, {

283

product_id: productId,

284

timestamp: Date.now()

285

});

286

}

287

288

async trackRegistration(userId: string): Promise<void> {

289

await this.trackEvent('registration', 0, {

290

user_id: userId,

291

timestamp: Date.now()

292

});

293

}

294

295

async trackLevelComplete(level: number): Promise<void> {

296

await this.trackEvent('level_complete', level, {

297

level: level,

298

timestamp: Date.now()

299

});

300

}

301

}

302

303

// Usage

304

const tracker = new ConversionTracker('your-pixel-code');

305

306

// Track different events

307

await tracker.trackPurchase(100, 'premium_month');

308

await tracker.trackRegistration('user123');

309

await tracker.trackLevelComplete(5);

310

```

311

312

### Hybrid Monetization

313

314

```typescript

315

// Combine ads and payments for optimal revenue

316

class MonetizationManager {

317

private paymentManager: PaymentManager;

318

private adManager: AdManager;

319

private tracker: ConversionTracker;

320

321

constructor() {

322

this.paymentManager = new PaymentManager(51665960, 12345);

323

this.adManager = new AdManager();

324

this.tracker = new ConversionTracker('pixel-code');

325

}

326

327

async unlockPremiumContent(contentId: string): Promise<boolean> {

328

// Offer choice: pay or watch ads

329

const choice = await this.showMonetizationChoice();

330

331

if (choice === 'payment') {

332

const success = await this.paymentManager.purchaseProduct({

333

id: contentId,

334

name: 'Premium Content',

335

description: 'Unlock premium content',

336

price: 5000, // 50 rubles

337

category: 'consumable'

338

}, getCurrentUserId());

339

340

if (success) {

341

await this.tracker.trackPurchase(5000, contentId);

342

return true;

343

}

344

} else if (choice === 'ads') {

345

const adSuccess = await this.adManager.showRewardedAd();

346

347

if (adSuccess) {

348

// Wait for ad completion

349

return new Promise((resolve) => {

350

bridge.subscribe((event) => {

351

if (event.detail.type === 'VKWebAppShowNativeAdsResult') {

352

this.tracker.trackEvent('ad_reward', 0, { content_id: contentId });

353

resolve(true);

354

}

355

});

356

});

357

}

358

}

359

360

return false;

361

}

362

363

private async showMonetizationChoice(): Promise<'payment' | 'ads' | 'cancel'> {

364

// Show UI choice to user

365

return new Promise((resolve) => {

366

const modal = document.createElement('div');

367

modal.innerHTML = `

368

<div class="monetization-modal">

369

<h3>Unlock Premium Content</h3>

370

<button id="pay-button">Pay 50₽</button>

371

<button id="ads-button">Watch Ad</button>

372

<button id="cancel-button">Cancel</button>

373

</div>

374

`;

375

376

document.body.appendChild(modal);

377

378

modal.querySelector('#pay-button')?.addEventListener('click', () => {

379

document.body.removeChild(modal);

380

resolve('payment');

381

});

382

383

modal.querySelector('#ads-button')?.addEventListener('click', () => {

384

document.body.removeChild(modal);

385

resolve('ads');

386

});

387

388

modal.querySelector('#cancel-button')?.addEventListener('click', () => {

389

document.body.removeChild(modal);

390

resolve('cancel');

391

});

392

});

393

}

394

}

395

```