Search code examples
node.jstwiliotwilio-api

Using the Twilio API, how can I check if a number is in use by a service?


I am trying to create a new messaging service using the Node.js twilio sdk. To do so, I have devised the following workflow.

I've created a new service like so.

client.messaging.v1.services.create({
    friendlyName: 'test service,
    inboundRequestUrl: 'https://someUrl.com',
    inboundMethod: 'POST',
    usecase: 'discussion'
})

I list all the numbers I own like so:

client.incomingPhoneNumbers.list()

I assign a number to my service like so (where the serviceSid is the sid of the service created in step 1 and the phoneNumberSid is the sid of one of phone numbers returned in step 2):

client.messaging.v1.services(<serviceSid>)
    .phoneNumbers
    .create({ phoneNumberSid: <phoneNumberSid> })

I am happy with this workflow, with the exception of one problem. You cannot assign the same number to two different messaging services, so I need to make sure the phone number whose sid I pass into step 3, doesn't already have a service. The problem is that the response I get back from step 2 doesn't tell me whether the numbers are used by another service.

All of this to say, can anyone suggest some way to modify this workflow to be more robust? Ideally, is there some way I can tell from step 2 whether or not a number is already being used by a service, so I know not to pass it in to step 3?

Thanks


Solution

  • Yes, there is a way to do this. To be honest, it's not very nice, but you can iterate over all messages services and test if your phone number (SID) belongs to a mapping of one of the services and then remove this mapping. Once removed, you can assign the phone number to any other messaging service.

    async function unbindPhoneFromMessagingServices(phoneNumberSid) {
      const allServices = await client.messaging.v1.services.list();
      await Promise.all(
        allServices.map(async (service) => {
          const mapping = client.messaging.v1
            .services(service.sid)
            .phoneNumbers(phoneNumberSid);
          try {
            await mapping.fetch();
          } catch (e) {
            const RESOURCE_NOT_FOUND = e.code === 20404;
            if (RESOURCE_NOT_FOUND) {
              return;
            }
            throw e;
          }
          await mapping.remove();
          console.log(
            `The phone number was decoupled from messaging service ${service.sid}.`
          );
        })
      );
    }
    

    PS: This snippet is taken from one of my repositories. Feel free to check out the complete code on GitHub.