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

user-data.mddocs/

0

# User Data & Profile

1

2

Access to user profile information, friends list, contact details, and personal data with privacy controls and secure data handling.

3

4

## Capabilities

5

6

### User Information

7

8

Get comprehensive user profile information including basic details, photos, and privacy settings.

9

10

```typescript { .api }

11

/**

12

* Get user information by ID or current user

13

* @param props.user_id - Specific user ID (optional, defaults to current user)

14

* @param props.user_ids - Comma-separated list of user IDs (alternative to user_id)

15

* @returns User profile information

16

*/

17

function send(method: 'VKWebAppGetUserInfo', props?: {

18

user_id?: number;

19

user_ids?: string;

20

}): Promise<UserInfo>;

21

22

interface UserInfo {

23

/** User ID */

24

id: number;

25

/** First name */

26

first_name: string;

27

/** Last name */

28

last_name: string;

29

/** Profile photo 100px */

30

photo_100: string;

31

/** Profile photo 200px */

32

photo_200: string;

33

/** Whether profile is closed */

34

is_closed: boolean;

35

/** Whether current user can access closed profile */

36

can_access_closed: boolean;

37

/** User's timezone (if available) */

38

timezone?: number;

39

/** User's language (if available) */

40

lang?: string;

41

}

42

```

43

44

**Usage Examples:**

45

46

```typescript

47

// Get current user info

48

const currentUser = await bridge.send('VKWebAppGetUserInfo');

49

console.log(`Hello, ${currentUser.first_name} ${currentUser.last_name}!`);

50

console.log('Profile photo:', currentUser.photo_200);

51

52

// Get specific user info

53

const userInfo = await bridge.send('VKWebAppGetUserInfo', {

54

user_id: 12345

55

});

56

57

// Get multiple users info

58

const usersInfo = await bridge.send('VKWebAppGetUserInfo', {

59

user_ids: '12345,67890,111213'

60

});

61

62

// Check privacy settings

63

if (userInfo.is_closed && !userInfo.can_access_closed) {

64

console.log('User profile is private');

65

} else {

66

console.log('User profile is accessible');

67

}

68

```

69

70

### Friends List

71

72

Access user's friends list with detailed friend information and relationship data.

73

74

```typescript { .api }

75

/**

76

* Get user's friends list

77

* @param props.multi - Whether to return detailed friend information

78

* @returns Friends list with user details

79

*/

80

function send(method: 'VKWebAppGetFriends', props?: {

81

multi?: boolean;

82

}): Promise<{

83

users: UserGetFriendsFriend[];

84

}>;

85

86

interface UserGetFriendsFriend {

87

/** Friend's user ID */

88

id: number;

89

/** Friend's first name */

90

first_name: string;

91

/** Friend's last name */

92

last_name: string;

93

/** Friend's profile photo */

94

photo_100: string;

95

/** Friend's larger profile photo */

96

photo_200: string;

97

/** Whether friend is online */

98

online?: 0 | 1;

99

/** Last seen timestamp */

100

last_seen?: {

101

time: number;

102

platform: number;

103

};

104

}

105

```

106

107

**Usage Examples:**

108

109

```typescript

110

// Get friends list

111

const friendsResult = await bridge.send('VKWebAppGetFriends');

112

console.log(`You have ${friendsResult.users.length} friends`);

113

114

// Display friends with photos

115

friendsResult.users.forEach(friend => {

116

console.log(`${friend.first_name} ${friend.last_name}`, friend.photo_100);

117

});

118

119

// Get detailed friends info

120

const detailedFriends = await bridge.send('VKWebAppGetFriends', {

121

multi: true

122

});

123

124

// Filter online friends

125

const onlineFriends = detailedFriends.users.filter(friend => friend.online === 1);

126

console.log(`${onlineFriends.length} friends are online`);

127

128

// Sort friends by last seen

129

const recentFriends = detailedFriends.users

130

.filter(friend => friend.last_seen)

131

.sort((a, b) => (b.last_seen!.time - a.last_seen!.time))

132

.slice(0, 10);

133

```

134

135

### Contact Information

136

137

Access user's email and phone number with proper authorization and verification.

138

139

