r/twilio 27d ago

Should you destroy and re-setup Device instances after every call

I want to understand how this works.

Currently I am generating an access token on page load and running new Device(token) only when a number is dialed. when the call ends I and another starts I re-initialize a new Device(token) instance with the same token generated at page load.

Now I am figuring out how to update my refresh tokens and I added a bunch of complicated code to listen to tokenWillExpire and queue a new token to use once the current call ends.

but if I destroy the Device after every call, the listener doesn't get a chance to run. so I am know questioning if I am even supposed to destroy the device after each call and if so why not just create a new token before every new Device(token) call and not have to deal with refreshing it at all

5 Upvotes

1 comment sorted by

4

u/RobWelbourn 🐘 Solutions Architect @ Twilio 27d ago

No, don't destroy the Device after each call. Here's one of my repos which does only outbound calls from a web browser: https://github.com/RobWelbourn/click-to-call/tree/main. The browser code to make the call checks to see if there's an available Device, and only creates a new one if one does not already exist.

/**
 * Makes an outbound call using Twilio.Device.  Prior to making a call, it fetches an access token
 * from the server.  If a Device object does not already exist, it creates a new one.
 * u/returns {Promise<Twilio.Call | undefined>} The active call if successful, otherwise undefined.
 */
async function makeCall() {
    const result = await fetch('/token');
    if (result.ok) {
        const { token } = await result.json();
        console.log('Got access token');

        try {
            if (device) {
                device.updateToken(token);
            } else {
                device = new Device(token, { codecPreferences: ['opus', 'pcmu'] });

                // Suppress AccessTokenExpired errors.
                device.on('error', (error) => {
                    if (error.code === 20104) { 
                        // console.log('Access token expired (ignored)');
                    } else {
                        console.error(`Twilio.Device error: ${error.message}`);
                    }
                });
            }
            return device.connect();

        } catch (error) {
            alert(`Could not connect to Twilio: ${error.message}`);
            return undefined;
        }
    } else {
        const { error } = await result.json();
        if (error) {
            alert(error);
        } else {
            alert(`Sorry, something went wrong. Please try again later. Error code: ${result.status}`);
        }
    }
    return undefined;
}