🇮🇱 עברית
Embed Dialer

הטמיעו את החייגן בכל תצורה

חייגן WebRTC מלא בתוך האפליקציה שלכם. בחרו: וידג׳ט מוכן בלחיצה, או Headless — המנוע שלנו נסתר ואתם בונים GUI משלכם (כפתורים, שדות, אירועים) דרך ה-SDK, ה-API או ה-MCP.

וידג׳ט

ה-UI שלנו, drop-in. שורה אחת ויש חייגן.

Headless (ה-GUI שלכם)

המנוע נסתר. אתם מציירים הכל ושולטים דרך פקודות + אירועים.

Token

exchange token חד-פעמי מה-backend (API או MCP).

1. השגת Token (צד-שרת)

ה-frontend לא נוגע בטוקן ה-API. ה-backend שלכם מפיק exchange token חד-פעמי ומעביר אותו ל-frontend.

# צד-שרת (backend) — הפיקו exchange token חד-פעמי (תקף 5 דק׳)
curl -X POST https://aicalls.txi.co.il/api/v1/embed/token \
  -H "Authorization: Bearer pbx_live_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "layout": "headless", "autoAnswer": false }'

# כל השדות אופציונליים. ללא userId → ברירת-מחדל: המשתמש הפעיל הראשון של הדייר.
# { userId?, crmUserId?, extensionId?, layout?: "widget"|"headless", autoAnswer? }

התשובה:

{
  "exchangeToken": "emx_…",        // העבירו ל-frontend (חד-פעמי)
  "embedUrl": "https://aicalls.txi.co.il/embed/dialer?t=emx_…&layout=headless",
  "snippet": "<script …>  // מוכן להדבקה",
  "commands": ["dial","answer","hangup","transfer","mute","sendDigit", …],
  "events":   ["ready","registered","call.ringing","call.answered","call.ended", …],
  "expiresIn": 300
}
גם דרך MCP:
// דרך MCP (סוכן AI) — אותו דבר ככלי:
tool: pbx_embed_token   { "layout": "headless" }
// מחזיר exchangeToken + embedUrl + snippet

2א. תצורה: וידג׳ט (ה-UI שלנו)

<!-- תצורה A — וידג׳ט מוכן (ה-UI שלנו) -->
<script src="https://aicalls.txi.co.il/embed.js"></script>
<div id="pbx"></div>
<script>
  const pbx = window.PBX.init({
    container: '#pbx',
    exchangeToken: 'emx_…',   // מה-backend שלכם
    layout: 'widget',         // widget | fullscreen | sidebar
  })
  pbx.on('call.answered', e => crm.openContact(e.callerNumber))
  pbx.on('call.ended',    e => crm.logCall(e))
</script>

2ב. תצורה: Headless (ה-GUI שלכם)

הדגל ui:'none' מטעין את המנוע ב-iframe נסתר (1px). כל מה שהמשתמש רואה — שלכם.

<!-- תצורה B — Headless: ה-GUI שלכם, המנוע שלנו נסתר -->
<script src="https://aicalls.txi.co.il/embed.js"></script>
<script>
  const pbx = window.PBX.init({
    exchangeToken: 'emx_…',
    ui: 'none',           // אין גרפיקה שלנו — iframe נסתר (WebRTC רץ ברקע)
    autoAnswer: false,    // אתם שולטים במענה לשיחות נכנסות
  })

  // 1) אירועים → ה-UI שלכם:
  pbx.on('ready',         ()  => {})
  pbx.on('registered',    ()  => myUi.enable())
  pbx.on('call.ringing',  e   => myUi.showIncoming(e))   // { number, direction }
  pbx.on('call.answered', e   => myUi.onLive(e))
  pbx.on('call.ended',    e   => myUi.clear(e))
  pbx.on('mute',          e   => myUi.setMuted(e.muted))
  pbx.on('error',         e   => myUi.toast(e.error))

  // 2) הכפתורים והשדות שלכם → המנוע:
  myDialButton.onclick    = () => pbx.dial(myNumberInput.value)
  myAnswerButton.onclick  = () => pbx.answer()
  myHangupButton.onclick  = () => pbx.hangup()
  myMuteButton.onclick    = () => pbx.toggleMute()      // mute()/unmute()
  myKeypad.onpress        = d  => pbx.sendDigit(d)       // DTMF
  myTransferButton.onclick= () => pbx.transfer('1002')
  myStatusSelect.onchange = v  => pbx.setStatus(v)       // available|busy|away
</script>

דוגמה רצה מלאה (כפתורים, מקלדת DTMF, יומן אירועים): /embed-headless-example.html

פקודות (frontend → מנוע)

pbx.dial(number)חיוג יוצא
pbx.answer()מענה לשיחה נכנסת (כש-autoAnswer:false)
pbx.hangup()ניתוק
pbx.reject()דחיית שיחה נכנסת
pbx.transfer(target)העברת שיחה (SIP REFER)
pbx.mute(on) / unmute() / toggleMute()השתקה
pbx.sendDigit(d)שליחת ספרת DTMF בשיחה
pbx.setStatus(s)סטטוס נציג: available|busy|away
pbx.setContext(ctx)הזרקת נתוני CRM (זיהוי מתקשר)

אירועים (מנוע → frontend)

pbx.on('ready', …)המנוע נטען ואומת
pbx.on('registered', …)השלוחה רשומה (אפשר לחייג)
pbx.on('call.ringing', …)שיחה מצלצלת — { number, direction }
pbx.on('call.started', …)שיחה התחילה
pbx.on('call.answered', …)שיחה נענתה
pbx.on('call.ended', …)שיחה הסתיימה
pbx.on('call.failed', …)חיוג נכשל — { error }
pbx.on('mute', …)מצב השתקה השתנה — { muted }
pbx.on('error', …)שגיאה — { error }

ללא SDK — postMessage גולמי

אם אתם נוהגים את ה-iframe ידנית, שתי נקודות קריטיות (אחרת הדפדפן זורק את ההודעה בשקט): ה-targetOrigin חייב להיות הדומיין של ה-iframe, וההודעה חייבת לכלול source:'pbx-sdk'.

// ללא ה-SDK? postMessage גולמי — שימו לב לשני אלה:
const iframe = document.querySelector('iframe')  // /embed/dialer?t=…&layout=headless
iframe.contentWindow.postMessage(
  { source: 'pbx-sdk', type: 'dial', number: '+97250…' }, // ← source חובה
  'https://aicalls.txi.co.il'                              // ← targetOrigin = ה-iframe, לא הדומיין שלכם! ('*' עובד גם)
)
// אירועים חוזרים: window.addEventListener('message', e => {
//   if (e.data?.source === 'pbx-iframe') handle(e.data.type, e.data.event, e.data.payload) })
רוצים גם אירועים בצד-שרת? כל אירועי השיחה זמינים גם כ-Webhooks ו-Socket.IO.