I am using Vue as my frontend. I am looking to integrate with Twilio’s Voice SDK to place outgoing calls and receiving incoming calls. I have setup my TwilML app, etc. and the plumbing of my token from my backend to the frontend. I am able to place a call to a hardcoded number, I hear a ringtone, browser asks for microphone permissions, but afterwards it instantaneously hangs up. I noticed the thread here:Twilio JS client hanging up immediately
I followed several of the answers, but to no avail.
Here is my current code:
Twilio Component (.vue):
<template>
<div class="twilio-call">
<button @click="makeCall" :disabled="isCalling">
{{ isCalling ? "Calling..." : "Call" }}
</button>
</div>
</template>
<script>
import * as messagingApi from "../../../api/messaging.js";
import * as twilioVoiceSDK from "../../../utils/twilio.js"
export default {
name: "TwilioCall",
data() {
return {
twilioToken:
"",
toNumber: "+1HardcodedNumber",
isCalling: false,
};
},
methods: {
async makeCall() {
this.twilioToken = await messagingApi.getTwilioToken();
if (this.isCalling) return;
try {
this.isCalling = true;
// Initialize Twilio Device
if (!twilioVoiceSDK.getDevice()) {
twilioVoiceSDK.createDevice(this.twilioToken);
// Handle error events
twilioVoiceSDK.getDevice().on("error", (error) => {
console.error("Twilio Error:", error);
this.isCalling = false;
});
}
// Register the Twilio device
await twilioVoiceSDK.getDevice().register();
// Make a call to the hardcoded number
const callParams = { To: this.toNumber };
const call = await twilioVoiceSDK.getDevice().connect(callParams);
// Handle disconnect event
call.on("disconnect", () => {
this.isCalling = false;
console.log("Call disconnected");
});
// Add event listeners to capture detailed logs
twilioVoiceSDK.getDevice().on("ready", () =>
console.log("Twilio Device is ready.")
);
twilioVoiceSDK.getDevice().on("error", (error) =>
console.error("Twilio Device Error:", error)
);
twilioVoiceSDK.getDevice().on("connect", (conn) =>
console.log("Twilio Connection established:", conn)
);
twilioVoiceSDK.getDevice().on("disconnect", (conn) =>
console.log("Twilio Connection disconnected:", conn)
);
twilioVoiceSDK.getDevice().on("incoming", (conn) =>
console.log("Incoming call:", conn)
);
console.log("Calling:", this.toNumber);
} catch (error) {
console.error("Error making call:", error);
this.isCalling = false;
}
},
},
};
</script>
<style scoped>
.twilio-call {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
button:disabled {
cursor: not-allowed;
opacity: 0.5;
}
</style>
Twilio.js in utils
import { Device } from '@twilio/voice-sdk';
/**
* Do NOT bind this object in Vue. Vue wraps proxies around it and that causes issues.
*
* @type { import('@twilio/voice-sdk').Device }
*/
let device = null;
/**
* @param {String} token
* @returns {Device}
*/
export function createDevice(token) {
return device = new Device(token, {
// See https://www.twilio.com/docs/voice/sdks/javascript/twiliodevice#deviceoptions
logLevel: 0,
// Set Opus as our preferred codec. Opus generally performs better, requiring less bandwidth and
// providing better audio quality in restrained network conditions.
codecPreferences: ['opus', 'pcmu'],
});
}
/**
* @returns { import('@twilio/voice-sdk').Device }
*/
export function getDevice() {
return device;
}
Any help would be greatly appreciated!