Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rajneeshksoni/a0ec1b2f61f2866a5a1f9cc030c2a79b to your computer and use it in GitHub Desktop.
Save rajneeshksoni/a0ec1b2f61f2866a5a1f9cc030c2a79b to your computer and use it in GitHub Desktop.
twili-daily-pstn-sip-both-way
import twilio from "twilio";
const accountSid = "ACCOUNT_SID";
const authToken = "AUTH_TOKEN";
async function wait(second) {
return new Promise((resolve) => {
setTimeout(resolve, second * 1000);
});
}
async function callSipThenPstn(event) {
const client = twilio(accountSid, authToken);
const twimlRes = `
<Response>
<Dial callerId=CALLER_ID_NUMBER>${event.phoneNumber}</Dial>
</Response>`;
// First dial sip with retry
let sipResp;
let try_count = 0;
while (true) {
try_count++;
sipResp = await client.calls.create({
twiml: twimlRes,
method: "POST",
to: event.sipUri,
from: CALLER_ID_NUMBER,
});
console.log(`sipResp.sid: ${sipResp.sid} status: ${sipResp.status}`);
// wait for 10 second
await wait(10);
let resp = await client.calls(sipResp.sid).fetch();
console.log(`sip call status after 10 sec wait: status: ${resp.status}`);
if (
resp.status == "in-progress" ||
resp.status == "completed" ||
resp.status == "canceled"
) {
return { sid: resp.sid, status: resp.status, try_count: try_count };
} else {
// close the current call and re-dial
await client.calls(sipResp.sid).update({ status: "completed" });
if (try_count >= 3) {
return { status: "call-failed", try_count: try_count };
}
}
}
}
async function callPstnThenSip(event) {
const client = twilio(accountSid, authToken);
// twilio twiml rquired & to be replaced with &amp;
let sipUri = event.sipUri.replaceAll("&", "&amp;");
console.log("final sipURI: " + sipUri);
const twimlRes = `
<Response>
<Dial><Sip>${sipUri}</Sip></Dial>
</Response>`;
// First dial PSTN
let pstnResp;
pstnResp = await client.calls.create({
twiml: twimlRes,
method: "POST",
to: event.phoneNumber,
from: CALLER_ID_NUMBER,
});
console.log(`pstnResp.sid: ${pstnResp.sid} status: ${pstnResp.status}`);
// wait for 10 second
await wait(10);
let resp = await client.calls(pstnResp.sid).fetch();
return { sid: resp.sid, status: resp.status, try_count: 1 };
}
export const handler = async (event) => {
let body;
try {
body = JSON.parse(event.body);
console.log(body);
console.log("-------");
if (body.sipUri && body.phoneNumber) {
let resp;
if (body.dialPstnFirst) {
resp = await callPstnThenSip(body);
} else {
resp = await callSipThenPstn(body);
}
const response = {
statusCode: 200,
body: JSON.stringify(resp),
};
return response;
} else {
const response = {
statusCode: 400,
body: JSON.stringify(
`call with {sipUri: "sip:...", phoneNumber: "+157373"} }`
),
};
return response;
}
} catch (e) {
console.log("failed with error:", e);
return {
statusCode: 400,
body: e.message,
};
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment