कंटेंट पर जाएँ
गाइड

Wixzel Voice के साथ WebSocket पर Flutter वॉइस एजेंट जोड़ें

इस गाइड के अंत तक आपके Flutter ऐप में यूज़र आपके बनाए वॉइस एजेंट से WebSocket पर बात कर सकेंगे, बिना SIP ट्रंक और बिना फ़ोन नंबर के। आपका सर्वर एक बार इस्तेमाल होने वाला सेशन बनाता है, इसलिए आपकी API की कभी ऐप तक नहीं पहुँचती, और wixzel_voice Dart SDK प्रोटोकॉल संभालता है। लगभग एक घंटा लगेगा, ज़्यादातर माइक्रोफ़ोन और स्पीकर जोड़ने में। एक सेशन उसी इंजन पर फ़ोन कॉल की तरह बिल होता है: Gemini Live इंजन पर $0.0491 प्रति कनेक्टेड मिनट, चार मिनट के सेशन के लिए लगभग $0.20, प्रीपेड बैलेंस से प्रति सेकंड, और टेलीफ़ोनी का कोई खर्च नहीं।

लेखक · प्रकाशित · अपडेट

समय
लगभग एक घंटा
इंजन
gemini-live
इंजन टाइम
$0.0491 प्रति कनेक्टेड मिनट

शुरू करने से पहले आपको क्या चाहिए?

  • क्रेडिट वाली Wixzel Voice API की, जो आपके सर्वर पर रहे।
  • सेशन बनाने के लिए आपके कंट्रोल वाला एक सर्वर। उदाहरण में Node.js और Express है; कोई भी भाषा जो HTTPS रिक्वेस्ट भेज सके, काम करेगी।
  • एक Flutter ऐप, जिसमें 16-bit PCM स्ट्रीम करने वाला रिकॉर्डिंग प्लगइन हो, बेहतर हो कि 8 kHz मोनो पर echo cancellation के साथ, और एक प्लेयर जो raw PCM लेता हो।

