OutboundCallWebHookController.php 5.33 KB
<?php

namespace NexmoBundle\Controller;

use AppBundle\Controller\SpokeControllerTrait;
use AppBundle\Entity\User;
use AppBundle\Entity\VoiceCall;
use AppBundle\Event\VoiceCallEvent;
use AppBundle\Event\VoiceCallEvents;
use CobrandBundle\CobrandInstance;
use Doctrine\ORM\ORMException;
use FOS\RestBundle\Controller\Annotations\Get;
use FOS\RestBundle\Controller\Annotations\Post;

use NexmoBundle\VoiceCall\VoiceCallOrigins;
use NexmoBundle\VoiceCall\VoiceCallStatus;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class OutboundCallWebHookController extends NexmoWebHookController
{
    /**
     * @Post("/event-url", name="event_webhook")
     *
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     */
    public function postEventAction(Request $request)
    {
        $uuid = $request->get("uuid");
        $voiceCall = $this->getDoctrine()->getRepository("AppBundle:VoiceCall")->findOneBy([
            "uuid"  => $uuid
        ]);

        if (!$voiceCall instanceof VoiceCall) {
            return $this->jsonResponse(["success" => false], Response::HTTP_OK);
        }

        $delegates = [];
        $requestMap = [
            "status" => function ($val) use ($voiceCall, &$delegates) {
                $voiceCall->setStatus($val);
                // add delegate for changing statuses
                $delegates[] = function () use ($voiceCall) {
                    $event = new VoiceCallEvent($voiceCall);

                    switch($voiceCall->getStatus()) {
                        case VoiceCallStatus::STARTED:
                        case VoiceCallStatus::RINGING:
                            $this->get("event_dispatcher")->dispatch(VoiceCallEvents::STARTED_VOICE_CALL, $event);
                            break;
                        case VoiceCallStatus::ANSWERED:
                            $this->get("event_dispatcher")->dispatch(VoiceCallEvents::ANSWERED_VOICE_CALL, $event);
                            break;
                        case VoiceCallStatus::BUSY:
                        case VoiceCallStatus::CANCELLED:
                        case VoiceCallStatus::REJECTED:
                        case VoiceCallStatus::FAILED:
                            $this->get("event_dispatcher")->dispatch(VoiceCallEvents::FAILED_VOICE_CALL, $event);
                            break;
                        case VoiceCallStatus::COMPLETED:
                            $this->get("event_dispatcher")->dispatch(VoiceCallEvents::COMPLETED_VOICE_CALL, $event);
                            break;
                    }
                }; // end delegate func
            },
            "timestamp" => function ($val) use ($voiceCall) {
                $dt = new \DateTime($val);
                $voiceCall->setUpdatedAt($dt);
            },
            "rate" => function ($val) use ($voiceCall) {
                $voiceCall->setRate($val);
            },
            "price" => function ($val) use ($voiceCall) {
                $voiceCall->setPrice($val);
            },
            "duration" => function ($val) use ($voiceCall) {
                $voiceCall->setDuration($val);
            },
        ];

        foreach ($request->request->all() as $key => $val) {
            if (array_key_exists($key, $requestMap)) {
                $requestMap[$key]($val);
            }
        }

        $em = $this->getEntityManager();
        $em->persist($voiceCall);

        try {
            $em->flush();
            if (!empty($delegates)) {
                foreach ($delegates as $key => $eachDelegate) {
                    $eachDelegate();
                }
            }

            return $this->jsonResponse(["success" => true], Response::HTTP_OK);
        } catch (\Exception $exception) {
            // webhooks need 200 response
            return $this->jsonResponse(["success" => false], Response::HTTP_OK);
        }
    }


    /**
     * @Get("/answer-url", name="answer_webhook")
     *
     * @param Request $request
     * @return \Symfony\Component\HttpFoundation\JsonResponse
     */
    public function getAnswerWebHookAction(Request $request)
    {
        $callerUser = $this->getDoctrine()->getRepository("AppBundle:User")
            ->find($request->get("caller_uid", 0));

        $eventUrl = base64_decode($request->get('event_url'));

        if ($callerUser instanceof User) {
            $proxyNumber = (string) $callerUser->getProfile()->getPrimaryContactNumber();
        }

        $appName = "Spoke Health";
        $currentCobrand = $this->get("cobrand.factory")->current();
        if ($currentCobrand instanceof CobrandInstance) {
            $appName = $currentCobrand->getApp()->getName();
        }

        $ncoo = [
            [
                "action" => "talk",
                "text" => "Hi! Please stay on the line while we connect you to your assigned employee on {$appName}."
            ],
            [
                "action" => "connect",
                "timeout" => 45,
                "from" => $this->getParameter("nexmo_provisioned_number"),
                "eventUrl" => [$eventUrl],
                "endpoint" => [[
                    "type" => "phone",
                    "number" => $proxyNumber
                ]]
            ]
        ];

        return $this->jsonResponse($ncoo, Response::HTTP_OK);
    }
}