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 + snippet2א. תצורה: וידג׳ט (ה-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|awaypbx.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.