2017-01-05 20:17:19 +00:00
< ? php
namespace Skobkin\Bundle\PointToolsBundle\Service\Telegram ;
use Doctrine\ORM\EntityManagerInterface ;
use Skobkin\Bundle\PointToolsBundle\Entity\Telegram\Account ;
use Skobkin\Bundle\PointToolsBundle\Entity\User ;
use Skobkin\Bundle\PointToolsBundle\Exception\Telegram\CommandProcessingException ;
use Skobkin\Bundle\PointToolsBundle\Repository\SubscriptionEventRepository ;
use Skobkin\Bundle\PointToolsBundle\Repository\SubscriptionRepository ;
use Skobkin\Bundle\PointToolsBundle\Repository\UserRepository ;
use Skobkin\Bundle\PointToolsBundle\Service\Factory\Telegram\AccountFactory ;
use Skobkin\Bundle\PointToolsBundle\Service\UserApi ;
use unreal4u\TelegramAPI\Telegram\Types\Message ;
2017-01-06 17:18:39 +00:00
use unreal4u\TelegramAPI\Telegram\Types\ReplyKeyboardMarkup ;
2017-01-05 20:17:19 +00:00
/**
* Processes all private messages
*/
class PrivateMessageProcessor
{
/**
2017-01-06 17:18:39 +00:00
* @ var MessageSender
2017-01-05 20:17:19 +00:00
*/
2017-01-06 17:18:39 +00:00
private $messenger ;
2017-01-05 20:17:19 +00:00
/**
* @ var UserApi
*/
private $userApi ;
/**
* @ var AccountFactory
*/
private $accountFactory ;
/**
* @ var EntityManagerInterface
*/
private $em ;
/**
* @ var \Twig_Environment
*/
private $twig ;
/**
* @ var UserRepository
*/
private $userRepo ;
/**
* @ var SubscriptionRepository
*/
private $subscriptionRepo ;
/**
* @ var SubscriptionEventRepository
*/
private $subscriptionEventRepo ;
/**
* @ var int
*/
private $pointUserId ;
public function __construct (
2017-01-06 17:18:39 +00:00
MessageSender $messageSender ,
2017-01-05 20:17:19 +00:00
UserApi $userApi ,
AccountFactory $accountFactory ,
EntityManagerInterface $em ,
\Twig_Environment $twig ,
2017-01-05 21:50:16 +00:00
int $pointUserId
2017-01-05 20:17:19 +00:00
)
{
2017-01-06 17:18:39 +00:00
$this -> messenger = $messageSender ;
2017-01-05 20:17:19 +00:00
$this -> userApi = $userApi ;
$this -> accountFactory = $accountFactory ;
$this -> em = $em ;
$this -> twig = $twig ;
$this -> pointUserId = $pointUserId ;
$this -> userRepo = $em -> getRepository ( 'SkobkinPointToolsBundle:User' );
$this -> subscriptionRepo = $em -> getRepository ( 'SkobkinPointToolsBundle:Subscription' );
$this -> subscriptionEventRepo = $em -> getRepository ( 'SkobkinPointToolsBundle:SubscriptionEvent' );
}
public function process ( Message $message )
{
if ( ! IncomingUpdateDispatcher :: CHAT_TYPE_PRIVATE === $message -> chat -> type ) {
2017-01-06 17:18:39 +00:00
throw new \LogicException ( 'This service can process only private chat messages' );
2017-01-05 20:17:19 +00:00
}
2017-01-06 17:18:39 +00:00
try {
// Registering Telegram user
/** @var Account $account */
$account = $this -> accountFactory -> findOrCreateFromMessage ( $message );
$this -> em -> flush ();
} catch ( \Exception $e ) {
// Low-level message in case of incorrect $account
$this -> messenger -> sendMessageToChat ( $message -> chat -> id , 'There was an error during your Telegram account registration. Try again or report the bug.' );
2017-01-05 20:17:19 +00:00
}
try {
2017-01-06 17:18:39 +00:00
$words = explode ( ' ' , $message -> text , 10 );
if ( 0 === count ( $words )) {
return ;
}
2017-01-05 20:17:19 +00:00
switch ( $words [ 0 ]) {
case '/link' :
case 'link' :
if ( array_key_exists ( 2 , $words )) {
if ( $this -> linkAccount ( $account , $words [ 1 ], $words [ 2 ])) {
// Saving linking status
$this -> em -> flush ();
2017-01-06 17:18:39 +00:00
$this -> sendAccountLinked ( $account );
2017-01-05 20:17:19 +00:00
} else {
2017-01-06 17:18:39 +00:00
$this -> sendError ( $account , 'Account linking error' , 'Check login and password or try again later.' );
2017-01-05 20:17:19 +00:00
}
} else {
2017-01-06 17:18:39 +00:00
$this -> sendError ( $account , 'Login/Password error' , 'You need to specify login and password separated by space after /link (example: `/link mylogin MypASSw0rd`)' );
2017-01-05 20:17:19 +00:00
}
break ;
case '/me' :
case 'me' :
if ( $user = $account -> getUser ()) {
2017-01-06 17:18:39 +00:00
$this -> sendUserEvents ( $account , $user );
2017-01-05 20:17:19 +00:00
} else {
2017-01-06 17:18:39 +00:00
$this -> sendError ( $account , 'Account not linked' , 'You must /link your account first to be able to use this command.' );
2017-01-05 20:17:19 +00:00
}
break ;
case '/last' :
case 'last' :
if ( array_key_exists ( 1 , $words )) {
if ( null !== $user = $this -> userRepo -> findUserByLogin ( $words [ 1 ])) {
2017-01-06 17:18:39 +00:00
$this -> sendUserEvents ( $account , $user );
2017-01-05 20:17:19 +00:00
} else {
2017-01-06 17:18:39 +00:00
$this -> sendError ( $account , 'User not found' );
2017-01-05 20:17:19 +00:00
}
} else {
2017-01-06 17:18:39 +00:00
$this -> sendGlobalEvents ( $account );
2017-01-05 20:17:19 +00:00
}
break ;
case '/sub' :
case 'sub' :
if ( array_key_exists ( 1 , $words )) {
if ( null !== $user = $this -> userRepo -> findUserByLogin ( $words [ 1 ])) {
2017-01-06 17:18:39 +00:00
$this -> sendUserSubscribers ( $account , $user );
2017-01-05 20:17:19 +00:00
} else {
2017-01-06 17:18:39 +00:00
$this -> sendError ( $account , 'User not found' );
2017-01-05 20:17:19 +00:00
}
} else {
2017-01-05 21:50:16 +00:00
if ( $user = $account -> getUser ()) {
2017-01-06 17:18:39 +00:00
$this -> sendUserSubscribers ( $account , $user );
2017-01-05 21:50:16 +00:00
} else {
2017-01-06 17:18:39 +00:00
$this -> sendError ( $account , 'Account not linked' , 'You must /link your account first to be able to use this command.' );
2017-01-05 21:50:16 +00:00
}
2017-01-05 20:17:19 +00:00
}
break ;
case '/stats' :
case 'stats' :
2017-01-06 17:18:39 +00:00
$this -> sendStats ( $account );
2017-01-05 20:17:19 +00:00
break ;
case '/help' :
default :
2017-01-06 17:18:39 +00:00
$this -> sendHelp ( $account );
2017-01-05 20:17:19 +00:00
break ;
}
} catch ( CommandProcessingException $e ) {
2017-01-06 17:18:39 +00:00
$this -> sendError ( $account , 'Processing error' , $e -> getMessage ());
2017-01-05 20:17:19 +00:00
if ( $e -> getPrevious ()) {
throw $e -> getPrevious ();
}
} catch ( \Exception $e ) {
2017-01-06 17:18:39 +00:00
$this -> sendError ( $account , 'Unknown error' );
2017-01-05 20:17:19 +00:00
throw $e ;
}
}
private function linkAccount ( Account $account , string $login , string $password ) : bool
{
2017-01-05 21:30:52 +00:00
/** @var User $user */
if ( null === $user = $this -> userRepo -> findUserByLogin ( $login )) {
throw new CommandProcessingException ( 'User not found in Point Tools database. Please try again later.' );
}
2017-01-05 20:17:19 +00:00
2017-01-05 21:30:52 +00:00
if ( $this -> userApi -> isAuthDataValid ( $login , $password )) {
2017-01-05 20:17:19 +00:00
$account -> setUser ( $user );
return true ;
}
return false ;
}
2017-01-06 17:18:39 +00:00
private function sendAccountLinked ( Account $account )
2017-01-05 20:17:19 +00:00
{
2017-01-06 17:18:39 +00:00
$this -> messenger -> sendMessageToUser ( $account , 'Account linked. Try using /me now.' );
2017-01-05 20:17:19 +00:00
}
2017-01-06 17:18:39 +00:00
private function sendUserSubscribers ( Account $account , User $user )
2017-01-05 20:17:19 +00:00
{
$subscribers = [];
foreach ( $user -> getSubscribers () as $subscription ) {
$subscribers [] = '@' . $subscription -> getSubscriber () -> getLogin ();
}
2017-01-06 17:18:39 +00:00
$this -> sendTemplatedMessage (
$account ,
'@SkobkinPointTools/Telegram/user_subscribers.md.twig' ,
[
'user' => $user ,
'subscribers' => $subscribers ,
]
);
2017-01-05 20:17:19 +00:00
}
2017-01-06 17:18:39 +00:00
private function sendUserEvents ( Account $account , User $user )
2017-01-05 20:17:19 +00:00
{
$events = $this -> subscriptionEventRepo -> getUserLastSubscribersEvents ( $user , 10 );
2017-01-06 17:18:39 +00:00
$this -> sendTemplatedMessage (
$account ,
'@SkobkinPointTools/Telegram/last_user_subscriptions.md.twig' ,
[
'user' => $user ,
'events' => $events ,
]
);
2017-01-05 20:17:19 +00:00
}
2017-01-06 17:18:39 +00:00
private function sendGlobalEvents ( Account $account )
2017-01-05 20:17:19 +00:00
{
$events = $this -> subscriptionEventRepo -> getLastSubscriptionEvents ( 10 );
2017-01-06 17:18:39 +00:00
$this -> sendTemplatedMessage ( $account , '@SkobkinPointTools/Telegram/last_global_subscriptions.md.twig' , [ 'events' => $events ]);
2017-01-05 20:17:19 +00:00
}
2017-01-06 17:18:39 +00:00
private function sendStats ( Account $account )
2017-01-05 20:17:19 +00:00
{
2017-01-06 17:18:39 +00:00
$this -> sendTemplatedMessage (
$account ,
'@SkobkinPointTools/Telegram/stats.md.twig' ,
[
'total_users' => $this -> userRepo -> getUsersCount (),
'active_users' => $this -> subscriptionRepo -> getUserSubscribersCountById ( $this -> pointUserId ),
'today_events' => $this -> subscriptionEventRepo -> getLastDayEventsCount (),
]
);
2017-01-05 20:17:19 +00:00
}
2017-01-06 17:18:39 +00:00
private function sendHelp ( Account $account )
2017-01-05 20:17:19 +00:00
{
2017-01-06 17:18:39 +00:00
$this -> sendTemplatedMessage ( $account , '@SkobkinPointTools/Telegram/help.md.twig' );
}
2017-01-05 20:17:19 +00:00
2017-01-06 17:18:39 +00:00
private function sendError ( Account $account , string $title , string $text = '' )
{
$this -> sendTemplatedMessage (
$account ,
'@SkobkinPointTools/Telegram/error.md.twig' ,
[
'title' => $title ,
'text' => $text ,
]
);
2017-01-05 20:17:19 +00:00
}
2017-01-06 17:18:39 +00:00
private function sendTemplatedMessage (
Account $account ,
string $template ,
array $templateData = [],
ReplyKeyboardMarkup $keyboardMarkup = null ,
bool $disableWebPreview = true ,
string $format = MessageSender :: PARSE_MODE_MARKDOWN
) : bool
2017-01-05 20:17:19 +00:00
{
2017-01-06 17:18:39 +00:00
$text = $this -> twig -> render ( $template , $templateData );
2017-01-05 20:17:19 +00:00
2017-01-06 17:18:39 +00:00
return $this -> messenger -> sendMessageToUser ( $account , $text , $format , $keyboardMarkup , $disableWebPreview , false );
2017-01-05 20:17:19 +00:00
}
2017-01-06 17:18:39 +00:00
private function sendPlainTextMessage ( Account $account , string $text , ReplyKeyboardMarkup $keyboardMarkup = null , bool $disableWebPreview = true ) : bool
2017-01-05 20:17:19 +00:00
{
2017-01-06 17:18:39 +00:00
return $this -> messenger -> sendMessageToUser ( $account , $text , MessageSender :: PARSE_MODE_NOPARSE , $keyboardMarkup , $disableWebPreview );
2017-01-05 20:17:19 +00:00
}
}