Scroll Top

The Power of Magic Phone Numbers in Broadcasting Messages for Larger PSTN Chime Meetings

Feature Image 2

Introduction to AWS Chime PSTN

In the ever-evolving landscape of cloud communications, AWS Chime PSTN stands out as a powerful tool for developers looking to create custom voice applications.

AWS Chime PSTN, where PSTN stands for Public Switched Telephone Network, is a service that bridges the gap between traditional phone systems and modern cloud-based communication solutions. It’s a key component of the larger AWS Chime SDK, Amazon’s suite of real-time communication tools. With AWS Chime PSTN, developers can build sophisticated voice applications that integrate seamlessly with existing telephone infrastructure.

 

AWS Chime PSTN
AWS Chime PSTN

Broadcasting challenges

When managing large-scale audio conferences with AWS Chime PSTN, one common requirement is the ability to broadcast messages to all participants simultaneously. For instance, you might need to announce that recording has started or provide important information to everyone on the call. While AWS Chime PSTN provides robust capabilities for audio conferencing, the standard methods for broadcasting have limitations, especially for large conferences or meetings with replicas. These can include up to 10,250 participants, comprising 40 replicas and 1 primary meeting, with each replica accommodating 250 participants.

 

Brodcasting messages in typical chime meeting with replicas
Broadcasting messages in typical chime meeting with replicas

The Standard Approach and its Limitations

The conventional method for broadcasting messages involves sending and executing the Speak action for each participant individually. Here’s why this approach is problematic:

  1. Scalability Issues: An audio conference can host up to 10,000 participants. Using individual Speak actions would require invoking the SMA Handler Lambda function 10,000 times—once for each participant.
  2. Performance Bottleneck: This approach is incredibly slow and resource-intensive, leading to noticeable delays and potential degradation of the conference experience.
  3. Cost Implications: Excessive Lambda invocations can result in higher costs and possible throttling. Each Speak action performed by Chime can increase the overall expense.

On average, it takes about 5–6 seconds for all participants to hear the broadcast message. For instance, when announcing that recording has started, the last participant may hear the message after a delay of up to 15-20 seconds. 

Introducing the powerful magic phone number solution 

To overcome these limitations, AWS has implemented an undocumented yet effective solution: the magic phone number. This method offers a more efficient way to broadcast messages to all conference participants simultaneously.

What is the magic phone number?

Use the magic phone number (+17035550122) to seamlessly integrate an Amazon Chime SDK meeting with Amazon Chime PSTN Audio. It acts as a bridge between your SIP Media Application and the entire conference.

How the magic phone number works:

  1. Outbound Call to magic phone number: Instead of calling each participant, you make a single outbound call from your AWS registered phone number to the magic phone number.
  2. Joining the Conference: The call to the magic phone number effectively joins the primary chime meeting as a special participant.
  3. Broadcasting: When you play audio or use the Speak action to this magic phone number attendee, the message is broadcast to all participants in the conference simultaneously with a single invocation of lambda and with a single speak action.

Implementing the magic phone number technique

Here’s how to implement this solution:

  • Prepare for the outbound call: Establish an outbound call to the magic phone number using specific SIP headers.
import {
  ChimeSDKVoiceClient
  CreateSipMediaApplicationCallCommand,
  CreateSipMediaApplicationCallCommandInput,
  BadRequestException,
} from "@aws-sdk/client-chime-sdk-voice";
const speakMessage = "Recording started!"
const MAGIC_NUMBER = "+17035550122"
const createSipMediaApplicationCallArguments: CreateSipMediaApplicationCallCommandInput = {
  FromPhoneNumber: bridgePhoneNumber, // AWS provisioned number
  ToPhoneNumber: MAGIC_NUMBER, // +17035550122
  SipMediaApplicationId: SIP_MEDIA_APPLICATION_ID, // the SMA Id
  SipHeaders: {
    "X-chime-join-token": chimeMeetingToken, // Chime Meeting join token
    "X-chime-meeting-id": chimeMeetingId, // MeetingId of the meeting where we need to broadcast messages
  },
  ArgumentsMap: {
    speakMessage: speakMessage,
  },
};

 

  • Initiate the call: To create the SIP Media Application call, use the AWS Chime Voice SDK:
const chimeSDKVoice = new ChimeSDKVoiceClient({region: "us-east-1"});

async createSipMediaApplicationCall(
    createSipMediaApplicationCallArguments: CreateSipMediaApplicationCallCommandInput
  ) {
    const callCreateRequestResponse = await chimeSDKVoice
      .send(
        new CreateSipMediaApplicationCallCommand(
          createSipMediaApplicationCallArguments
        )
      )
      .then((res) => {
        logger.info(
          "SIP media application call create request response: ",
          JSON.stringify(res)
        );
        return res;
      })
      .catch((err) => {
        logger.info(
          "Error: SIP media application call create request: ",
          JSON.stringify(err)
        );

        if (err instanceof BadRequestException) {
          throw new Error({
            errorCode: ERROR_CODES.INVALID_PHONE_NUMBER,
            errorMessage: err?.message,
            errorType: ERROR_TYPES.BUSINESS_EXCEPTION,
            statusCode: HTTP_STATUS_CODES.BAD_REQUEST,
          });
        } else {
          throw err;
        }
      });
    return callCreateRequestResponse;
  }
}
// triggers an outbound call to magic phone number from AWS provisioned number
await createSipMediaApplicationCall(createSipMediaApplicationCallArguments)

 

  • Handle the Response: After initiating an outbound call, the SMA receives an event and forwards it to a Lambda function (SMA handler) for the subsequent actions. Once we successfully answer the call, we aim to save the message or announcement using the magic phone number. In order to store this message or announcement, we use transaction attributes, which persist throughout the call unless modified.
async handleOutboundCall(
  event: any
) {
  const outBoundCallArguments =
    event?.ActionData?.Parameters?.Arguments;
  
  if(outBoundCallArguments.speakMessage)
    transactionAttributes = {
      speakMessage: outBoundCallArguments.speakMessage
    };
    
  actions = [] 
  return {
    SchemaVersion: '1.0',
    Actions: actions,
    TransactionAttributes: transactionAttributes,
  };
}
  • Broadcast the Message: Let’s manage the CALL_ANSWERED success event and use the Speak and Hang Up actions to broadcast the message or announcement.
function getSpeakAction(
  text: string,
  callId: string,
  textType = "text",
  engine = "neural",
  voiceId = "Ruth"
) {
  return {
    Type: ACTION_TYPES.SPEAK,
    Parameters: {
      Text: text, // required
      CallId: callId, // required
      Engine: engine, // optional. Defaults to standard
      LanguageCode: "en-US", // optional
      TextType: textType, // optional
      VoiceId: voiceId, // optional. Defaults to Joanna
    },
  };
}

const hangupAction = {
  Type: ACTION_TYPES.HANGUP,
  Parameters: {
    SipResponseCode: "0",
    CallId: "call-id-1",
    ParticipantTag: LEGS.LEG_A,
  },
};

function speakAndHangUp(speakText: string, callId: string) {
  const speakAction = getSpeakAction(speakText, callId);
  hangupAction.Parameters.CallId = callId;
  hangupAction.Parameters.ParticipantTag = LEGS.LEG_A;
  return [speakAction, hangupAction];
}

// Handles CALL_ANSWERED Action success event
async handlePlayAudioAction(
  event: any
) {

  const legAParticipant = event.CallDetails.Participants.find(
    (participant) => participant.ParticipantTag === "LEG-A"
  );

  const legBParticipant = event.CallDetails.Participants.find(
    (participant) => participant.ParticipantTag === "LEG-B"
  );
  
  actions = []
  const transactionAttributes = event?.CallDetails?.TransactionAttributes;
  if(transactionAttributes && transactionAttributes.speakMessage){
    const speakMessage = transactionAttributes.speakMessage
    actions = speakAndHangUp(speakMessage, legAParticipant.CallId)
  }
    
    
  return {
    SchemaVersion: '1.0',
    Actions: actions,
    TransactionAttributes: transactionAttributes,
  };
}

After executing the speak action, we end the outbound call to prevent using the magic phone number during the meeting, as this could incur costs based on the duration of the meeting.

Sequence diagram:
Magic Phone Number Sequence Diagram
Magic Phone Number Sequence Diagram

Key Advantages of the Magic Phone Number Approach:

  1. Efficiency: Broadcasts to all participants with a single action.
  2. Scalability: Works equally well for small and large conferences.
  3. Performance: Significantly faster than individual participant messaging.
  4. Cost-Effective: Reduces the number of Lambda invocations and associated costs.

 Important Notes

  • Although AWS has not officially documented this technique, their team has confirmed it.
  • There is no way to modify or customize the Magic phone number.
  • AWS guarantees the stability of this number due to its widespread use by numerous clients.

The Magic phone number technique in AWS Chime PSTN offers a powerful solution for broadcasting messages in large-scale audio conferences. By leveraging this method, developers can create more efficient and responsive conferencing applications, enhancing the overall user experience while optimizing resource usage. 

References

GitHub — aws-samples/amazon-chime-sdk-click-to-call

Using the Amazon Chime SDK PSTN Audio service — Amazon Chime SDK

 

 

 

Sai Pratap Kondreddy

+ posts

Vigneswaran Balasubramanian

+ posts