Skip to content

Instantly share code, notes, and snippets.

@SomiDivian
Last active April 13, 2023 19:04
Show Gist options
  • Save SomiDivian/66f657fd6ce46dc09e522d4ef68e14e1 to your computer and use it in GitHub Desktop.
Save SomiDivian/66f657fd6ce46dc09e522d4ef68e14e1 to your computer and use it in GitHub Desktop.
/** πŸ”΄ Twilio console > Twiml App > config */
{
voice_post_request_url: `https://my_url/api/twilio/request-url`
}
/** πŸ”΄ ./device-context.tsx */
type OptionalTwilio = {
device: Device | null;
};
const { Provider: ProviderBase, useValue: useDevice } =
createSimpleContext<OptionalTwilio>("TwilioDevice");
const DeviceProvider = ({ children, token }: { children: React.ReactNode, token: string }) => {
const deviceRef = useRef<Device | null>(null);
useIsomorphicLayoutEffect(() => {
if (!deviceRef.current) {
deviceRef.current = new Device(token, {
logLevel: "debug",
codecPreferences: ["opus", "pcmu"],
});
deviceRef.current.register();
}
}, [deviceRef.current]);
return (
<ProviderBase value={{ device: deviceRef.current }}>
{children}
</ProviderBase>
);
}
export { DeviceProvider, useDevice }
/** πŸ”΄ ./api/twilio/request-url */
import tw from 'twilio'
const action = async (request) => {
const form = new URLSearchParams(await request.text());
const To = form.get('To')
const From = form.get('From')
const inbound = form.get('Direction') === 'inbound'
if (inbound) {
const twiml = new tw.twiml.VoiceResponse();
const dial = _twiml.dial(
{
answerOnBridge: true,
callerId: From!,
},
- To!
+ // To!
);
dial.number(To!);
return xml(twiml.toString(), {
status: 200,
});
}
return json({})
}
/** πŸ”΄ Component */
const Demo = () => {
const { device } = useDevice()
const [ currentCall, setCurrentCall ] = useState<Call | null>(null)
const [ callStatus, setCallStatus ] = useState<CallStatus | 'idle'>('idle')
useIsomorphicLayoutEffect(() => {
if (!currentCall) return;
currentCall?.on("accept", () => {
console.log("πŸ’‘ accept");
setCallStatus("open");
});
currentCall?.on("cancel", () => {
console.log("πŸ’‘ cancel");
setCurrentCall(null);
setCallStatus("closed");
});
currentCall?.on("disconnect", (e) => {
console.log("πŸ’‘ disconnect");
setCurrentCall(null);
setCallStatus("closed");
});
currentCall?.on("error", () => {
console.log("πŸ’‘ error")
setCurrentCall(null)
});
currentCall?.on("reconnected", () => {
console.log("πŸ’‘ reconnected");
setCallStatus("open");
});
currentCall?.on("reconnecting", () => {
console.log("πŸ’‘ reconnecting");
setCallStatus("reconnecting");
});
currentCall?.on("reject", () => {
console.log("πŸ’‘ reject");
setCurrentCall(null);
setCallStatus("closed");
});
}, [currentCall])
const call = async () => {
if (!device) throw new Error('❌ No device initialized')
const response = await device.connect({
params: {
+ From: `${my_twilio_phone_number}`,
To: `${my_local_phone_number}`,
receiverName: 'Test'
}
})
setCurrentCall(response)
}
return (
<div>
<button onClick={call} disabled={!device || !!currentCall}> --Call Now-- </button>
</div>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment