Twilio Browser Hold, Add, Merge CallsJavascript

Форум по Javascript
Ответить Пред. темаСлед. тема
Anonymous
 Twilio Browser Hold, Add, Merge Calls

Сообщение Anonymous »

В настоящее время у меня интегрированный агент (от браузера) до интеграции вызова клиента (телефон) с использованием Twilio JS SDK, но теперь я хочу интегрировать первой вызов удержания, добавить новую функцию вызова и слияния, я пробовал все, но не найдено ресурса или выводов . < /p>
Следуя моему браузере JS < /p>
// Fetch Twilio token from PHP backend
async function fetchToken(agentId, conductedFrom) {
try {
const response = await fetch(`${crm_url}/twilio-generate-in-browser-call-token.php`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: "agentId=" + agentId + "&conductedFrom=" + conductedFrom
});
if (!response.ok) {
throw new Error('Failed to fetch token');
}
const data = await response.json();
return data.token;
} catch (error) {
console.error('Error fetching token:', error);
alert('Failed to fetch token. Please try again.');
return null;
}
}

// Global variables
let twilioDevice = null;
let activeConnection = null;
let callStartTime = null;
let timerInterval = null;

// Initialize Twilio Client
async function initializeTwilio(agentId, conductedFrom) {
const token = await fetchToken(agentId, conductedFrom);
if (!token) {
console.error("Token generation failed");
return;
}

try {
twilioDevice = new Twilio.Device(token, {
codecPreferences: ['opus', 'pcmu'],
enableRingingState: true,
debug: true, // Enable debugging logs
closeProtection: true // Prevent accidental page close during calls
});

// console.log('Twilio Device initialized:', twilioDevice.on);

twilioDevice.on('registered', () => {
console.log('Twilio Device is registered and ready to make calls');
});

twilioDevice.on('error', (error) => {
console.error('Twilio.Device Error:', error);
updateCallStatus('Error: ' + error.message);
});

twilioDevice.on('incoming', (connection) => {
console.log('Incoming call from:', connection.parameters.From);
updateCallStatus('Incoming call...');
showIncomingCallModal(connection);
jQuery("#newCallingDialerModal").modal('hide');
});

twilioDevice.on('disconnect', (connection) => {
console.log('Call disconnected');
updateCallStatus('Call ended');
stopTimer();
activeConnection = null; // Reset the active connection
jQuery('#newCallingStatusModal').modal('hide'); // Close the modal immediately
jQuery("#newCallingDialerModal").modal('hide');
jQuery('#newCallingIncomingCallModal').modal('hide');
});

twilioDevice.on('offline', () => {
console.log('Twilio device is offline');
jQuery('#newCallingIncomingCallModal').modal('hide');
});

// Listen for the 'tokenWillExpire' event there is 1 hr time limit but even for fallback
twilioDevice.on('tokenWillExpire', async () => {
refreshTwilioToken(agentId, conductedFrom);
});

// Check if registration is successful, and if not, try to explicitly call register()
await new Promise(resolve => {
twilioDevice.on('registered', resolve);
setTimeout(() => {
console.log("Device didn't register automatically, trying explicit register...");
twilioDevice.register();
}, 3000); // If not registered within 5 seconds, try explicit register()
});
} catch (error) {
console.error("Error initializing Twilio Device:", error);
}
}

async function updateParentCallStatus(callSid = null, directionFrom = "outgoing") {
if (callSid == null) {
console.error('CallSid Needed');
return;
}

try {
const response = await fetch(`${crm_url}/twilio-current-call-status-callback.php`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: "firstCallUpdateUpdateSid=" + callSid + "&directionFrom=" + directionFrom
});

const data = await response.text();
console.log('Parent call status updated:', data);
} catch (error) {
console.error('Error updating parent call status:', error);
}
}

// Initialize Twilio when the page loads
initializeTwilio(agentId, conductedFrom);

// Make an outgoing call
jQuery(document).on('click', '.phone_dialpad_call_btn', async function () {
const thisElement = jQuery(this);
const dialpadParent = thisElement.closest("div.phone_dialpad_parent");
const countryCode = dialpadParent.find('select.phone_dialpad_countrycode_select_val').val();
const phoneNumber = dialpadParent.find('input.phone_dialpad_number_val').val();

if (!countryCode) {
alert('Select country code');
return;
}
if (!phoneNumber || !phoneNumber.match(/^\+?[1-9]\d{1,14}$/)) {
alert('Please enter a valid phone number');
return;
}

let dialingNumberString = countryCode + phoneNumber;
const token = await fetchToken(agentId, conductedFrom);
if (!token) {
console.log('Failed to fetch token');
return;
}

// Ensure Twilio Device is initialized
if (!twilioDevice) {
await initializeTwilio(agentId, conductedFrom);
if (!twilioDevice) {
console.error('Twilio Device initialization failed');
return;
}
}

try {
// Initiate the call
activeConnection = await twilioDevice.connect({
params: { To: dialingNumberString }
});

updateCallStatus('Calling...');
jQuery('#newCallingStatusModal').modal('show');
jQuery("#newCallingDialerModal").modal('hide');

// Timer starts only when the call is accepted
activeConnection.on('accept', () => {
console.log('Call connected');
updateCallStatus('Call in progress...');
startTimer(); // Start timer only when the call is accepted
// console.log("Full Call Parameters:", JSON.stringify(activeConnection.parameters, null, 2));
if (activeConnection.parameters.CallSid) {
updateParentCallStatus(activeConnection.parameters.CallSid);
}
});

// Handle call disconnection
activeConnection.on('disconnect', () => {
console.log('Call disconnected');
updateCallStatus('Call ended');
stopTimer(); // Stop timer immediately
// console.log("Full Call Parameters:", JSON.stringify(activeConnection.parameters, null, 2));
if (activeConnection.parameters.CallSid) {
updateParentCallStatus(activeConnection.parameters.CallSid);
}
activeConnection = null; // Reset the active connection
jQuery('#newCallingStatusModal').modal('hide'); // Close the modal immediately

});

} catch (error) {
console.error('Twilio Call Error:', error);
updateCallStatus('Call failed: ' + error.message);
stopTimer();
}
});

async function refreshTwilioToken(agentId, conductedFrom) {
console.log('Manually refreshing Twilio token...');
const newToken = await fetchToken(agentId, conductedFrom);
if (newToken && twilioDevice) {
twilioDevice.updateToken(newToken);
console.log('Token refreshed successfully');
} else {
console.error('Failed to refresh Twilio token');
}
}

// Hang up the call
document.getElementById('hangupButton').addEventListener('click', () => {
if (activeConnection) {
activeConnection.disconnect(); // Disconnect the call immediately
activeConnection = null;
}
updateCallStatus('Call ended');
stopTimer();
jQuery('#newCallingStatusModal').modal('hide'); // Close the modal immediately
jQuery('#newCallingIncomingCallModal').modal('hide');
});

// Incoming call modal handling
function showIncomingCallModal(connection) {
activeConnection = connection; // Set active connection

// Show the incoming call modal
jQuery('#newCallingIncomingCallModal').modal('show');
document.getElementById('incomingCallNumber').textContent = activeConnection.parameters.From;

// Accept the call
document.getElementById('acceptCallButton').onclick = () => {
activeConnection.accept();
updateCallStatus('Call in progress...');
jQuery('#newCallingStatusModal').modal('show');
jQuery('#newCallingIncomingCallModal').modal('hide');
startTimer(); // Start timer only when the call is accepted
// console.log("Full Call Parameters:", JSON.stringify(activeConnection.parameters, null, 2));
if (activeConnection.parameters.CallSid) {
updateParentCallStatus(activeConnection.parameters.CallSid, "incoming");
}
};

// Reject the call
document.getElementById('rejectCallButton').onclick = () => {
activeConnection.reject();
jQuery('#newCallingIncomingCallModal').modal('hide');
updateCallStatus('Call rejected');
jQuery('#newCallingStatusModal').modal('hide');
// console.log("Full Call Parameters:", JSON.stringify(activeConnection.parameters, null, 2));
if (activeConnection.parameters.CallSid) {
updateParentCallStatus(activeConnection.parameters.CallSid, "incoming");
}
activeConnection = null; // Reset active connection after rejection
};

// Listen for disconnect on the active connection
activeConnection.on('disconnect', () => {
console.log('Call disconnected');
updateCallStatus('Call ended');
stopTimer();
// console.log("Full Call Parameters:", JSON.stringify(activeConnection.parameters, null, 2));
if (activeConnection.parameters.CallSid) {
updateParentCallStatus(activeConnection.parameters.CallSid, "incoming");
}
activeConnection = null; // Reset active connection
jQuery('#newCallingStatusModal').modal('hide'); // Close call status modal
jQuery('#newCallingIncomingCallModal').modal('hide'); // Close incoming call modal
});
}

// Update call status in the modal
function updateCallStatus(status) {
document.getElementById('callStatus').textContent = status;
}

// Start the call timer
function startTimer() {
callStartTime = Date.now();
timerInterval = setInterval(updateTimer, 1000);
}

// Stop the call timer
function stopTimer() {
clearInterval(timerInterval);
document.getElementById('callTimer').textContent = '00:00';
}

// Update the timer display
function updateTimer() {
const elapsedTime = Math.floor((Date.now() - callStartTime) / 1000);
const minutes = Math.floor(elapsedTime / 60).toString().padStart(2, '0');
const seconds = (elapsedTime % 60).toString().padStart(2, '0');
document.getElementById('callTimer').textContent = `${minutes}:${seconds}`;
}
< /code>
Следующее обработчик вызовов, который обрабатывается Twiml < /p>
// Caller input details from twilio
$toph = $_REQUEST['To']; // 917797809829
$fromph = $_REQUEST['From']; // client:2x13612
$callsid = $_REQUEST['CallSid']; // CAfef253c1b7c1d15bcb1cd7240ce6556c
$callstat = $_REQUEST['CallStatus']; // ringing
$twilioMasterNo = getTwilioMasterInfo($con);

// Twilio call status callback url handling hook file
$statusCallbackUrl = $site_URL . "twilio-current-call-status-callback.php";

$qp = $_REQUEST;
$calldesc = "";
foreach($qp as $key => $val){
$out = $key.' == '.$val;
if ($calldesc == "") {
$calldesc = $out;
} else {
$calldesc = $calldesc . ' && ' . $out;
}
}
if ($twilioMasterNo != "" && $leadid != "") {

?>






Подробнее здесь: https://stackoverflow.com/questions/794 ... erge-calls
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Twilio Browser Hold, Add, Merge Calls
    Anonymous » » в форуме Php
    0 Ответы
    22 Просмотры
    Последнее сообщение Anonymous
  • Как отправить запрос на сообщение в ресурс Calls? (Сделание общительных звонков в Twilio)
    Anonymous » » в форуме Python
    0 Ответы
    7 Просмотры
    Последнее сообщение Anonymous
  • Как отправить запрос на сообщение в ресурс Calls? (Сделание общительных звонков в Twilio)
    Anonymous » » в форуме Python
    0 Ответы
    1 Просмотры
    Последнее сообщение Anonymous
  • В чем разница между request->merge() и request->add() в Laravel
    Anonymous » » в форуме Php
    0 Ответы
    116 Просмотры
    Последнее сообщение Anonymous
  • Является ли установлен `routeId` `yader add add set-cookie`a локально хранящий печенье?
    Anonymous » » в форуме Python
    0 Ответы
    22 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Javascript»