```typescript { .api }

140

/**

141

* Get user's email address

142

* @returns Email with verification signature

143

*/

144

function send(method: 'VKWebAppGetEmail'): Promise<{

145

email: string;

146

sign: string;

147

}>;

148

149

/**

150

* Get user's phone number

151

* @returns Phone number with verification data

152

*/

153

function send(method: 'VKWebAppGetPhoneNumber'): Promise<{

154

phone_number: string;

155

sign: string;

156

is_verified: boolean;

157

}>;

158

```

159

160

**Usage Examples:**

161

162

```typescript

163

// Get user email

164

try {

165

const emailData = await bridge.send('VKWebAppGetEmail');

166

console.log('User email:', emailData.email);

167

console.log('Verification sign:', emailData.sign);

168

169

// Verify signature on your server

170

// The sign should be verified using your app secret key

171

} catch (error) {

172

console.log('User denied email access or email not available');

173

}

174

175

// Get user phone number

176

try {

177

const phoneData = await bridge.send('VKWebAppGetPhoneNumber');

178

console.log('Phone number:', phoneData.phone_number);

179

console.log('Is verified:', phoneData.is_verified);

180

console.log('Verification sign:', phoneData.sign);

181

} catch (error) {

182

console.log('User denied phone access or phone not available');

183

}

184

```

185

186

### Personal Card Data

187

188

Access structured personal information including contact details and address data.

189

190

```typescript { .api }

191

/**

192

* Get personal card data with specified information types

193

* @param props.type - Array of requested data types

194

* @returns Personal card information

195

*/

196

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

197

type: PersonalCardType[];

198

}): Promise<PersonalCardData>;

199

200

type PersonalCardType = 'phone' | 'email' | 'address';

201

202

interface PersonalCardData {

203

phone?: string;

204

email?: string;

205

address?: {

206

country?: string;

207

city?: string;

208

street?: string;

209

house?: string;

210

apartment?: string;

211

postal_code?: string;

212

};

213

}

214

```

215

216

**Usage Examples:**

217

218

```typescript

219

// Get phone and email

220

const personalData = await bridge.send('VKWebAppGetPersonalCard', {

221

type: ['phone', 'email']

222

});

223

224

if (personalData.phone) {

225

console.log('Phone:', personalData.phone);

226

}

227

228

if (personalData.email) {

229

console.log('Email:', personalData.email);

230

}

231

232

// Get full personal card including address

233

const fullPersonalData = await bridge.send('VKWebAppGetPersonalCard', {

234

type: ['phone', 'email', 'address']

235

});

236

237

if (fullPersonalData.address) {

238

const addr = fullPersonalData.address;

239

const fullAddress = [

240

addr.street,

241

addr.house,

242

addr.apartment,

243

addr.city,

244

addr.country,

245

addr.postal_code

246

].filter(Boolean).join(', ');

247

248

console.log('Address:', fullAddress);

249

}

250

251

// Use for form auto-filling

252

function fillContactForm(data: PersonalCardData) {

253

const phoneInput = document.getElementById('phone') as HTMLInputElement;

254

const emailInput = document.getElementById('email') as HTMLInputElement;

255

256

if (data.phone && phoneInput) {

257

phoneInput.value = data.phone;

258

}

259

260

if (data.email && emailInput) {

261

emailInput.value = data.email;

262

}

263

264

if (data.address) {

265

const cityInput = document.getElementById('city') as HTMLInputElement;

266

if (data.address.city && cityInput) {

267

cityInput.value = data.address.city;

268

}

269

}

270

}

271

```

272

273

### Granted Permissions

274

275

Check what device permissions have been granted to the app.

276

277

```typescript { .api }

278

/**

279

* Get currently granted device permissions

280

* @returns List of granted permissions

281

*/

282

function send(method: 'VKWebAppGetGrantedPermissions'): Promise<{

283

permissions: EGrantedPermission[];

284

}>;

285

286

enum EGrantedPermission {

287

CAMERA = 'camera',

288

LOCATION = 'location',

289

PHOTO = 'photo'

290

}

291

```

292

293

**Usage Examples:**

294

295

