Merged in feature_telegram_account_link (pull request #13)
Telegram account linking added
This commit is contained in:
commit
3a5c010d64
38
app/DoctrineMigrations/Version20170105191821.php
Normal file
38
app/DoctrineMigrations/Version20170105191821.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Application\Migrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
/**
|
||||
* Telegram accounts added
|
||||
*/
|
||||
class Version20170105191821 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
|
||||
|
||||
$this->addSql('CREATE TABLE users.telegram_accounts (account_id INT NOT NULL, user_id INT DEFAULT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, updated_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, linked_at TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT NULL, first_name TEXT NOT NULL, last_name TEXT DEFAULT NULL, username TEXT DEFAULT NULL, private_chat_id BIGINT DEFAULT NULL, subscriber_notification BOOLEAN NOT NULL, rename_notification BOOLEAN NOT NULL, PRIMARY KEY(account_id))');
|
||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_1EDB9B25A76ED395 ON users.telegram_accounts (user_id)');
|
||||
$this->addSql('CREATE INDEX subscriber_notification_idx ON users.telegram_accounts (subscriber_notification) WHERE subscriber_notification = TRUE');
|
||||
$this->addSql('CREATE INDEX rename_notification_idx ON users.telegram_accounts (rename_notification) WHERE rename_notification = TRUE');
|
||||
$this->addSql('ALTER TABLE users.telegram_accounts ADD CONSTRAINT FK_1EDB9B25A76ED395 FOREIGN KEY (user_id) REFERENCES users.users (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
|
||||
|
||||
$this->addSql('DROP TABLE users.telegram_accounts');
|
||||
}
|
||||
}
|
|
@ -18,14 +18,31 @@ class WebHookController extends Controller
|
|||
throw $this->createNotFoundException();
|
||||
}
|
||||
|
||||
$logger = $this->get('logger');
|
||||
|
||||
$content = json_decode($request->getContent(), true);
|
||||
|
||||
$update = new Update(
|
||||
$content,
|
||||
$this->get('logger')
|
||||
$logger
|
||||
);
|
||||
|
||||
$this->get('point_tools.telegram.update_processor')->process($update);
|
||||
try {
|
||||
$this->get('point_tools.telegram.update_dispatcher')->process($update);
|
||||
} catch (\Exception $e) {
|
||||
if ($this->getParameter('kernel.debug')) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$logger->addError('Telegram bot error', [
|
||||
'exception' => get_class($e),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'code' => $e->getCode(),
|
||||
'message' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString(),
|
||||
]);
|
||||
}
|
||||
|
||||
return new JsonResponse('received');
|
||||
}
|
||||
|
|
96
src/Skobkin/Bundle/PointToolsBundle/DTO/Api/Auth.php
Normal file
96
src/Skobkin/Bundle/PointToolsBundle/DTO/Api/Auth.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace Skobkin\Bundle\PointToolsBundle\DTO\Api;
|
||||
|
||||
use JMS\Serializer\Annotation as JMSS;
|
||||
|
||||
/**
|
||||
* @JMSS\ExclusionPolicy("none")
|
||||
* @JMSS\AccessType("public_method")
|
||||
*/
|
||||
class Auth
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @JMSS\SerializedName("token")
|
||||
* @JMSS\Type("string")
|
||||
*/
|
||||
private $token;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @JMSS\SerializedName("csrf_token")
|
||||
* @JMSS\Type("string")
|
||||
*/
|
||||
private $csRfToken;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @JMSS\SerializedName("error")
|
||||
* @JMSS\Type("string")
|
||||
*/
|
||||
private $error;
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getToken()
|
||||
{
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $token
|
||||
*
|
||||
* @return Auth
|
||||
*/
|
||||
public function setToken(string $token = null): Auth
|
||||
{
|
||||
$this->token = $token;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCsRfToken()
|
||||
{
|
||||
return $this->csRfToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $csRfToken
|
||||
*
|
||||
* @return Auth
|
||||
*/
|
||||
public function setCsRfToken(string $csRfToken = null)
|
||||
{
|
||||
$this->csRfToken = $csRfToken;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getError()
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $error
|
||||
*
|
||||
* @return Auth
|
||||
*/
|
||||
public function setError(string $error = null): Auth
|
||||
{
|
||||
$this->error = $error;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
264
src/Skobkin/Bundle/PointToolsBundle/Entity/Telegram/Account.php
Normal file
264
src/Skobkin/Bundle/PointToolsBundle/Entity/Telegram/Account.php
Normal file
|
@ -0,0 +1,264 @@
|
|||
<?php
|
||||
|
||||
namespace Skobkin\Bundle\PointToolsBundle\Entity\Telegram;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
||||
|
||||
/**
|
||||
* Account
|
||||
*
|
||||
* @ORM\Table(name="telegram_accounts", schema="users", indexes={
|
||||
* @ORM\Index(name="subscriber_notification_idx", columns={"subscriber_notification"}, options={"where": "subscriber_notification = TRUE"}),
|
||||
* @ORM\Index(name="rename_notification_idx", columns={"rename_notification"}, options={"where": "rename_notification = TRUE"}),
|
||||
* })
|
||||
* @ORM\Entity
|
||||
* @ORM\HasLifecycleCallbacks()
|
||||
*/
|
||||
class Account
|
||||
{
|
||||
/**
|
||||
* Telegram user ID
|
||||
*
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Id()
|
||||
* @ORM\Column(name="account_id", type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*
|
||||
* @ORM\Column(name="created_at", type="datetime")
|
||||
*/
|
||||
private $createdAt;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*
|
||||
* @ORM\Column(name="updated_at", type="datetime", nullable=true)
|
||||
*/
|
||||
private $updatedAt;
|
||||
|
||||
/**
|
||||
* @var \DateTime
|
||||
*
|
||||
* @ORM\Column(name="linked_at", type="datetime", nullable=true)
|
||||
*/
|
||||
private $linkedAt;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="first_name", type="text")
|
||||
*/
|
||||
private $firstName;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(name="last_name", type="text", nullable=true)
|
||||
*/
|
||||
private $lastName;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*
|
||||
* @ORM\Column(name="username", type="text", nullable=true)
|
||||
*/
|
||||
private $username;
|
||||
|
||||
/**
|
||||
* ID of private chat with user
|
||||
*
|
||||
* @var int
|
||||
*
|
||||
* @ORM\Column(name="private_chat_id", type="bigint", nullable=true)
|
||||
*/
|
||||
private $chatId;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*
|
||||
* @ORM\OneToOne(targetEntity="Skobkin\Bundle\PointToolsBundle\Entity\User")
|
||||
* @ORM\JoinColumn(name="user_id", nullable=true, onDelete="CASCADE")
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Notifications about new subscribers
|
||||
*
|
||||
* @var bool
|
||||
*
|
||||
* @ORM\Column(name="subscriber_notification", type="boolean")
|
||||
*/
|
||||
private $subscriberNotification = false;
|
||||
|
||||
/**
|
||||
* Notifications about user renaming
|
||||
*
|
||||
* @var bool
|
||||
*
|
||||
* @ORM\Column(name="rename_notification", type="boolean")
|
||||
*/
|
||||
private $renameNotification = false;
|
||||
|
||||
|
||||
public function __construct(int $id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ORM\PrePersist()
|
||||
*/
|
||||
public function prePersist()
|
||||
{
|
||||
$this->createdAt = new \DateTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* @ORM\PreUpdate()
|
||||
*/
|
||||
public function preUpdate()
|
||||
{
|
||||
$this->updatedAt = new \DateTime();
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCreatedAt(): \DateTime
|
||||
{
|
||||
return $this->createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getUpdatedAt(): \DateTime
|
||||
{
|
||||
return $this->updatedAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getLinkedAt(): \DateTime
|
||||
{
|
||||
return $this->linkedAt;
|
||||
}
|
||||
|
||||
public function getFirstName(): string
|
||||
{
|
||||
return $this->firstName;
|
||||
}
|
||||
|
||||
public function setFirstName(string $firstName): Account
|
||||
{
|
||||
$this->firstName = $firstName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLastName(): string
|
||||
{
|
||||
return $this->lastName;
|
||||
}
|
||||
|
||||
public function setLastName(string $lastName = null): Account
|
||||
{
|
||||
$this->lastName = $lastName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUsername(): string
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
public function setUsername(string $username = null): Account
|
||||
{
|
||||
$this->username = $username;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setChatId(int $chatId): self
|
||||
{
|
||||
$this->chatId = $chatId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getChatId(): int
|
||||
{
|
||||
return $this->chatId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User|null
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setUser(User $user): Account
|
||||
{
|
||||
if (!$this->user && $user) {
|
||||
$this->linkedAt = new \DateTime();
|
||||
}
|
||||
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUserId(): int
|
||||
{
|
||||
return $this->user->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables all notifications
|
||||
*/
|
||||
public function disableNotifications(): self
|
||||
{
|
||||
$this->subscriberNotification = false;
|
||||
$this->renameNotification = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSubscriberNotification(bool $subscriberNotification): self
|
||||
{
|
||||
$this->subscriberNotification = $subscriberNotification;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isSubscriberNotification(): bool
|
||||
{
|
||||
return $this->subscriberNotification;
|
||||
}
|
||||
|
||||
public function setRenameNotification(bool $renameNotification): self
|
||||
{
|
||||
$this->renameNotification = $renameNotification;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isRenameNotification(): bool
|
||||
{
|
||||
return $this->renameNotification;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Skobkin\Bundle\PointToolsBundle\Exception\Telegram;
|
||||
|
||||
|
||||
class CommandProcessingException extends \Exception
|
||||
{
|
||||
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
namespace Skobkin\Bundle\PointToolsBundle\Repository;
|
||||
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Skobkin\Bundle\PointToolsBundle\Entity\SubscriptionEvent;
|
||||
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
||||
|
@ -11,9 +10,9 @@ use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
|||
class SubscriptionEventRepository extends EntityRepository
|
||||
{
|
||||
/**
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function getLastDayEventsCount()
|
||||
public function getLastDayEventsCount(): int
|
||||
{
|
||||
$qb = $this->createQueryBuilder('se');
|
||||
|
||||
|
@ -34,7 +33,7 @@ class SubscriptionEventRepository extends EntityRepository
|
|||
*
|
||||
* @return QueryBuilder
|
||||
*/
|
||||
public function createUserLastSubscribersEventsQuery(User $user)
|
||||
public function createUserLastSubscribersEventsQuery(User $user): QueryBuilder
|
||||
{
|
||||
$qb = $this->createQueryBuilder('se');
|
||||
|
||||
|
@ -47,12 +46,28 @@ class SubscriptionEventRepository extends EntityRepository
|
|||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last user subscriber events
|
||||
*
|
||||
* @param User $user
|
||||
* @param int $limit
|
||||
*
|
||||
* @return SubscriptionEvent[]
|
||||
*/
|
||||
public function getUserLastSubscribersEvents(User $user, int $limit = 20): array
|
||||
{
|
||||
$qb = $this->createUserLastSubscribersEventsQuery($user);
|
||||
$qb->setMaxResults($limit);
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last global subscriptions QueryBuilder for pagination
|
||||
*
|
||||
* @return QueryBuilder
|
||||
*/
|
||||
public function createLastSubscriptionEventsQuery()
|
||||
public function createLastSubscriptionEventsQuery(): QueryBuilder
|
||||
{
|
||||
$qb = $this->createQueryBuilder('se');
|
||||
|
||||
|
@ -71,7 +86,7 @@ class SubscriptionEventRepository extends EntityRepository
|
|||
*
|
||||
* @return SubscriptionEvent[]
|
||||
*/
|
||||
public function getLastSubscriptionEvents($limit = 20)
|
||||
public function getLastSubscriptionEvents(int $limit = 20): array
|
||||
{
|
||||
$qb = $this->createLastSubscriptionEventsQuery();
|
||||
$qb->setMaxResults($limit);
|
||||
|
|
|
@ -14,6 +14,7 @@ services:
|
|||
tags:
|
||||
- { name: guzzle.client }
|
||||
|
||||
|
||||
skobkin_point_tools.api_user:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\UserApi
|
||||
arguments:
|
||||
|
@ -21,6 +22,7 @@ services:
|
|||
- "%point_use_https%"
|
||||
- "%point_api_base_url%"
|
||||
- @doctrine.orm.entity_manager
|
||||
- @serializer
|
||||
|
||||
skobkin_point_tools.api_post:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\PostApi
|
||||
|
@ -30,26 +32,34 @@ services:
|
|||
- "%point_api_base_url%"
|
||||
- @skobkin__point_tools.service_factory.post_factory
|
||||
|
||||
|
||||
skobkin_point_tools.subscriptions_manager:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\SubscriptionsManager
|
||||
arguments: [ @doctrine.orm.entity_manager ]
|
||||
|
||||
|
||||
# Factories
|
||||
# User factory
|
||||
skobkin__point_tools.service_factory.user_factory:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\UserFactory
|
||||
arguments: [ @doctrine.orm.entity_manager ]
|
||||
|
||||
# Comment factory
|
||||
skobkin__point_tools.service_factory.comment_factory:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\CommentFactory
|
||||
arguments: [ @doctrine.orm.entity_manager, @skobkin__point_tools.service_factory.user_factory ]
|
||||
|
||||
# Tag factory
|
||||
skobkin__point_tools.service_factory.tag_factory:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\TagFactory
|
||||
arguments: [ @logger, @doctrine.orm.entity_manager ]
|
||||
|
||||
# File factory
|
||||
skobkin__point_tools.service_factory.file_factory:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\FileFactory
|
||||
arguments: [ @logger, @doctrine.orm.entity_manager ]
|
||||
|
||||
# Post factory
|
||||
skobkin__point_tools.service_factory.post_factory:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\PostFactory
|
||||
arguments:
|
||||
|
@ -60,21 +70,27 @@ services:
|
|||
- @skobkin__point_tools.service_factory.comment_factory
|
||||
- @skobkin__point_tools.service_factory.tag_factory
|
||||
|
||||
# Telegram accounts factory
|
||||
point_tools.factory.telegram_account:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Telegram\AccountFactory
|
||||
arguments: [@doctrine.orm.entity_manager]
|
||||
|
||||
|
||||
# Custom Markdown parser
|
||||
markdown.parser.point:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\Markdown\PointParser
|
||||
arguments:
|
||||
- []
|
||||
- @router
|
||||
arguments: [[], @router]
|
||||
tags:
|
||||
- { name: markdown.parser }
|
||||
|
||||
|
||||
# Event listener
|
||||
point_tools.event_listener.user_rename_subscriber:
|
||||
class: Skobkin\Bundle\PointToolsBundle\EventListener\UserRenameSubscriber
|
||||
tags:
|
||||
- { name: doctrine.event_subscriber, connection: default }
|
||||
|
||||
|
||||
# Twig extensions
|
||||
point_tools.twig.point_avatar_extension:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Twig\PointUserExtension
|
||||
|
@ -83,17 +99,40 @@ services:
|
|||
tags:
|
||||
- { name: twig.extension }
|
||||
|
||||
# Telegram API client
|
||||
|
||||
# Telegram services
|
||||
# API client
|
||||
point_tools.telegram.api_client:
|
||||
class: unreal4u\TelegramAPI\TgLog
|
||||
arguments: [%telegram_token%, @logger, @point_tools.http.telegram_client]
|
||||
|
||||
# Telegram simple message sender
|
||||
# Simple message sender
|
||||
point_tools.telegram.simple_sender:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\Telegram\SimpleSender
|
||||
arguments: [@point_tools.telegram.api_client]
|
||||
|
||||
# Telegram command processor
|
||||
point_tools.telegram.update_processor:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\Telegram\IncomingUpdateProcessor
|
||||
arguments: [%point_id%, @point_tools.telegram.api_client, @doctrine.orm.entity_manager, @twig]
|
||||
# Common incoming message processor
|
||||
point_tools.telegram.update_dispatcher:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\Telegram\IncomingUpdateDispatcher
|
||||
arguments:
|
||||
- @point_tools.telegram.private_message_processor
|
||||
- @point_tools.telegram.inline_query_processor
|
||||
|
||||
# InlineQuery processor
|
||||
point_tools.telegram.inline_query_processor:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\Telegram\InlineQueryProcessor
|
||||
lazy: true
|
||||
arguments: [@doctrine.orm.entity_manager, @point_tools.telegram.api_client]
|
||||
|
||||
# Private message processor
|
||||
point_tools.telegram.private_message_processor:
|
||||
class: Skobkin\Bundle\PointToolsBundle\Service\Telegram\PrivateMessageProcessor
|
||||
lazy: true
|
||||
arguments:
|
||||
- @point_tools.telegram.api_client
|
||||
- @skobkin_point_tools.api_user
|
||||
- @point_tools.factory.telegram_account
|
||||
- @doctrine.orm.entity_manager
|
||||
- @twig
|
||||
- %point_id%
|
||||
- %point_login%
|
|
@ -0,0 +1,7 @@
|
|||
*{{ title }}*
|
||||
{% if text %}
|
||||
|
||||
{{ text }}
|
||||
{% endif %}
|
||||
|
||||
[Send bug report](https://bitbucket.org/skobkin/point-tools/issues?status=new&status=open).
|
|
@ -1,7 +1,10 @@
|
|||
*Help*:
|
||||
|
||||
/me - Show your last subscriber events (/link needed)
|
||||
/link %login% %password% - Link your Telegram account with Point.im account
|
||||
/last - shows last global subscription events
|
||||
/last %user% - shows last user subscribers events
|
||||
/sub - Show user subscribers
|
||||
/help shows this message
|
||||
|
||||
Visit [Point Tools](https://point.skobk.in/) for more info.
|
|
@ -0,0 +1,12 @@
|
|||
{# @var user \Skobkin\Bundle\PointToolsBundle\Entity\User #}
|
||||
*Last [@{{ user.login }}]({{ user.login|point_user_url(true) }}):*
|
||||
|
||||
{% set subscription = constant('\\Skobkin\\Bundle\\PointToolsBundle\\Entity\\SubscriptionEvent::ACTION_SUBSCRIBE') %}
|
||||
{# @var event \Skobkin\Bundle\PointToolsBundle\Entity\SubscriptionEvent #}
|
||||
{% for event in events %}
|
||||
{% set sub_login = event.subscriber.login %}
|
||||
{{ event.date|date('d M y H:i') }} {% if subscription == event.action %} + {% else %} - {% endif %} [@{{ sub_login }}]({{ sub_login|point_user_url(true) }})
|
||||
{% endfor %}
|
||||
|
||||
{# @todo remove hardcoded URL #}
|
||||
See more events on [Point Tools](https://point.skobk.in{{ path('user_show', {'login': user.login}) }}) site.
|
|
@ -0,0 +1,11 @@
|
|||
{# @var user \Skobkin\Bundle\PointToolsBundle\Entity\User #}
|
||||
*@{{ user.login }} subscribers:*
|
||||
|
||||
{% if subscribers|length > 0 %}
|
||||
{{ subscribers|join(', ') }}
|
||||
{% else %}
|
||||
No subscribers
|
||||
{% endif %}
|
||||
|
||||
{# @todo remove hardcoded URL #}
|
||||
See more events on [Point Tools](https://point.skobk.in{{ path('user_show', {'login': user.login}) }}) site.
|
|
@ -23,7 +23,7 @@
|
|||
<div class="panel-body">
|
||||
<ul class="users mosaic">
|
||||
{% for user in subscribers %}
|
||||
<li><a href="{{ url('user_show', {login: user.login}) }}">@{{ user.login }}</a></li>
|
||||
<li><a href="{{ path('user_show', {login: user.login}) }}">@{{ user.login }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -94,7 +94,7 @@
|
|||
{% for event in subscriptions_log %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{ url('user_show', {login: event.subscriber.login}) }}">@{{ event.subscriber.login }}</a>
|
||||
<a href="{{ path('user_show', {login: event.subscriber.login}) }}">@{{ event.subscriber.login }}</a>
|
||||
</td>
|
||||
<td>
|
||||
<span class="glyphicon {% if event.action == 'subscribe' %}glyphicon-plus{% elseif event.action == 'unsubscribe' %}glyphicon-minus{% endif %}"></span>
|
||||
|
|
|
@ -80,9 +80,7 @@ class AbstractApi
|
|||
public function sendPostRequest($path, array $parameters = [])
|
||||
{
|
||||
/** @var GuzzleRequest $request */
|
||||
$request = $this->client->post($path, null, null, [
|
||||
'form_params' => $parameters,
|
||||
]);
|
||||
$request = $this->client->post($path, null, $parameters);
|
||||
|
||||
return $request->send();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Skobkin\Bundle\PointToolsBundle\Service\Factory\Telegram;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Skobkin\Bundle\PointToolsBundle\Entity\Telegram\Account;
|
||||
use unreal4u\TelegramAPI\Telegram\Types\Message;
|
||||
|
||||
class AccountFactory
|
||||
{
|
||||
/**
|
||||
* @var EntityManagerInterface
|
||||
*/
|
||||
private $em;
|
||||
|
||||
/**
|
||||
* @var EntityRepository
|
||||
*/
|
||||
private $accountRepo;
|
||||
|
||||
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->accountRepo = $em->getRepository('SkobkinPointToolsBundle:Telegram\Account');
|
||||
}
|
||||
|
||||
public function findOrCreateFromMessage(Message $message): Account
|
||||
{
|
||||
if (null === $account = $this->accountRepo->findOneBy(['id' => $message->from->id])) {
|
||||
$account = new Account($message->from->id);
|
||||
$this->em->persist($account);
|
||||
}
|
||||
|
||||
// Setting/updating account data
|
||||
$account
|
||||
->setFirstName($message->from->first_name)
|
||||
->setLastName($message->from->last_name)
|
||||
->setUsername($message->from->username)
|
||||
->setChatId($message->chat->id)
|
||||
;
|
||||
|
||||
return $account;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace Skobkin\Bundle\PointToolsBundle\Service\Telegram;
|
||||
|
||||
use unreal4u\TelegramAPI\Telegram\Types\Inline\Query;
|
||||
use unreal4u\TelegramAPI\Telegram\Types\Message;
|
||||
use unreal4u\TelegramAPI\Telegram\Types\Update;
|
||||
|
||||
/**
|
||||
* Dispatches incoming messages processing to corresponding services
|
||||
*/
|
||||
class IncomingUpdateDispatcher
|
||||
{
|
||||
const CHAT_TYPE_PRIVATE = 'private';
|
||||
const CHAT_TYPE_GROUP = 'group';
|
||||
|
||||
/**
|
||||
* @var InlineQueryProcessor
|
||||
*/
|
||||
private $inlineQueryProcessor;
|
||||
|
||||
/**
|
||||
* @var PrivateMessageProcessor
|
||||
*/
|
||||
private $privateMessageProcessor;
|
||||
|
||||
|
||||
public function __construct(PrivateMessageProcessor $privateMessageProcessor, InlineQueryProcessor $inlineQueryProcessor)
|
||||
{
|
||||
$this->privateMessageProcessor = $privateMessageProcessor;
|
||||
$this->inlineQueryProcessor = $inlineQueryProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes update and delegates it to corresponding service
|
||||
*
|
||||
* @param Update $update
|
||||
*/
|
||||
public function process(Update $update)
|
||||
{
|
||||
if ($update->message && $update->message instanceof Message) {
|
||||
$chatType = $update->message->chat->type;
|
||||
|
||||
if (self::CHAT_TYPE_PRIVATE === $chatType) {
|
||||
$this->privateMessageProcessor->process($update->message);
|
||||
} elseif (self::CHAT_TYPE_GROUP === $chatType) {
|
||||
// @todo implement
|
||||
}
|
||||
} elseif ($update->inline_query && $update->inline_query instanceof Query) {
|
||||
$this->inlineQueryProcessor->process($update->inline_query);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Skobkin\Bundle\PointToolsBundle\Service\Telegram;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use unreal4u\TelegramAPI\Telegram\Methods\AnswerInlineQuery;
|
||||
use unreal4u\TelegramAPI\Telegram\Methods\SendMessage;
|
||||
use unreal4u\TelegramAPI\Telegram\Types\Inline\Query;
|
||||
use unreal4u\TelegramAPI\Telegram\Types\InputMessageContent\Text;
|
||||
use unreal4u\TelegramAPI\Telegram\Types\Message;
|
||||
use unreal4u\TelegramAPI\Telegram\Types\Update;
|
||||
use unreal4u\TelegramAPI\TgLog;
|
||||
|
||||
/**
|
||||
* @todo refactor
|
||||
*/
|
||||
class IncomingUpdateProcessor
|
||||
{
|
||||
const CHAT_TYPE_PRIVATE = 'private';
|
||||
const CHAT_TYPE_GROUP = 'group';
|
||||
|
||||
const PARSE_MODE_MARKDOWN = 'Markdown';
|
||||
const PARSE_MODE_HTML5 = 'HTML';
|
||||
|
||||
/**
|
||||
* @var TgLog
|
||||
*/
|
||||
private $client;
|
||||
|
||||
/**
|
||||
* @var EntityManagerInterface
|
||||
*/
|
||||
private $em;
|
||||
|
||||
/**
|
||||
* @var \Twig_Environment
|
||||
*/
|
||||
private $twig;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $pointUserId;
|
||||
|
||||
/**
|
||||
* @param TgLog $client
|
||||
*/
|
||||
public function __construct(int $pointUserId, TgLog $client, EntityManagerInterface $em, \Twig_Environment $twig)
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->em = $em;
|
||||
$this->twig = $twig;
|
||||
$this->pointUserId = $pointUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes update and delegates it to corresponding service
|
||||
*
|
||||
* @param Update $update
|
||||
*/
|
||||
public function process(Update $update)
|
||||
{
|
||||
if ($update->message && $update->message instanceof Message) {
|
||||
$chatType = $update->message->chat->type;
|
||||
|
||||
if (self::CHAT_TYPE_PRIVATE === $chatType) {
|
||||
$this->processPrivateMessage($update);
|
||||
} elseif (self::CHAT_TYPE_GROUP === $chatType) {
|
||||
|
||||
}
|
||||
} elseif ($update->inline_query && $update->inline_query instanceof Query) {
|
||||
$this->processInlineQuery($update);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo refactor
|
||||
*
|
||||
* @param Update $update
|
||||
*/
|
||||
private function processPrivateMessage(Update $update)
|
||||
{
|
||||
$chatId = $update->message->chat->id;
|
||||
$text = $update->message->text;
|
||||
|
||||
$sendMessage = new SendMessage();
|
||||
$sendMessage->chat_id = $chatId;
|
||||
$sendMessage->parse_mode = self::PARSE_MODE_MARKDOWN;
|
||||
$sendMessage->disable_web_page_preview = true;
|
||||
|
||||
$words = explode(' ', $text, 3);
|
||||
|
||||
if (0 === count($words)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch ($words[0]) {
|
||||
case 'l':
|
||||
case '/last':
|
||||
case 'last':
|
||||
if (array_key_exists(1, $words)) {
|
||||
$sendMessage->text = 'Not implemented yet :(';
|
||||
} else {
|
||||
$events = $this->em->getRepository('SkobkinPointToolsBundle:SubscriptionEvent')->getLastSubscriptionEvents(10);
|
||||
$sendMessage->text = $this->twig->render('@SkobkinPointTools/Telegram/last_global_subscriptions.md.twig', ['events' => $events]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'sub':
|
||||
case '/sub':
|
||||
case 'subscribers':
|
||||
$sendMessage->text = 'Subscribers list here...';
|
||||
break;
|
||||
|
||||
case 'stats':
|
||||
case '/stats':
|
||||
$stats = [
|
||||
'total_users' => $this->em->getRepository('SkobkinPointToolsBundle:User')->getUsersCount(),
|
||||
'active_users' => $this->em->getRepository('SkobkinPointToolsBundle:Subscription')->getUserSubscribersCountById($this->pointUserId),
|
||||
'today_events' => $this->em->getRepository('SkobkinPointToolsBundle:SubscriptionEvent')->getLastDayEventsCount(),
|
||||
];
|
||||
|
||||
$sendMessage->text = $this->twig->render('@SkobkinPointTools/Telegram/stats.md.twig', $stats);
|
||||
|
||||
break;
|
||||
|
||||
case '/help':
|
||||
default:
|
||||
$sendMessage->text = $this->twig->render('@SkobkinPointTools/Telegram/help.md.twig');
|
||||
break;
|
||||
}
|
||||
|
||||
$this->client->performApiRequest($sendMessage);
|
||||
}
|
||||
|
||||
private function processInlineQuery(Update $update)
|
||||
{
|
||||
$queryId = $update->inline_query->id;
|
||||
$text = $update->inline_query->query;
|
||||
|
||||
if (mb_strlen($text) < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
$answerInlineQuery = new AnswerInlineQuery();
|
||||
$answerInlineQuery->inline_query_id = $queryId;
|
||||
|
||||
foreach ($this->em->getRepository('SkobkinPointToolsBundle:User')->findUsersLikeLogin($text) as $user) {
|
||||
$article = new Query\Result\Article();
|
||||
$article->title = $user->getLogin();
|
||||
|
||||
$contentText = new Text();
|
||||
$contentText->message_text = sprintf(
|
||||
"@%s:\nName: %s\nSubscribers: %d",
|
||||
$user->getLogin(),
|
||||
$user->getName(),
|
||||
$user->getSubscribers()->count()
|
||||
);
|
||||
|
||||
$article->input_message_content = $contentText;
|
||||
$article->id = md5($user->getId());
|
||||
|
||||
$answerInlineQuery->addResult($article);
|
||||
}
|
||||
|
||||
$this->client->performApiRequest($answerInlineQuery);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace Skobkin\Bundle\PointToolsBundle\Service\Telegram;
|
||||
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Skobkin\Bundle\PointToolsBundle\Repository\UserRepository;
|
||||
use unreal4u\TelegramAPI\Telegram\Methods\AnswerInlineQuery;
|
||||
use unreal4u\TelegramAPI\Telegram\Types\Inline\Query;
|
||||
use unreal4u\TelegramAPI\Telegram\Types\InputMessageContent\Text;
|
||||
use unreal4u\TelegramAPI\TgLog;
|
||||
|
||||
class InlineQueryProcessor
|
||||
{
|
||||
/**
|
||||
* @var EntityManagerInterface
|
||||
*/
|
||||
private $em;
|
||||
|
||||
/**
|
||||
* @var UserRepository
|
||||
*/
|
||||
private $userRepo;
|
||||
|
||||
/**
|
||||
* @var TgLog
|
||||
*/
|
||||
private $client;
|
||||
|
||||
|
||||
public function __construct(EntityManagerInterface $em, TgLog $client)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->client = $client;
|
||||
|
||||
$this->userRepo = $em->getRepository('SkobkinPointToolsBundle:User');
|
||||
}
|
||||
|
||||
public function process(Query $inlineQuery)
|
||||
{
|
||||
if (mb_strlen($inlineQuery->query) < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
$answerInlineQuery = new AnswerInlineQuery();
|
||||
$answerInlineQuery->inline_query_id = $inlineQuery->id;
|
||||
|
||||
foreach ($this->em->getRepository('SkobkinPointToolsBundle:User')->findUsersLikeLogin($inlineQuery->query) as $user) {
|
||||
$article = new Query\Result\Article();
|
||||
$article->title = $user->getLogin();
|
||||
|
||||
$contentText = new Text();
|
||||
$contentText->message_text = sprintf(
|
||||
"@%s:\nName: %s\nSubscribers: %d",
|
||||
$user->getLogin(),
|
||||
$user->getName(),
|
||||
$user->getSubscribers()->count()
|
||||
);
|
||||
|
||||
$article->input_message_content = $contentText;
|
||||
$article->id = md5($user->getId());
|
||||
|
||||
$answerInlineQuery->addResult($article);
|
||||
}
|
||||
|
||||
$this->client->performApiRequest($answerInlineQuery);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,307 @@
|
|||
<?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\Methods\SendMessage;
|
||||
use unreal4u\TelegramAPI\Telegram\Types\Message;
|
||||
use unreal4u\TelegramAPI\TgLog;
|
||||
|
||||
/**
|
||||
* Processes all private messages
|
||||
*/
|
||||
class PrivateMessageProcessor
|
||||
{
|
||||
const TEMPLATE_ERROR = '@SkobkinPointTools/Telegram/error.md.twig';
|
||||
const TEMPLATE_STATS = '@SkobkinPointTools/Telegram/stats.md.twig';
|
||||
const TEMPLATE_HELP = '@SkobkinPointTools/Telegram/help.md.twig';
|
||||
const TEMPLATE_LAST_EVENTS = '@SkobkinPointTools/Telegram/last_global_subscriptions.md.twig';
|
||||
const TEMPLATE_LAST_USER_SUB_EVENTS = '@SkobkinPointTools/Telegram/last_user_subscriptions.md.twig';
|
||||
const TEMPLATE_USER_SUBSCRIBERS = '@SkobkinPointTools/Telegram/user_subscribers.md.twig';
|
||||
|
||||
const PARSE_MODE_MARKDOWN = 'Markdown';
|
||||
const PARSE_MODE_HTML5 = 'HTML';
|
||||
|
||||
/**
|
||||
* @var TgLog
|
||||
*/
|
||||
private $client;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $pointUserLogin;
|
||||
|
||||
|
||||
public function __construct(
|
||||
TgLog $client,
|
||||
UserApi $userApi,
|
||||
AccountFactory $accountFactory,
|
||||
EntityManagerInterface $em,
|
||||
\Twig_Environment $twig,
|
||||
int $pointUserId,
|
||||
string $pointUserLogin
|
||||
)
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->userApi = $userApi;
|
||||
$this->accountFactory = $accountFactory;
|
||||
$this->em = $em;
|
||||
$this->twig = $twig;
|
||||
$this->pointUserId = $pointUserId;
|
||||
$this->pointUserLogin = $pointUserLogin;
|
||||
|
||||
$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) {
|
||||
throw new \InvalidArgumentException('This service can process only private chat messages');
|
||||
}
|
||||
|
||||
// Registering Telegram user
|
||||
/** @var Account $account */
|
||||
$account = $this->accountFactory->findOrCreateFromMessage($message);
|
||||
$this->em->flush();
|
||||
|
||||
// Creating blank response for later use
|
||||
$sendMessage = $this->createResponseMessage($message, self::PARSE_MODE_MARKDOWN, true);
|
||||
|
||||
$words = explode(' ', $message->text, 4);
|
||||
|
||||
if (0 === count($words)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
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();
|
||||
$this->sendAccountLinked($sendMessage);
|
||||
} else {
|
||||
$this->sendError($sendMessage, 'Account linking error', 'Check login and password or try again later.');
|
||||
}
|
||||
} else {
|
||||
$this->sendError($sendMessage, 'Login/Password error', 'You need to specify login and password separated by space after /link (example: `/link mylogin MypASSw0rd`)');
|
||||
}
|
||||
break;
|
||||
|
||||
case '/me':
|
||||
case 'me':
|
||||
if ($user = $account->getUser()) {
|
||||
$this->sendUserEvents($sendMessage, $user);
|
||||
} else {
|
||||
$this->sendError($sendMessage, 'Account not linked', 'You must /link your account first to be able to use this command.');
|
||||
}
|
||||
break;
|
||||
|
||||
case '/last':
|
||||
case 'l':
|
||||
case 'last':
|
||||
if (array_key_exists(1, $words)) {
|
||||
if (null !== $user = $this->userRepo->findUserByLogin($words[1])) {
|
||||
$this->sendUserEvents($sendMessage, $user);
|
||||
} else {
|
||||
$this->sendError($sendMessage, 'User not found');
|
||||
}
|
||||
} else {
|
||||
$this->sendGlobalEvents($sendMessage);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '/sub':
|
||||
case 'sub':
|
||||
case 'subscribers':
|
||||
if (array_key_exists(1, $words)) {
|
||||
if (null !== $user = $this->userRepo->findUserByLogin($words[1])) {
|
||||
$this->sendUserSubscribers($sendMessage, $user);
|
||||
} else {
|
||||
$this->sendError($sendMessage, 'User not found');
|
||||
}
|
||||
} else {
|
||||
$user = $this->userRepo->findUserByLogin($this->pointUserLogin);
|
||||
$this->sendUserSubscribers($sendMessage, $user);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '/stats':
|
||||
case 'stats':
|
||||
$this->sendStats($sendMessage);
|
||||
|
||||
break;
|
||||
|
||||
case '/help':
|
||||
default:
|
||||
$this->sendHelp($sendMessage);
|
||||
break;
|
||||
}
|
||||
} catch (CommandProcessingException $e) {
|
||||
$this->sendError($sendMessage, 'Processing error', $e->getMessage());
|
||||
|
||||
if ($e->getPrevious()) {
|
||||
throw $e->getPrevious();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->sendError($sendMessage, 'Unknown error');
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
private function linkAccount(Account $account, string $login, string $password): bool
|
||||
{
|
||||
if ($this->userApi->isAuthDataValid($login, $password)) {
|
||||
/** @var User $user */
|
||||
if (null === $user = $this->userRepo->findOneBy(['login' => $login])) {
|
||||
throw new CommandProcessingException('User not found in Point Tools database. Please try again later.');
|
||||
}
|
||||
|
||||
$account->setUser($user);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function sendAccountLinked(SendMessage $sendMessage)
|
||||
{
|
||||
$sendMessage->text = 'Account linked. Try using /me now.';
|
||||
|
||||
$this->client->performApiRequest($sendMessage);
|
||||
}
|
||||
|
||||
private function sendUserSubscribers(SendMessage $sendMessage, User $user)
|
||||
{
|
||||
$subscribers = [];
|
||||
|
||||
foreach ($user->getSubscribers() as $subscription) {
|
||||
$subscribers[] = '@'.$subscription->getSubscriber()->getLogin();
|
||||
}
|
||||
|
||||
$sendMessage->text = $this->twig->render(self::TEMPLATE_USER_SUBSCRIBERS, [
|
||||
'user' => $user,
|
||||
'subscribers' => $subscribers,
|
||||
]);
|
||||
|
||||
$this->client->performApiRequest($sendMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SendMessage $sendMessage
|
||||
* @param User $user
|
||||
*/
|
||||
private function sendUserEvents(SendMessage $sendMessage, User $user)
|
||||
{
|
||||
$events = $this->subscriptionEventRepo->getUserLastSubscribersEvents($user, 10);
|
||||
$sendMessage->text = $this->twig->render(self::TEMPLATE_LAST_USER_SUB_EVENTS, [
|
||||
'user' => $user,
|
||||
'events' => $events,
|
||||
]);
|
||||
|
||||
$this->client->performApiRequest($sendMessage);
|
||||
}
|
||||
|
||||
private function sendGlobalEvents(SendMessage $sendMessage)
|
||||
{
|
||||
$events = $this->subscriptionEventRepo->getLastSubscriptionEvents(10);
|
||||
$sendMessage->text = $this->twig->render(self::TEMPLATE_LAST_EVENTS, ['events' => $events]);
|
||||
|
||||
$this->client->performApiRequest($sendMessage);
|
||||
}
|
||||
|
||||
private function sendStats(SendMessage $sendMessage)
|
||||
{
|
||||
$sendMessage->text = $this->twig->render(self::TEMPLATE_STATS, [
|
||||
'total_users' => $this->userRepo->getUsersCount(),
|
||||
'active_users' => $this->subscriptionRepo->getUserSubscribersCountById($this->pointUserId),
|
||||
'today_events' => $this->subscriptionEventRepo->getLastDayEventsCount(),
|
||||
]);
|
||||
|
||||
$this->client->performApiRequest($sendMessage);
|
||||
}
|
||||
|
||||
private function sendHelp(SendMessage $sendMessage)
|
||||
{
|
||||
$sendMessage->text = $this->twig->render(self::TEMPLATE_HELP);
|
||||
|
||||
$this->client->performApiRequest($sendMessage);
|
||||
}
|
||||
|
||||
private function sendError(SendMessage $sendMessage, string $title, string $text = '')
|
||||
{
|
||||
$sendMessage->text = $this->twig->render(self::TEMPLATE_ERROR, [
|
||||
'title' => $title,
|
||||
'text' => $text,
|
||||
]);
|
||||
|
||||
$this->client->performApiRequest($sendMessage);
|
||||
}
|
||||
|
||||
private function createResponseMessage(Message $message, string $parseMode = self::PARSE_MODE_MARKDOWN, bool $disableWebPreview = false): SendMessage
|
||||
{
|
||||
$sendMessage = new SendMessage();
|
||||
$sendMessage->chat_id = $message->chat->id;
|
||||
$sendMessage->parse_mode = $parseMode;
|
||||
$sendMessage->disable_web_page_preview = $disableWebPreview;
|
||||
|
||||
return $sendMessage;
|
||||
}
|
||||
}
|
|
@ -6,6 +6,8 @@ use Doctrine\ORM\EntityManager;
|
|||
use Doctrine\ORM\EntityRepository;
|
||||
use Guzzle\Http\Exception\ClientErrorResponseException;
|
||||
use Guzzle\Service\Client;
|
||||
use JMS\Serializer\Serializer;
|
||||
use Skobkin\Bundle\PointToolsBundle\DTO\Api\Auth;
|
||||
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
||||
use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\ApiException;
|
||||
use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\InvalidResponseException;
|
||||
|
@ -36,12 +38,18 @@ class UserApi extends AbstractApi
|
|||
*/
|
||||
protected $userRepository;
|
||||
|
||||
/**
|
||||
* @var Serializer
|
||||
*/
|
||||
private $serializer;
|
||||
|
||||
public function __construct(Client $httpClient, $https = true, $baseUrl = null, EntityManager $entityManager)
|
||||
|
||||
public function __construct(Client $httpClient, $https = true, $baseUrl = null, EntityManager $entityManager, Serializer $serializer)
|
||||
{
|
||||
parent::__construct($httpClient, $https, $baseUrl);
|
||||
|
||||
$this->em = $entityManager;
|
||||
$this->serializer = $serializer;
|
||||
$this->userRepository = $this->em->getRepository('SkobkinPointToolsBundle:User');
|
||||
}
|
||||
|
||||
|
@ -50,6 +58,57 @@ class UserApi extends AbstractApi
|
|||
return 'skobkin_point_tools_api_user';
|
||||
}
|
||||
|
||||
public function isAuthDataValid(string $login, string $password): bool
|
||||
{
|
||||
$auth = $this->authenticate($login, $password);
|
||||
|
||||
if (!$auth->getError() && $auth->getToken()) {
|
||||
$this->logout($auth);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function authenticate(string $login, string $password): Auth
|
||||
{
|
||||
try {
|
||||
$authData = $this->getPostRequestData(
|
||||
'/api/login',
|
||||
[
|
||||
'login' => $login,
|
||||
'password' => $password,
|
||||
]
|
||||
);
|
||||
|
||||
return $this->serializer->deserialize($authData, Auth::class, 'json');
|
||||
} catch (ClientErrorResponseException $e) {
|
||||
if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) {
|
||||
throw new InvalidResponseException('API method not found', 0, $e);
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function logout(Auth $auth): bool
|
||||
{
|
||||
try {
|
||||
$this->getPostRequestData('/api/logout', ['csrf_token' => $auth->getCsRfToken()]);
|
||||
|
||||
return true;
|
||||
} catch (ClientErrorResponseException $e) {
|
||||
if (Response::HTTP_NOT_FOUND === $e->getResponse()->getStatusCode()) {
|
||||
throw new InvalidResponseException('API method not found', 0, $e);
|
||||
} elseif (Response::HTTP_FORBIDDEN === $e->getResponse()->getStatusCode()) {
|
||||
return true;
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user subscribers by user login
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue