OnEventInboundWebHook.php 3.94 KB
<?php


namespace NexmoBundle\WebHook;

use AppBundle\Entity\AdminUser;
use AppBundle\Entity\OpentokSessionTypes;
use AppBundle\Event\VoiceCallEvent;
use AppBundle\Event\VoiceCallEvents;
use JMS\DiExtraBundle\Annotation\Inject;
use JMS\DiExtraBundle\Annotation\InjectParams;
use JMS\DiExtraBundle\Annotation\Service;
use NexmoBundle\Manager\InboundCallManager;
use NexmoBundle\VoiceCall\VoiceCallStatus;
use OpenTokBundle\Pool\GlobalAdminOpenTokPool;
use OpenTokBundle\Pool\OpenTokPoolFactory;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

/**
 * Class OnEventInboundWebHook
 * @Service("nexmo.webhooks.event_inbound", autowire=true, public=true)
 */
class OnEventInboundWebHook extends NexmoWebHookHandler
{
    /**
     * @var InboundCallManager
     */
    private $callManager;

    /**
     * @var EventDispatcherInterface
     */
    private $eventDispatcher;

    /**
     * @var GlobalAdminOpenTokPool
     */
    private $opentokPool;

    /**
     * @param EventDispatcherInterface $dispatcher
     * @InjectParams({
     *     "dispatcher" = @Inject("event_dispatcher", required=false)
     * })
     */
    public function setEventDispatcher(EventDispatcherInterface $dispatcher)
    {
        $this->eventDispatcher = $dispatcher;
    }

    /**
     * @param InboundCallManager $manager
     * @InjectParams({
     *     "manager" = @Inject("nexmo.manager.inbound_call", required=false)
     * })
     */
    public function setInboundVoiceCallManager(InboundCallManager $manager)
    {
        $this->callManager = $manager;
    }

    /**
     * @param OpenTokPoolFactory $factory
     * @throws \Exception
     * @InjectParams({
     *     "factory" = @Inject("opentok_pool_factory", required=false)
     * })
     */
    public function injectAdminPool(OpenTokPoolFactory $factory)
    {
        $this->opentokPool = $factory->get(OpentokSessionTypes::ADMIN_POOL);
    }

    protected function processRequest()
    {
        $voiceCall = $this->callManager->findOneByUuidOrHalt($this->getRequestParam('uuid'));

        $requestMap = [
            "status" => function ($val) use ($voiceCall, &$delegates) {
                $voiceCall->setStatus($val);
            },
            "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);
            },
        ];

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

        try {
            $this->callManager->beginTransaction();
            $this->callManager->initThreadContent($voiceCall);
            $this->callManager->save($voiceCall);
            $this->callManager->commit();

            if ($voiceCall->getRecipient() instanceof AdminUser) {
                $this->opentokPool->sendSignal("inbound-call", $this->callManager->asOpenTokSignalData($voiceCall));

                // trigger log only on completed call
                if (VoiceCallStatus::COMPLETED === $voiceCall->getStatus()) {
                    $this->eventDispatcher->dispatch(VoiceCallEvents::INBOUND_CALL_COMPLETED, new VoiceCallEvent($voiceCall));
                }
            }

            // no needed data for response
            $this->responseData = [
                'success' => true
            ];
        } catch (\Exception $exception) {
            $this->sentry->captureException($exception);

            // no needed data for response
            $this->responseData = [
                'success' => false
            ];
        }
    }
}