CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vkontakte--vk-bridge

Bridge library for VK Mini Apps to communicate with VK clients across iOS, Android, and Web platforms

Pending
Overview
Eval results
Files

user-data.mddocs/

User Data & Profile

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

Capabilities

User Information

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

/**
 * Get user information by ID or current user
 * @param props.user_id - Specific user ID (optional, defaults to current user)
 * @param props.user_ids - Comma-separated list of user IDs (alternative to user_id)
 * @returns User profile information
 */
function send(method: 'VKWebAppGetUserInfo', props?: {
  user_id?: number;
  user_ids?: string;
}): Promise<UserInfo>;

interface UserInfo {
  /** User ID */
  id: number;
  /** First name */
  first_name: string;
  /** Last name */
  last_name: string;
  /** Profile photo 100px */
  photo_100: string;
  /** Profile photo 200px */
  photo_200: string;
  /** Whether profile is closed */
  is_closed: boolean;
  /** Whether current user can access closed profile */
  can_access_closed: boolean;
  /** User's timezone (if available) */
  timezone?: number;
  /** User's language (if available) */
  lang?: string;
}

Usage Examples:

// Get current user info
const currentUser = await bridge.send('VKWebAppGetUserInfo');
console.log(`Hello, ${currentUser.first_name} ${currentUser.last_name}!`);
console.log('Profile photo:', currentUser.photo_200);

// Get specific user info
const userInfo = await bridge.send('VKWebAppGetUserInfo', {
  user_id: 12345
});

// Get multiple users info
const usersInfo = await bridge.send('VKWebAppGetUserInfo', {
  user_ids: '12345,67890,111213'
});

// Check privacy settings
if (userInfo.is_closed && !userInfo.can_access_closed) {
  console.log('User profile is private');
} else {
  console.log('User profile is accessible');
}

Friends List

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

/**
 * Get user's friends list
 * @param props.multi - Whether to return detailed friend information
 * @returns Friends list with user details
 */
function send(method: 'VKWebAppGetFriends', props?: {
  multi?: boolean;
}): Promise<{
  users: UserGetFriendsFriend[];
}>;

interface UserGetFriendsFriend {
  /** Friend's user ID */
  id: number;
  /** Friend's first name */
  first_name: string;
  /** Friend's last name */
  last_name: string;
  /** Friend's profile photo */
  photo_100: string;
  /** Friend's larger profile photo */
  photo_200: string;
  /** Whether friend is online */
  online?: 0 | 1;
  /** Last seen timestamp */
  last_seen?: {
    time: number;
    platform: number;
  };
}

Usage Examples:

// Get friends list
const friendsResult = await bridge.send('VKWebAppGetFriends');
console.log(`You have ${friendsResult.users.length} friends`);

// Display friends with photos
friendsResult.users.forEach(friend => {
  console.log(`${friend.first_name} ${friend.last_name}`, friend.photo_100);
});

// Get detailed friends info
const detailedFriends = await bridge.send('VKWebAppGetFriends', {
  multi: true
});

// Filter online friends
const onlineFriends = detailedFriends.users.filter(friend => friend.online === 1);
console.log(`${onlineFriends.length} friends are online`);

// Sort friends by last seen
const recentFriends = detailedFriends.users
  .filter(friend => friend.last_seen)
  .sort((a, b) => (b.last_seen!.time - a.last_seen!.time))
  .slice(0, 10);

Contact Information

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

/**
 * Get user's email address
 * @returns Email with verification signature
 */
function send(method: 'VKWebAppGetEmail'): Promise<{
  email: string;
  sign: string;
}>;

/**
 * Get user's phone number
 * @returns Phone number with verification data
 */
function send(method: 'VKWebAppGetPhoneNumber'): Promise<{
  phone_number: string;
  sign: string;
  is_verified: boolean;
}>;

Usage Examples:

// Get user email
try {
  const emailData = await bridge.send('VKWebAppGetEmail');
  console.log('User email:', emailData.email);
  console.log('Verification sign:', emailData.sign);
  
  // Verify signature on your server
  // The sign should be verified using your app secret key
} catch (error) {
  console.log('User denied email access or email not available');
}

// Get user phone number
try {
  const phoneData = await bridge.send('VKWebAppGetPhoneNumber');
  console.log('Phone number:', phoneData.phone_number);
  console.log('Is verified:', phoneData.is_verified);
  console.log('Verification sign:', phoneData.sign);
} catch (error) {
  console.log('User denied phone access or phone not available');
}

Personal Card Data

Access structured personal information including contact details and address data.

/**
 * Get personal card data with specified information types
 * @param props.type - Array of requested data types
 * @returns Personal card information
 */
function send(method: 'VKWebAppGetPersonalCard', props: {
  type: PersonalCardType[];
}): Promise<PersonalCardData>;

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

interface PersonalCardData {
  phone?: string;
  email?: string;
  address?: {
    country?: string;
    city?: string;
    street?: string;
    house?: string;
    apartment?: string;
    postal_code?: string;
  };
}

Usage Examples:

// Get phone and email
const personalData = await bridge.send('VKWebAppGetPersonalCard', {
  type: ['phone', 'email']
});

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

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

