'HTTP retrieval failure when creating drop-in audio chat using Twilio

I am leveraging the Twilio Programmable Voice API to create a drop in audio chat room when a user completes a signup form.

I am using ngrok to listen to both my React frontend app and Django backend app so I can expose my local server to the internet.

However, when I complete the form, I get the prompt to activate my mic and then hear the error Sorry, an application error has occurred, goodbye before my call drops. My Twilio error logs shows the error:

Error - 11200
An attempt to retrieve content from https://f5b7-104-182-176-156.ngrok.io/voice_chat/rooms/Emmanuel returned the HTTP status code 404
HTTP retrieval failure

Possible Causes
Web server returned a 4xx or 5xx HTTP response to Twilio
Misconfigured Web Server
Network disruptions between Twilio and your web server
No Content-Type header attached to response
Content-Type doesn't match actual content, e.g. an MP3 file that is being served with Content-Type: audio/x-wav, instead of Content-Type: audio/mpeg

When I do a GET on an endpoint that should show me all my rooms http://127.0.0.1:8000/voice_chat/rooms I get an empty list, indicating that no rooms have been created?

Here is my React code:

...
const NewRoom = () => {
    const [state, setState] = useGlobalState();
    const history = useHistory();
    const updateRoomName = (createdRoomTopic) => {
        setState({...state, createdRoomTopic});
    };

    const createRoomHandler = () => {
        const userData = {'roomName': state.nickname, 'participantLabel': state.createdRoomTopic}
        console.log('Inside create room handler', userData.roomName, userData.participantLabel)
        axios.post('http://127.0.0.1:8000/voice_chat/rooms/', userData )
            .then(res => {
                console.log('axios call has been hit', res.data)
            })
    }

    const handleRoomCreate = () => {
        const selectedRoom = {
            room_name: state.createdRoomTopic, participants: []
        };
        const rooms = state.rooms;
        const roomId = rooms.push(selectedRoom);
        setState({...state, rooms });
        setState({...state, selectedRoom});
        createRoomHandler()
        history.push(`/rooms/${roomId}`);
    };

    return (
        <div>
            <input
                placeholder="Enter room topic..."
                onChange={ e => updateRoomName(e.target.value)}
            />
            <button onClick={handleRoomCreate}>
                Start room</button>
        </div>
    );
};

my urls.py:

urlpatterns = [
    path("rooms", RoomView.as_view(), name="room_list"),
    path("token/<username>", TokenView.as_view(), name="rooms"),
]

and my RoomView:

@method_decorator(csrf_exempt, name="dispatch")
class RoomView(View):
    def get(self, request, *args, **kwargs):
        rooms = client.conferences.stream(
            status="in-progress"
        )
        rooms_reps = [
            {
                "room_name": conference.friendly_name,
                "sid": conference.sid,
                "participants": [
                    p.label for p in conference.participants.list()
                ],
                "status": conference.status,
            } for conference in rooms]
        return JsonResponse({"rooms": rooms_reps})

    def post(self, request, *args, **kwargs):
        room_name = request.POST.get("roomName", "default")
        participant_label = request.POST.get("participantLabel","default")
        response = VoiceResponse()
        dial = Dial()
        dial.conference(
            name=room_name,
            participant_label=participant_label,
            start_conference_on_enter=True,
        )
        print(dial)
        response.append(dial)
        return HttpResponse(response.to_xml(), content_type="text/xml")

Would appreciate any help



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source