इसे Wixzel Voice पर स्टेप-बाय-स्टेप कैसे बनाएँ?

  1. 01एजेंट एक बार बनाएँ

    यह एजेंट Gemini Live इस्तेमाल करता है, एक realtime मॉडल जो सुनता है, सोचता है और बोलता है:

    shell
    curl https://api.voice.wixzel.com/v1/agents \
      -H "Authorization: Bearer $WIXZEL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "In-app assistant",
        "system_prompt": "You are the voice assistant inside the Acme app. Answer in one or two short sentences.",
        "opening_message": "Hi, what can I help you with?",
        "voice": {
          "realtime": { "model": "google/gemini-live", "voice": "Kore" }
        }
      }'

    इस एजेंट में कुछ भी ऐप के लिए खास नहीं है: यही एजेंट किसी फ़ोन नंबर पर भी जवाब दे सकता है। इसका id अपने सर्वर पर AGENT_ID के रूप में रखें।

  2. 02अपने सर्वर पर सेशन बनाएँ

    ऐप के पास कभी आपकी API की नहीं होती। वह आपके सर्वर से पूछता है, और आपका सर्वर POST /v1/realtime/sessions से API से सेशन माँगता है, यहाँ TypeScript SDK के ज़रिए:

    server.mjs
    import express from 'express';
    import { WixzelVoice } from 'wixzel-voice';
    
    const wixzel = new WixzelVoice({ apiKey: process.env.WIXZEL_API_KEY });
    const app = express();
    
    // Replace with your own authentication. It must set req.userId.
    function requireUser(req, res, next) {
      req.userId = 'demo-user';
      next();
    }
    
    app.post('/voice/session', requireUser, async (req, res) => {
      const session = await wixzel.realtime.createSession({
        agent_id: process.env.AGENT_ID,
        max_duration_seconds: 300,
        metadata: { user_id: req.userId },
      });
      res.json(session);
    });
    
    app.listen(3000);

    रिस्पॉन्स में सॉकेट का url, एक client_secret जो सिर्फ़ एक बार, एक मिनट के लिए, इसी एजेंट के लिए काम करता है, और audio_format: "mulaw_8000" होता है। सेशन बनाने का कोई खर्च नहीं; बिलिंग तब शुरू होती है जब ऐप कनेक्ट होता है। max_duration_seconds बातचीत की अधिकतम अवधि तय करता है, 10 से 3600 सेकंड तक, डिफ़ॉल्ट 600। metadata कॉल रिकॉर्ड पर वापस दिखता है और मॉडल को कभी नहीं भेजा जाता। allowed_origins सिर्फ़ ब्राउज़र के लिए मायने रखता है, इसलिए नेटिव ऐप इसे छोड़ देता है।

  3. 03ऐप से कनेक्ट करें

    flutter pub add wixzel_voice http से SDK जोड़ें, फिर आपके सर्वर से मिला सेशन खोलें:

    voice_call.dart
    import 'dart:async';
    import 'dart:convert';
    import 'dart:typed_data';
    
    import 'package:http/http.dart' as http;
    import 'package:wixzel_voice/wixzel_voice.dart';
    
    /// Whatever your playback plugin offers, behind a small interface.
    abstract class PcmPlayer {
      void add(Int16List samples);
      void clear();
    }
    
    class VoiceCall {
      VoiceCall({required this.player, required this.onLine});
    
      final PcmPlayer player;
      final void Function(String role, String text) onLine;
    
      RealtimeConnection? _conn;
      StreamSubscription<Uint8List>? _mic;
      final List<int> _pending = [];
    
      /// [micBytes] is 16-bit little-endian PCM, 8 kHz mono, from your recording plugin.
      Future<void> start(Stream<Uint8List> micBytes) async {
        final res = await http.post(Uri.parse('https://api.example.com/voice/session'));
        final status = res.statusCode;
        if (status != 200) throw Exception('Could not start a voice session: HTTP $status');
        final session = RealtimeSession.fromJson(jsonDecode(res.body) as Map<String, dynamic>);
    
        final conn = RealtimeConnection.forSession(session);
        _conn = conn;
        conn.events.listen((event) {
          switch (event) {
            case RealtimeAudio(:final mulaw):
              player.add(mulawToPcm16(mulaw));
            case RealtimeAudioClear():
              player.clear(); // the user interrupted: drop queued audio
            case RealtimeTranscript(:final role, :final text):
              onLine(role, text);
            case RealtimeError(:final code, :final message):
              onLine('error', '$code: $message');
            case RealtimeEnded(:final reason):
              onLine('system', 'ended: $reason');
              _mic?.cancel();
            default:
          }
        });
        await conn.ready;
        _mic = micBytes.listen(_send);
      }
    
      void _send(Uint8List bytes) {
        final data = ByteData.sublistView(bytes);
        for (var i = 0; i + 1 < bytes.length; i += 2) {
          _pending.add(data.getInt16(i, Endian.little));
        }
        // 160 samples is 20 ms at 8 kHz, the frame size the server expects.
        while (_pending.length >= 160) {
          final frame = Int16List.fromList(_pending.sublist(0, 160));
          _pending.removeRange(0, 160);
          _conn?.sendAudio(pcm16ToMulaw(frame));
        }
      }
    
      Future<void> end() async {
        await _mic?.cancel();
        await _conn?.end();
      }
    }

    RealtimeConnection सिर्फ़ प्रोटोकॉल संभालता है: यह माइक्रोफ़ोन या स्पीकर नहीं खोलता, जिससे SDK प्लगइन dependencies से मुक्त रहता है और आप वही ऑडियो प्लगइन इस्तेमाल कर सकते हैं जो आपके पास पहले से हैं। pcm16ToMulaw और mulawToPcm16 16-bit PCM और wire पर जाने वाले फ़ॉर्मैट के बीच बदलते हैं।

    पहले माइक्रोफ़ोन की अनुमति माँगें: Android पर RECORD_AUDIO और iOS पर NSMicrophoneUsageDescription।

  4. 04echo cancellation चालू करें, और फ़ोन जैसी ऑडियो क्वालिटी की उम्मीद रखें

    रिकॉर्डिंग प्लगइन में अपने प्लेटफ़ॉर्म का echo cancellation चालू करें। इसके बिना एजेंट स्पीकर से अपनी ही आवाज़ सुनता है और खुद को बीच में टोक देता है।

    ऑडियो दोनों दिशाओं में 8 kHz पर G.711 µ-law है, बिल्कुल फ़ोन लाइन जैसा, क्योंकि सेशन उसी मीडिया पाथ से चलते हैं जिससे कॉल। बोली के लिए यह ठीक है, पर wideband ऑडियो से कम। अगर आपका प्लगइन अनुमति दे तो 8 kHz पर रिकॉर्ड करें, नहीं तो pcm16ToMulaw से पहले resample करें, और एजेंट का ऑडियो 8 kHz मोनो पर चलाएँ।

  5. 05बाद में सेशन पढ़ें

    हर सेशन channel: "web" वाला एक कॉल रिकॉर्ड है:

    shell
    curl "https://api.voice.wixzel.com/v1/calls?channel=web&limit=5" \
      -H "Authorization: Bearer $WIXZEL_API_KEY"

    वेब सेशन इनकमिंग होता है, उसमें from या to नहीं होता, और उसमें अवधि, cost_micros और आपका metadata होता है; GET /v1/calls/{id} ट्रांसक्रिप्ट भी देता है। यह उसी callCompleted webhook के साथ खत्म होता है जो फ़ोन कॉल भेजती है। वेब सेशन रिकॉर्ड नहीं होते।

Wixzel Voice पर इस बिल्ड की लागत कितनी है?

$0.0491 प्रति कनेक्टेड मिनट पर gemini-live इंजन पर 4 मिनट के सेशन का इंजन टाइम: हर सेशन पर लगभग $0.20। टेलीफ़ोनी की कोई लागत नहीं है, क्योंकि कोई फ़ोन लाइन नहीं है।

इस गाइड के बिल्ड का मासिक इंजन खर्च
हर महीने के सेशनकनेक्टेड मिनटहर महीने का इंजन खर्च
5002,000$98.20
2,50010,000$491
10,00040,000$1,964

एक सेशन का खर्च उसी इंजन पर फ़ोन कॉल जितना है, प्रति सेकंड, उसी प्रीपेड बैलेंस से। सेशन बनाने का कोई खर्च नहीं, इसलिए जो यूज़र स्क्रीन खोलकर माइक्रोफ़ोन की अनुमति नहीं देता, उसका भी कोई खर्च नहीं।

प्रीपेड, बिना सब्सक्रिप्शन और बिना फ़्री टियर: $5 से क्रेडिट जोड़ें और इस्तेमाल उसी से कटता है। अपने इस्तेमाल का अनुमान लगाएँ।

इस बिल्ड पर Wixzel Voice की कौन-सी सीमाएँ लागू होती हैं?

  • फ़ोन जैसा ऑडियो: दोनों दिशाओं में 8 kHz पर G.711 µ-law, wideband नहीं।
  • Dart SDK ऑडियो रिकॉर्ड या प्ले नहीं करता। माइक्रोफ़ोन और स्पीकर आपका ऐप अपनी पसंद के प्लगइन से देता है।
  • सेशन फ़ोन कॉल के साथ अकाउंट की एक साथ चलने वाली कॉल की सीमा में गिने जाते हैं, जो डिफ़ॉल्ट रूप से पाँच है। माँगने पर यह सीमा बढ़ाई जाती है।
  • एक सेशन डिफ़ॉल्ट रूप से 10 मिनट और ज़्यादा से ज़्यादा एक घंटा चलता है, और दो मिनट की खामोशी उसे खत्म कर देती है।
  • वेब सेशन रिकॉर्ड नहीं होते, और यूज़र को किसी व्यक्ति तक ट्रांसफ़र करने के लिए दूसरी लाइन नहीं है।

अक्सर पूछे जाने वाले सवाल

क्या Flutter के लिए कोई वॉइस एजेंट API है?

Wixzel Voice में है। इसके Dart SDK, pub.dev पर wixzel_voice, में RealtimeConnection है, जो Flutter या Dart ऐप को WebSocket पर वॉइस एजेंट से जोड़ता है। सेशन आपका सर्वर आपकी API की से बनाता है; ऐप के पास सिर्फ़ एक मिनट का, एक बार इस्तेमाल होने वाला secret होता है।

क्या ऐप के अंदर वॉइस एजेंट के लिए फ़ोन नंबर या SIP ट्रंक चाहिए?

नहीं। वेब और मोबाइल ऐप में सेशन WebSocket पर चलते हैं और कुछ कनेक्ट करने की ज़रूरत नहीं होती। ट्रंक और नंबर सिर्फ़ असली फ़ोन से और फ़ोन पर कॉल के लिए चाहिए।

एजेंट बार-बार खुद को बीच में क्यों टोकता है?

वह स्पीकर से अपनी ही आवाज़ सुन रहा है। अपने रिकॉर्डिंग प्लगइन में echo cancellation चालू करें, या पक्का करने के लिए हेडफ़ोन लगाकर टेस्ट करें।

क्या ऐप में कोई दूसरा इंजन इस्तेमाल किया जा सकता है?