// Get full personal card including address
const fullPersonalData = await bridge.send('VKWebAppGetPersonalCard', {
  type: ['phone', 'email', 'address']
});

if (fullPersonalData.address) {
  const addr = fullPersonalData.address;
  const fullAddress = [
    addr.street,
    addr.house,
    addr.apartment,
    addr.city,
    addr.country,
    addr.postal_code
  ].filter(Boolean).join(', ');
  
  console.log('Address:', fullAddress);
}

// Use for form auto-filling
function fillContactForm(data: PersonalCardData) {
  const phoneInput = document.getElementById('phone') as HTMLInputElement;
  const emailInput = document.getElementById('email') as HTMLInputElement;
  
  if (data.phone && phoneInput) {
    phoneInput.value = data.phone;
  }
  
  if (data.email && emailInput) {
    emailInput.value = data.email;
  }
  
  if (data.address) {
    const cityInput = document.getElementById('city') as HTMLInputElement;
    if (data.address.city && cityInput) {
      cityInput.value = data.address.city;
    }
  }
}

Granted Permissions

Check what device permissions have been granted to the app.

/**
 * Get currently granted device permissions
 * @returns List of granted permissions
 */
function send(method: 'VKWebAppGetGrantedPermissions'): Promise<{
  permissions: EGrantedPermission[];
}>;

enum EGrantedPermission {
  CAMERA = 'camera',
  LOCATION = 'location',
  PHOTO = 'photo'
}

Usage Examples:

// Check granted permissions
const permissions = await bridge.send('VKWebAppGetGrantedPermissions');
console.log('Granted permissions:', permissions.permissions);

// Enable features based on permissions
const hasCamera = permissions.permissions.includes(EGrantedPermission.CAMERA);
const hasLocation = permissions.permissions.includes(EGrantedPermission.LOCATION);
const hasPhoto = permissions.permissions.includes(EGrantedPermission.PHOTO);

// Show/hide UI elements based on permissions
const cameraButton = document.getElementById('camera-button');
if (cameraButton) {
  cameraButton.style.display = hasCamera ? 'block' : 'none';
}

// Request permissions-dependent functionality
if (hasCamera) {
  // Enable QR code scanner
  const qrButton = document.getElementById('qr-scanner');
  if (qrButton) {
    qrButton.onclick = async () => {
      const result = await bridge.send('VKWebAppOpenCodeReader');
      console.log('QR code:', result.code_data);
    };
  }
}

if (hasLocation) {
  // Enable location features
  const locationButton = document.getElementById('get-location');
  if (locationButton) {
    locationButton.onclick = async () => {
      const geo = await bridge.send('VKWebAppGetGeodata');
      if (geo.available === 1) {
        console.log('Location:', geo.lat, geo.long);
      }
    };
  }
}

Privacy and Security Considerations

Data Verification

// Always verify signatures on your server
async function verifyUserEmail(email: string, sign: string, userId: number): Promise<boolean> {
  // Server-side verification using your app secret key
  const response = await fetch('/api/verify-email', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, sign, userId })
  });
  
  return response.ok;
}

// Usage
const emailData = await bridge.send('VKWebAppGetEmail');
const isVerified = await verifyUserEmail(
  emailData.email, 
  emailData.sign, 
  currentUser.id
);

if (isVerified) {
  // Use verified email
  console.log('Verified email:', emailData.email);
} else {
  console.error('Email verification failed');
}

Graceful Permission Handling

async function getUserDataSafely() {
  const userData: Partial<{
    profile: UserInfo;
    email: string;
    phone: string;
    friends: UserGetFriendsFriend[];
  }> = {};

  try {
    // Always try to get profile first
    userData.profile = await bridge.send('VKWebAppGetUserInfo');
  } catch (error) {
    console.error('Failed to get user profile:', error);
    return null;
  }

  // Try to get additional data with fallbacks
  try {
    const emailData = await bridge.send('VKWebAppGetEmail');
    userData.email = emailData.email;
  } catch (error) {
    console.log('Email not available or access denied');
  }

  try {
    const phoneData = await bridge.send('VKWebAppGetPhoneNumber');
    userData.phone = phoneData.phone_number;
  } catch (error) {
    console.log('Phone not available or access denied');
  }

  try {
    const friendsData = await bridge.send('VKWebAppGetFriends');
    userData.friends = friendsData.users;
  } catch (error) {
    console.log('Friends list not available or access denied');
  }

  return userData;
}

Error Handling Patterns

// Handle different error types
try {
  const userInfo = await bridge.send('VKWebAppGetUserInfo', { user_id: 12345 });
} catch (error) {
  switch (error.error_type) {
    case 'client_error':
      if (error.error_data.error_code === 15) {
        console.log('User not found or privacy settings prevent access');
      } else {
        console.error('Client error:', error.error_data.error_reason);
      }
      break;
    case 'api_error':
      console.error('API error:', error.error_data.error_msg);
      break;
    default:
      console.error('Unexpected error:', error);
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-vkontakte--vk-bridge

docs

advertising-monetization.md

application-lifecycle.md

authentication.md

core-bridge.md

device-features.md

geolocation.md

index.md

launch-parameters.md

middleware.md

payments-commerce.md

qr-barcode-scanning.md

social-features.md

storage-data.md

ui-display.md

user-data.md

tile.json