baronbrn
baronbrn

Reputation: 119

Twilio Symfony - The controller must return a \"Symfony\\Component\\HttpFoundation\\Response\" but returned Twilio\\TwiML\\VoiceResponse."

I want to implement Twilio browser to browser call with Symfony5 and ApiPlatform

I'm following this tuto:

https://www.twilio.com/docs/voice/client/tutorials/calls-between-devices?code-sample=code-generate-twiml-from-client-parameters-3&code-language=PHP&code-sdk-version=5.x

I have this function, that's the one I want my TwiML app to be configured on

    /**
     * @Route("/twilio/handle/twiml/{clientId}", name="twilio_handl_twiml")
     * @param $clientId
     * @return VoiceResponse
     */
    public function handleTwiml($clientId): VoiceResponse
    {
        /** @var Client $client */
        $client = $this->clientRepository->findOneBy(['id' => 11]);
        $to = $client->getUser()->getLastName().$client->getUser()->getId();


        $voiceResponse = new VoiceResponse();
        $number = htmlspecialchars($to);
        $dial = $voiceResponse->dial(null, array('callerId' => '+15017122661'));

        if (isset($to)) {
            if (preg_match("/^[\d\+\-\(\) ]+$/", $number)) {
                $dial->number($number);
            } else {
                $dial->client($number);
            }
        } else {
            $voiceResponse->say('There has been an issue. Thanks for calling!');
        }

        return $voiceResponse;
    }

And I've declared it as a custom route on one of my entities in the "get" section:


 *          "twilio_handl_twiml"={
 *            "path"="/twilio/handle/twiml/{clientId}",
 *            "controller"="TwilioController:class"
 *          },

Now the function creates a proper VoiceResponse object

But when I call this route I get the following error message:

The controller must return a "Symfony\Component\HttpFoundation\Response" object but it returned an object of type Twilio\TwiML\VoiceResponse.

Now does anyone know why I couldn't return whatever kind of Response I want from a custom route ?

I don't really see why the framework would declare this as an error

If anyone can help me understand better this error I'd appreciate it

Thanks!

Upvotes: 1

Views: 548

Answers (1)

philnash
philnash

Reputation: 73057

Twilio developer evangelist here.

As @Cerad has said in the comments, you need to respond with an object derived from the Symfony Response object.

I haven't used Symfony, so please excuse me if this is wrong, but I think you can update your handler to the following, it might work:

    use Symfony\Component\HttpFoundation\Response;

    /**
     * @Route("/twilio/handle/twiml/{clientId}", name="twilio_handl_twiml")
     * @param $clientId
     * @return Response
     */
    public function handleTwiml($clientId): VoiceResponse
    {
        /** @var Client $client */
        $client = $this->clientRepository->findOneBy(['id' => 11]);
        $to = $client->getUser()->getLastName().$client->getUser()->getId();


        $voiceResponse = new VoiceResponse();
        $number = htmlspecialchars($to);
        $dial = $voiceResponse->dial(null, array('callerId' => '+15017122661'));

        if (isset($to)) {
            if (preg_match("/^[\d\+\-\(\) ]+$/", $number)) {
                $dial->number($number);
            } else {
                $dial->client($number);
            }
        } else {
            $voiceResponse->say('There has been an issue. Thanks for calling!');
        }
        
        $response = new Response(
            $voiceResponse->asXML(),
            Response::HTTP_OK,
            ['content-type' => 'application/xml']
        );

        return $response;
    }

The key here is to build up the Symfony response with the content of the voice response ($voiceResponse->asXML()) and also set the content type to application/xml.

Upvotes: 2

Related Questions