Open 6Hat opened 5 years ago
Can you say how to repeat this issue? I have started using the repo and don't have this issue. This is what I trimmed quickstart.js
down to:
$(function () {
var device;
console.log('requesting capability token...');
$.getJSON('twilio/token')
.then(function (data) {
console.log('capability token success')
device = new Twilio.Device(data.token);
device.on('ready',function (device) {
console.log('device.on ready')
$('#call-controls, #button-call').show();
});
device.on('error', function (error) {
console.log('device.on error: ' + error.message);
});
device.on('connect', function (conn) {
console.log('device.on connect');
var twilio_call_sid = conn.parameters.CallSid;
$('#call-id').val(twilio_call_sid);
log_call_to_database(twilio_call_sid, 'connect');
$('#button-call').hide();
$('#button-hangup, #button-hold, #button-record-start').show();
// volumeIndicators.style.display = 'block';
// bindVolumeIndicators(conn);
});
device.on('disconnect', function (conn) {
console.log('device.on disconnect');
$('#call-id').val(conn.parameters.CallSid);
$('#button-call').show();
$('#button-hangup, [id*="button-record-"]').hide();
//volumeIndicators.style.display = 'none';
});
device.on('incoming', function (conn) {
console.log('device.on incoming');
var twilio_call_sid = conn.parameters.CallSid;
$('#call-id').val(twilio_call_sid);
$('#button-call').hide();
$('#button-answer').show();
var blocked_number = '+12345678910';
if (conn.parameters.From === blocked_number) {
// conn.reject();
// save_call(twilio_call_sid,'auto-rejected');
// console.log('Blocked number. Call rejected.');
} else {
conn.on('accept', function() {
console.log('device.on accept');
$('#button-answer').hide();
$('#button-hangup, #button-hold, #button-record-start').show();
log_call_to_database(twilio_call_sid, 'accepted');
});
$('#button-answer').on('click', function () {
conn.accept();
});
}
});
//...
// etc
I will sift through your code and look for any changes that may resolve this issue... I am really hopefully as I am developing an app for our corporate office and I really need this to be solid. For now here is my quickstart which is really not altered:
$(function () {
var speakerDevices = document.getElementById('speaker-devices');
var ringtoneDevices = document.getElementById('ringtone-devices');
var outputVolumeBar = document.getElementById('output-volume');
var inputVolumeBar = document.getElementById('input-volume');
var volumeIndicators = document.getElementById('volume-indicators');
var device;
log('Requesting Capability Token...');
$.getJSON('/Comm/TwilioToken')
.then(function (data) {
log('Got a token.');
console.log('Token: ' + data.token);
// Setup Twilio.Device
device = new Twilio.Device(data.token);
device.on('ready',function (device) {
log('Twilio.Device Ready!');
document.getElementById('call-controls').style.display = 'block';
});
device.on('error', function (error) {
log('Twilio.Device Error: ' + error.message);
});
device.on('connect', function (conn) {
log('Successfully established call!');
document.getElementById('button-call').style.display = 'none';
document.getElementById('button-hangup').style.display = 'inline';
volumeIndicators.style.display = 'block';
bindVolumeIndicators(conn);
});
device.on('disconnect', function (conn) {
log('Call ended.');
document.getElementById('button-call').style.display = 'inline';
document.getElementById('button-hangup').style.display = 'none';
volumeIndicators.style.display = 'none';
});
device.on('incoming', function (conn) {
log('Incoming connection from ' + conn.parameters.From);
var archEnemyPhoneNumber = '+12093373517';
if (conn.parameters.From === archEnemyPhoneNumber) {
conn.reject();
log('It\'s your nemesis. Rejected call.');
} else {
// accept the incoming connection and start two-way audio
log('Incoming connection from ' + conn.parameters.From);
conn.accept();
}
});
setClientNameUI(data.identity);
device.audio.on('deviceChange', updateAllDevices.bind(device));
// Show audio selection UI if it is supported by the browser.
if (device.audio.isOutputSelectionSupported) {
document.getElementById('output-selection').style.display = 'block';
}
})
.catch(function (err) {
console.log(err);
log('Could not get a token from server!');
});
// Bind button to make call
document.getElementById('button-call').onclick = function () {
// get the phone number to connect the call to
var params = {
To: document.getElementById('phone-number').value
};
console.log('Calling ' + params.To + '...');
if (device) {
device.connect(params);
}
};
// Bind button to hangup call
document.getElementById('button-hangup').onclick = function () {
log('Hanging up...');
if (device) {
device.disconnectAll();
}
};
document.getElementById('get-devices').onclick = function () {
navigator.mediaDevices.getUserMedia({ audio: true })
.then(updateAllDevices.bind(device));
};
speakerDevices.addEventListener('change', function() {
var selectedDevices = [].slice.call(speakerDevices.children)
.filter(function(node) { return node.selected; })
.map(function(node) { return node.getAttribute('data-id'); });
device.audio.speakerDevices.set(selectedDevices);
});
ringtoneDevices.addEventListener('change', function() {
var selectedDevices = [].slice.call(ringtoneDevices.children)
.filter(function(node) { return node.selected; })
.map(function(node) { return node.getAttribute('data-id'); });
device.audio.ringtoneDevices.set(selectedDevices);
});
function bindVolumeIndicators(connection) {
connection.on('volume', function(inputVolume, outputVolume) {
var inputColor = 'red';
if (inputVolume < .50) {
inputColor = 'green';
} else if (inputVolume < .75) {
inputColor = 'yellow';
}
inputVolumeBar.style.width = Math.floor(inputVolume * 300) + 'px';
inputVolumeBar.style.background = inputColor;
var outputColor = 'red';
if (outputVolume < .50) {
outputColor = 'green';
} else if (outputVolume < .75) {
outputColor = 'yellow';
}
outputVolumeBar.style.width = Math.floor(outputVolume * 300) + 'px';
outputVolumeBar.style.background = outputColor;
});
}
function updateAllDevices() {
updateDevices(speakerDevices, device.audio.speakerDevices.get());
updateDevices(ringtoneDevices, device.audio.ringtoneDevices.get());
// updateDevices(speakerDevices, );
// updateDevices(ringtoneDevices, device);
}
// Update the available ringtone and speaker devices
function updateDevices(selectEl, selectedDevices) {
selectEl.innerHTML = '';
device.audio.availableOutputDevices.forEach(function(device, id) {
var isActive = (selectedDevices.size === 0 && id === 'default');
selectedDevices.forEach(function(device) {
if (device.deviceId === id) { isActive = true; }
});
var option = document.createElement('option');
option.label = device.label;
option.setAttribute('data-id', id);
if (isActive) {
option.setAttribute('selected', 'selected');
}
selectEl.appendChild(option);
});
}
// Activity log
function log(message) {
var logDiv = document.getElementById('log');
logDiv.innerHTML += '<p>> ' + message + '</p>';
logDiv.scrollTop = logDiv.scrollHeight;
}
// Set the client name in the UI
function setClientNameUI(clientName) {
var div = document.getElementById('client-name');
div.innerHTML = 'Your client name: <strong>' + clientName +
'</strong>';
}
});
Here's the difference:
Under device.on('incoming', function (conn) { ...
you directly have conn.accept();
which accepts the call automatically when an incoming call is detected.
I have this as conn.on('accept', function() { ...
to trigger some actions when conn.accept();
is called, like so...:
conn.on('accept', function() {
console.log('device.on accept');
$('#button-answer').hide();
$('#button-hangup, #button-hold, #button-record-start').show();
log_call_to_database(twilio_call_sid, 'accepted');
});
... and then, most importantly for you, have conn.accept();
wrapped in a jQuery on click
function so that it only gets called when the user clicks the answer button, like so:
$('#button-answer').on('click', function () {
conn.accept();
});
Cannot thank you enough! I was thinking I had to switch from Client to Desktop... this really saved me. Appreciate your time!!!
Please can you share your code . @6Hat ?
Is there any event to find out if the user attend the call . I want to start a timer (call duration) when user pick a call.
Try something like this?
$('#button-answer').on('click', function () {
conn.accept();
functionThatStartsATimer()
});
@forrestedw yeah but this is for incoming calls. I'm talking about outbound calls.
@forrestedw yeah but this is for incoming calls. I'm talking about outbound calls.
device.on('connect', function (conn) { log('Successfully established call!'); functionThatStartsATimer(); });
In Google Chrome the inbound call only "rings" on occasions... but usually it just Answers automatically! In both Chrome and Edge there is no way to "Answer" the call? Outbound calls work great!