```typescript

296

// Check granted permissions

297

const permissions = await bridge.send('VKWebAppGetGrantedPermissions');

298

console.log('Granted permissions:', permissions.permissions);

299

300

// Enable features based on permissions

301

const hasCamera = permissions.permissions.includes(EGrantedPermission.CAMERA);

302

const hasLocation = permissions.permissions.includes(EGrantedPermission.LOCATION);

303

const hasPhoto = permissions.permissions.includes(EGrantedPermission.PHOTO);

304

305

// Show/hide UI elements based on permissions

306

const cameraButton = document.getElementById('camera-button');

307

if (cameraButton) {

308

cameraButton.style.display = hasCamera ? 'block' : 'none';

309

}

310

311

// Request permissions-dependent functionality

312

if (hasCamera) {

313

// Enable QR code scanner

314

const qrButton = document.getElementById('qr-scanner');

315

if (qrButton) {

316

qrButton.onclick = async () => {

317

const result = await bridge.send('VKWebAppOpenCodeReader');

318

console.log('QR code:', result.code_data);

319

};

320

}

321

}

322

323

if (hasLocation) {

324

// Enable location features

325

const locationButton = document.getElementById('get-location');

326

if (locationButton) {

327

locationButton.onclick = async () => {

328

const geo = await bridge.send('VKWebAppGetGeodata');

329

if (geo.available === 1) {

330

console.log('Location:', geo.lat, geo.long);

331

}

332

};

333

}

334

}

335

```

336

337

## Privacy and Security Considerations

338

339

### Data Verification

340

341

```typescript

342

// Always verify signatures on your server

343

async function verifyUserEmail(email: string, sign: string, userId: number): Promise<boolean> {

344

// Server-side verification using your app secret key

345

const response = await fetch('/api/verify-email', {

346

method: 'POST',

347

headers: { 'Content-Type': 'application/json' },

348

body: JSON.stringify({ email, sign, userId })

349

});

350

351

return response.ok;

352

}

353

354

// Usage

355

const emailData = await bridge.send('VKWebAppGetEmail');

356

const isVerified = await verifyUserEmail(

357

emailData.email,

358

emailData.sign,

359

currentUser.id

360

);

361

362

if (isVerified) {

363

// Use verified email

364

console.log('Verified email:', emailData.email);

365

} else {

366

console.error('Email verification failed');

367

}

368

```

369

370

### Graceful Permission Handling

371

372

```typescript

373

async function getUserDataSafely() {

374

const userData: Partial<{

375

profile: UserInfo;

376

email: string;

377

phone: string;

378

friends: UserGetFriendsFriend[];

379

}> = {};

380

381

try {

382

// Always try to get profile first

383

userData.profile = await bridge.send('VKWebAppGetUserInfo');

384

} catch (error) {

385

console.error('Failed to get user profile:', error);

386

return null;

387

}

388

389

// Try to get additional data with fallbacks

390

try {

391

const emailData = await bridge.send('VKWebAppGetEmail');

392

userData.email = emailData.email;

393

} catch (error) {

394

console.log('Email not available or access denied');

395

}

396

397

try {

398

const phoneData = await bridge.send('VKWebAppGetPhoneNumber');

399

userData.phone = phoneData.phone_number;

400

} catch (error) {

401

console.log('Phone not available or access denied');

402

}

403

404

try {

405

const friendsData = await bridge.send('VKWebAppGetFriends');

406

userData.friends = friendsData.users;

407

} catch (error) {

408

console.log('Friends list not available or access denied');

409

}

410

411

return userData;

412

}

413

```

414

415

### Error Handling Patterns

416

417

```typescript

418

// Handle different error types

419

try {

420

const userInfo = await bridge.send('VKWebAppGetUserInfo', { user_id: 12345 });

421

} catch (error) {

422

switch (error.error_type) {

423

case 'client_error':

424

if (error.error_data.error_code === 15) {

425

console.log('User not found or privacy settings prevent access');

426

} else {

427

console.error('Client error:', error.error_data.error_reason);

428

}

429

break;

430

case 'api_error':

431

console.error('API error:', error.error_data.error_msg);

432

break;

433

default:

434

console.error('Unexpected error:', error);

435

}

436

}

437

```