हाँ। classic और sarvam पाइपलाइन भी सॉकेट पर चलती हैं: किसी खास ElevenLabs आवाज़ के लिए classic चुनें, या भारतीय भाषाओं के लिए sarvam। कीमत इंजन की अपनी प्रति मिनट कीमत है, फ़ोन कॉल जितनी ही; यहाँ Gemini Live इस्तेमाल हुआ है, $0.0491 पर।

सेशन के बीच अकाउंट का क्रेडिट खत्म हो जाए तो क्या होता है?

ऐप को कोड low_balance के साथ एक session.warning मिलता है, जिसमें लगभग कितने सेकंड बचे हैं यह होता है, फिर सेशन insufficient_credits वजह के साथ खत्म हो जाता है। जिस सेशन के लिए बिल्कुल क्रेडिट न हो, वह close code 4402 के साथ रिजेक्ट हो जाता है।

और कहाँ पढ़ें

  • Realtime: वेब और मोबाइलडॉक्स

    सेशन बनाना, प्रोटोकॉल, रिजेक्शन कोड और बिलिंग।

  • SDKडॉक्स

    Dart और TypeScript SDK, ब्राउज़र क्लाइंट समेत।

  • वॉइस इंजनडॉक्स

    Realtime और कंपोज़ की गई आवाज़ें, और आवाज़ों की लिस्ट।

  • Webhookडॉक्स

    वेब सेशन के लिए callCompleted, आपके metadata के साथ।

एजेंटिक टेलीफ़ोनी के लिए API

Wixzel Voice के बारे में

Wixzel Voice एक वॉइस AI API है, जिससे ऐसे AI एजेंट बनते हैं जो आपके अपने SIP ट्रंक पर असली फ़ोन कॉल करते और उनका जवाब देते हैं, या आपके वेब और मोबाइल ऐप में लोगों से बात करते हैं। एक API की और एक प्रीपेड बैलेंस हर वॉइस इंजन को कवर करते हैं, और बिल असली इस्तेमाल के हर सेकंड के हिसाब से बनता है।

Wixzel Voice MCP सर्वर से Claude को असली फ़ोन लाइन दें

Claude Code या claude.ai में Claude आपके SIP ट्रंक से असली कॉल करता है और ट्रांसक्रिप्ट पढ़कर बताता है, और कुछ भी डायल होने से पहले आपसे पुष्टि लेता है।

Wixzel Voice के साथ Node.js में Twilio AI रिसेप्शनिस्ट बनाएँ

आपके मौजूदा Twilio नंबर पर एक AI रिसेप्शनिस्ट जवाब देता है और API में अपॉइंटमेंट बुक करता है, Node.js में बना हुआ।

Wixzel Voice के sarvam इंजन पर हिंदी और मलयालम फ़ोन एजेंट

दो फ़ोन एजेंट, एक हिंदी और एक मलयालम बोलने वाला, Sarvam के भारतीय भाषा मॉडल पर, जो आपके SIP ट्रंक से कॉल का जवाब देते हैं या कॉल करते हैं।

Wixzel Voice API से असली फ़ोन कॉल पर Gemini Live

चार cURL रिक्वेस्ट से आपके SIP ट्रंक पर असली फ़ोन को कॉल करता Gemini Live एजेंट, और ट्रांसक्रिप्ट और खर्च के साथ कॉल रिकॉर्ड।

Wixzel Voice के साथ AI लीड-क्वालिफ़िकेशन कैंपेन चलाएँ

लीड की एक लिस्ट, जिसे आपका एजेंट आपके SIP ट्रंक पर, एक साथ चलने वाली कॉल की आपकी सीमा के हिसाब से बैच में कॉल करता है, और हर कॉल का स्टेटस और ट्रांसक्रिप्ट वापस पढ़ा जाता है।

Wixzel Voice से अपनी वेबसाइट पर बोलने वाला AI मैस्कट लगाएँ

आपकी वेबसाइट के कोने में एक बोलने वाला मैस्कट, जिसे विज़िटर ब्राउज़र से कॉल करते हैं, आपके डोमेन और आपकी रोज़ की सीमाओं तक सीमित, और हर कॉलर की लिस्ट के साथ।

Wixzel Voice के साथ Flutter ऐप में अपने एजेंट का मैस्कट दिखाएँ

एक Flutter स्क्रीन, जिसमें आपके एजेंट का मैस्कट realtime कॉल के दौरान एजेंट की आवाज़ के साथ मुँह हिलाता है, और आपकी API की आपके सर्वर पर रहती है।

अपना पहला वॉइस एजेंट बनाएँ