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

qr-barcode-scanning.mddocs/

QR & Barcode Scanning

Camera-based scanning capabilities for QR codes, barcodes, and other machine-readable codes with customizable scanning modes and output formats.

Capabilities

QR Code Reader

Open QR code scanner with camera for scanning QR codes and receiving decoded data.

/**
 * Open QR code scanner with camera
 * @returns Scanned QR code data and format
 */
function send(method: 'VKWebAppOpenCodeReader'): Promise<CodeReaderOutput>;

/**
 * Alternative QR scanner method
 * @returns Scanned QR code data
 */
function send(method: 'VKWebAppOpenQR'): Promise<{
  qr_data: string;
}>;

interface CodeReaderOutput {
  /** Scanned code data content */
  code_data: string;
  /** Code format type */
  code_type?: string;
}

Usage Examples:

// Basic QR code scanning
try {
  const qrResult = await bridge.send('VKWebAppOpenCodeReader');
  console.log('QR Code data:', qrResult.code_data);
  console.log('Code type:', qrResult.code_type);
  
  // Handle different QR code types
  if (qrResult.code_data.startsWith('http')) {
    // Handle URL QR codes
    window.open(qrResult.code_data, '_blank');
  } else if (qrResult.code_data.includes('@')) {
    // Handle email QR codes
    window.location.href = `mailto:${qrResult.code_data}`;
  } else {
    // Handle text QR codes
    console.log('Text content:', qrResult.code_data);
  }
} catch (error) {
  console.error('QR scanning failed:', error);
}

// Alternative QR scanning method
try {
  const qrData = await bridge.send('VKWebAppOpenQR');
  console.log('QR data:', qrData.qr_data);
} catch (error) {
  console.error('QR scanning cancelled or failed:', error);
}

// Check scanner availability before use
const canScanQR = await bridge.supportsAsync('VKWebAppOpenCodeReader');
if (canScanQR) {
  const result = await bridge.send('VKWebAppOpenCodeReader');
  handleQRResult(result);
} else {
  // Fallback: manual input or web-based scanner
  console.log('Camera scanning not available');
}

QR Code Processing

Process and validate scanned QR code data for different content types.

// QR code content type detection
function detectQRType(qrData: string): 'url' | 'email' | 'phone' | 'wifi' | 'text' {
  if (qrData.startsWith('http://') || qrData.startsWith('https://')) {
    return 'url';
  } else if (qrData.includes('@') && qrData.includes('.')) {
    return 'email';
  } else if (qrData.startsWith('tel:') || /^\+?[\d\s-()]+$/.test(qrData)) {
    return 'phone';
  } else if (qrData.startsWith('WIFI:')) {
    return 'wifi';
  } else {
    return 'text';
  }
}

// Handle different QR code types
async function handleQRResult(result: CodeReaderOutput) {
  const type = detectQRType(result.code_data);
  
  switch (type) {
    case 'url':
      // Open URL
      if (confirm(`Open ${result.code_data}?`)) {
        window.open(result.code_data, '_blank');
      }
      break;
      
    case 'email':
      // Open email client
      window.location.href = `mailto:${result.code_data}`;
      break;
      
    case 'phone':
      // Open phone dialer
      const phoneNumber = result.code_data.replace('tel:', '');
      window.location.href = `tel:${phoneNumber}`;
      break;
      
    case 'wifi':
      // Parse WiFi configuration
      const wifiMatch = result.code_data.match(/WIFI:T:([^;]*);S:([^;]*);P:([^;]*);H:([^;]*);/);
      if (wifiMatch) {
        const [, type, ssid, password, hidden] = wifiMatch;
        console.log('WiFi Network:', { type, ssid, password, hidden });
        // Display WiFi connection info to user
      }
      break;
      
    case 'text':
      // Handle plain text
      console.log('Text content:', result.code_data);
      // Copy to clipboard or display to user
      await bridge.send('VKWebAppCopyText', { text: result.code_data });
      break;
  }
}

Scanner Integration Patterns

Common patterns for integrating QR scanning into app workflows.

// Scanner button component
class QRScannerButton {
  private async scanQR(): Promise<string | null> {
    try {
      // Check availability first
      if (!await bridge.supportsAsync('VKWebAppOpenCodeReader')) {
        throw new Error('QR scanner not available');
      }
      
      const result = await bridge.send('VKWebAppOpenCodeReader');
      return result.code_data;
    } catch (error) {
      if (error.error_type === 'client_error' && error.error_data.error_code === 4) {
        // User cancelled scanning
        console.log('QR scanning cancelled by user');
        return null;
      } else {
        // Other errors
        console.error('QR scanning error:', error);
        throw error;
      }
    }
  }
  
  async handleScanClick() {
    try {
      const qrData = await this.scanQR();
      if (qrData) {
        this.onQRScanned(qrData);
      }
    } catch (error) {
      this.onScanError(error);
    }
  }
  
  private onQRScanned(data: string) {
    // Handle successful scan
    console.log('QR Code scanned:', data);
  }
  
  private onScanError(error: any) {
    // Handle scan error
    console.error('Scan failed:', error);
  }
}

// Continuous scanning workflow
class ContinuousQRScanner {
  private isScanning = false;
  
  async startContinuousScanning() {
    this.isScanning = true;
    
    while (this.isScanning) {
      try {
        const result = await bridge.send('VKWebAppOpenCodeReader');
        
        // Process result
        if (this.isValidQR(result.code_data)) {
          this.processQR(result.code_data);
          break; // Stop after successful scan
        } else {
          // Invalid QR, continue scanning
          console.log('Invalid QR code, scanning again...');
        }
      } catch (error) {
        if (error.error_data?.error_code === 4) {
          // User cancelled
          this.isScanning = false;
          break;
        } else {
          // Other error, retry after delay
          await new Promise(resolve => setTimeout(resolve, 1000));
        }
      }
    }
  }
  
  stopScanning() {
    this.isScanning = false;
  }
  
  private isValidQR(data: string): boolean {
    // Implement validation logic
    return data.length > 0;
  }
  
  private processQR(data: string) {
    // Process valid QR code
    console.log('Valid QR processed:', data);
  }
}

Platform Availability

QR scanning is available on the following platforms:

  • iOS WebView: Full camera access with VKWebAppOpenCodeReader
  • Android WebView: Full camera access with VKWebAppOpenCodeReader
  • Web/Desktop: Not available (camera access restricted)

Always check method support before attempting to use camera functionality:

const canScan = await bridge.supportsAsync('VKWebAppOpenCodeReader');
if (!canScan) {
  // Provide alternative input method
  showManualInputDialog();
}

Error Handling

Common error scenarios and handling strategies:

try {
  const result = await bridge.send('VKWebAppOpenCodeReader');
  processQRResult(result);
} catch (error) {
  switch (error.error_data?.error_code) {
    case 4: // User cancelled
      console.log('User cancelled QR scanning');
      break;
    case 6: // Permission denied
      console.error('Camera permission denied');
      showPermissionDialog();
      break;
    case 10: // Camera not available
      console.error('Camera not available on device');
      showCameraUnavailableMessage();
      break;
    default:
      console.error('QR scanning failed:', error);
      showGenericErrorMessage();
  }
}

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