Commit d846fa4a authored by MBoretto's avatar MBoretto

send message to multiple chat and other stuff

parent 4378f6cf
......@@ -15,7 +15,7 @@ A Telegram Bot based on the official [Telegram Bot API](https://core.telegram.or
## introduction
This is a pure php Telegram Bot, fully extensible via plugins. Telegram recently announced official support for a [Bot API](https://telegram.org/blog/bot-revolution) allowing integrators of all sorts to bring automated interactions to the mobile platform. This Bot aims to provide a platform where one could simply write a plugin and have interactions in a matter of minutes.
The Bot support Reply Markup and handle commands in group chat.
The Bot supports Reply Markup and handle commands in group chat with multiple bot.
Instructions
......@@ -153,31 +153,66 @@ $credentials = array('host'=>'localhost', 'user'=>'dbuser', 'password'=>'dbpass'
$telegram->enableMySQL($credentials);
```
You can set a custom prefix to all the tables while you are enabling mysql:
```php
$telegram->enableMySQL($credentials, $BOT_NAME.'_');
```
Commads
--------------
The bot is able to recognise commands in chat with multiple bot.
It can execute command triggering a chat event. Here's the list:
-Groupchatcreated (GroupchatcreatedCommand.php)
-Newchatparticipant (NewchatparticipantCommand.php)
-Deletechatphoto (DeletechatphotoCommand.php)
-Newchattitle (NewchattitleCommand.php)
-Leftchatparticipant (LeftchatparticipantCommand.php)
GenericCommand.php let you handle commands that non exist or use commands as var:
Favourite colour? /black /red
Favourite number? /1 /134
Utilis
------
Maybe you would like to develop your own commands. A good practice is to store them outside vendor/. This can be done adding before the method:
```php
$COMMANDS_FOLDER = __DIR__.'/Commands/';
$telegram->addCommandsPath($COMMANDS_FOLDER);
```
Send message to all active chats (new!)
---------------------------------------
To do this you have to enable the mysql connections.
Here's an example of use:
```php
$results = $telegram->sendToActiveChats(
'sendMessage', //callback function to execute (see Request.php methods)
array('text'=>'Hey! Checkout the new feature!!'), //Param to evaluate the request
true, //Send to chats (group chat)
true, //Send to users (single chat)
null, //'yyyy-mm-dd hh:mm:ss' date range from
null //'yyyy-mm-dd hh:mm:ss' date range to
);
print_r($results);
```
Utilis
------
You can also log incoming messages on a text file, set this option with the methods:
```php
$telegram->setLogRequests(true);
$telegram->setLogPath($BOT_NAME.'.log');
$telegram->setLogRequests(true);
$telegram->setLogPath($BOT_NAME.'.log');
```
This code is available on [Github][0]. Pull requests are welcome.
......
<?php
/*
* This file is part of the TelegramBot package.
*
* (c) Avtandil Kikabidze aka LONGMAN <akalongman@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Longman\TelegramBot\Commands;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\Command;
use Longman\TelegramBot\Entities\Update;
class DeletechatphotoCommand extends Command
{
protected $name = 'Deletechatphoto';
protected $description = 'Delete chat photo';
protected $usage = '/';
protected $version = '1.0.0';
protected $enabled = true;
public function execute()
{
$update = $this->getUpdate();
$message = $this->getMessage();
$delete_chat_photo = $message->getDeleteChatPhoto();
// temporary do nothing
}
}
<?php
/*
* This file is part of the TelegramBot package.
*
* (c) Avtandil Kikabidze aka LONGMAN <akalongman@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Longman\TelegramBot\Commands;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\Command;
use Longman\TelegramBot\Entities\Update;
class GenericCommand extends Command
{
protected $name = 'Generic';
protected $description = 'Handle genric commands or is executed by defaul when a command is not found';
protected $usage = '/';
protected $version = '1.0.0';
protected $enabled = true;
public function execute()
{
$update = $this->getUpdate();
$message = $this->getMessage();
//you can use $command as param
$command = $message->getCommand();
$data['text'] = 'Command: '.$command.' not found.. :(';
$result = Request::sendMessage($data);
return $result;
}
}
<?php
/*
* This file is part of the TelegramBot package.
*
* (c) Avtandil Kikabidze aka LONGMAN <akalongman@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Longman\TelegramBot\Commands;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\Command;
use Longman\TelegramBot\Entities\Update;
class GroupchatcreatedCommand extends Command
{
protected $name = 'Groupchatcreated';
protected $description = 'Group chat created';
protected $usage = '/';
protected $version = '1.0.0';
protected $enabled = true;
public function execute()
{
$update = $this->getUpdate();
$message = $this->getMessage();
$group_chat_created = $message->getGroupChatCreated();
// temporary do nothing
}
}
......@@ -16,7 +16,7 @@ use Longman\TelegramBot\Entities\Update;
class LeftchatparticipantCommand extends Command
{
protected $name = 'left_chat_participant';
protected $name = 'leftchatparticipant';
protected $description = 'Left Chat Participant';
protected $usage = '/';
protected $version = '1.0.0';
......
......@@ -16,7 +16,7 @@ use Longman\TelegramBot\Entities\Update;
class NewchatparticipantCommand extends Command
{
protected $name = 'new_chat_participant';
protected $name = 'Newchatparticipant';
protected $description = 'New Chat Participant';
protected $usage = '/';
protected $version = '1.0.0';
......
<?php
/*
* This file is part of the TelegramBot package.
*
* (c) Avtandil Kikabidze aka LONGMAN <akalongman@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Longman\TelegramBot\Commands;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\Command;
use Longman\TelegramBot\Entities\Update;
class NewchattitleCommand extends Command
{
protected $name = 'Newchattitle';
protected $description = 'New chat Title';
protected $usage = '/';
protected $version = '1.0.0';
protected $enabled = true;
public function execute()
{
$update = $this->getUpdate();
$message = $this->getMessage();
$new_chat_title = $message->getNewChatTitle();
// temporary do nothing
}
}
......@@ -57,7 +57,6 @@ class User extends Entity
public function getUsername()
{
return $this->username;
}
}
......@@ -102,6 +102,14 @@ class Request
return $result;
}
public static function getMe()
{
$result = self::send('getMe');
return $result;
}
public static function setWebhook($url)
{
$result = self::send('setWebhook', array('url' => $url));
......
......@@ -30,7 +30,7 @@ class Telegram
*
* @var string
*/
protected $version = '0.0.11';
protected $version = '0.0.15';
/**
* Telegram API key
......@@ -122,9 +122,6 @@ class Telegram
);
/**
* Constructor
*
......@@ -274,11 +271,9 @@ class Telegram
{
$this->input = Request::getInput();
if (empty($this->input)) {
throw new TelegramException('Input is empty!');
}
$post = json_decode($this->input, true);
if (empty($post)) {
throw new TelegramException('Invalid JSON!');
......@@ -290,8 +285,6 @@ class Telegram
$message = $update->getMessage();
// check type
$type = $message->getType();
......@@ -317,53 +310,25 @@ class Telegram
return $this->executeCommand('Leftchatparticipant', $update);
break;
case 'new_chat_title':
// trigger new_chat_title
return $this->executeCommand('Newchattitle', $update);
break;
case 'delete_chat_photo':
// trigger delete_chat_photo
return $this->executeCommand('Deletechatphoto', $update);
break;
case 'group_chat_created':
// trigger group_chat_created
return $this->executeCommand('Groupchatcreated', $update);
break;
}
}
public function eventUserAddedToChat(Update $update)
{
$message = $update->getMessage();
$participant = $message->getNewChatParticipant();
if (!empty($participant)) {
$chat_id = $message->getChat()->getId();
$data = array();
$data['chat_id'] = $chat_id;
if ($participant->getUsername() == $this->getBotName()) {
$text = 'Hi there';
} else {
if ($participant->getUsername()) {
$text = 'Hi @'.$participant->getUsername();
} else {
$text = 'Hi '.$participant->getFirstName();
}
}
$data['text'] = $text;
$result = Request::sendMessage($data);
return $result;
}
}
/**
* Execute /command
*
......@@ -372,8 +337,11 @@ class Telegram
public function executeCommand($command, Update $update)
{
$class = $this->getCommandClass($command, $update);
if (empty($class)) {
return false;
//print_r($class);
if (!$class) {
//handle a generic command or non existing one
return $this->executeCommand('Generic', $update);
}
if (!$class->isEnabled()) {
......@@ -438,13 +406,68 @@ class Telegram
}
/**
*DB Mehods
*
*
*/
//TODO
//Documentation write send message to all
/**
* Enable MySQL integration
*
* @param array $credentials MySQL credentials
*
* @return string
*/
public function enableMySQL(array $credentials, $table_prefix = null)
{
if (empty($credentials)) {
throw new TelegramException('MySQL credentials not provided!');
}
$this->mysql_credentials = $credentials;
$dsn = 'mysql:host=' . $credentials['host'] . ';dbname=' . $credentials['database'];
$options = array(\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',);
try {
$pdo = new \PDO($dsn, $credentials['user'], $credentials['password'], $options);
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_WARNING);
//Define table
define('TB_MESSAGES', $table_prefix.'messages');
define('TB_USERS', $table_prefix.'users');
define('TB_CHATS', $table_prefix.'chats');
define('TB_USERS_CHATS', $table_prefix.'users_chats');
} catch (\PDOException $e) {
throw new TelegramException($e->getMessage());
}
$this->pdo = $pdo;
$this->mysql_enabled = true;
return $this;
}
/**
* Convert from unix timestamp to timestamp
*
* @return string
*/
protected function toTimestamp($time)
{
return date('Y-m-d H:i:s', $time);
}
/**
* Insert request in db
*
* @return bool
*/
protected function insertRequest(Update $update)
// protected function insertRequest(Update $update)
public function insertRequest(Update $update)
{
if (empty($this->pdo)) {
return false;
......@@ -453,61 +476,91 @@ class Telegram
$message = $update->getMessage();
try {
$sth1 = $this->pdo->prepare('INSERT INTO `users`
//Users table
$sth1 = $this->pdo->prepare('INSERT INTO `'.TB_USERS.'`
(
`id`, `username`, `first_name`, `last_name`
`id`, `username`, `first_name`, `last_name`, `created_at`, `updated_at`
)
VALUES (:id, :username, :first_name, :last_name)
ON DUPLICATE KEY UPDATE `username`=:username, `first_name`=:first_name, `last_name`=:last_name
VALUES (
:id, :username, :first_name, :last_name, :date, :date
)
ON DUPLICATE KEY UPDATE `username`=:username, `first_name`=:first_name,
`last_name`=:last_name, `updated_at`=:date
');
$from = $message->getFrom();
$date = $this->toTimestamp($message->getDate());
$user_id = $from->getId();
$username = $from->getUsername();
$first_name = $from->getFirstName();
$last_name = $from->getLastName();
$sth1->bindParam(':id', $user_id, \PDO::PARAM_INT);
$sth1->bindParam(':username', $username, \PDO::PARAM_STR, 255);
$sth1->bindParam(':first_name', $first_name, \PDO::PARAM_STR, 255);
$sth1->bindParam(':last_name', $last_name, \PDO::PARAM_STR, 255);
$sth1->bindParam(':date', $date, \PDO::PARAM_STR);
$status = $sth1->execute();
//chats table
$sth2 = $this->pdo->prepare('INSERT INTO `'.TB_CHATS.'`
(
`id`, `title`, `created_at` ,`updated_at`
)
VALUES (:id, :title, :date, :date)
ON DUPLICATE KEY UPDATE `title`=:title, `updated_at`=:date
');
$chat_id = $message->getChat()->getId();
$chat_title = $message->getChat()->getTitle();
$sth2->bindParam(':id', $chat_id, \PDO::PARAM_INT);
$sth2->bindParam(':title', $chat_title, \PDO::PARAM_STR, 255);
$sth2->bindParam(':date', $date, \PDO::PARAM_STR);
$status = $sth2->execute();
$sth = $this->pdo->prepare('INSERT IGNORE INTO `messages`
//user_chat table
$sth3 = $this->pdo->prepare('INSERT IGNORE INTO `'.TB_USERS_CHATS.'`
(
`update_id`, `message_id`, `user_id`, `date`, `chat`, `forward_from`,
`user_id`, `chat_id`
)
VALUES (:user_id, :chat_id)
');
$sth3->bindParam(':user_id', $user_id, \PDO::PARAM_INT);
$sth3->bindParam(':chat_id', $chat_id, \PDO::PARAM_INT);
$status = $sth3->execute();
//Messages Table
$sth = $this->pdo->prepare('INSERT IGNORE INTO `'.TB_MESSAGES.'`
(
`update_id`, `message_id`, `user_id`, `date`, `chat_id`, `forward_from`,
`forward_date`, `reply_to_message`, `text`
)
VALUES (:update_id, :message_id, :user_id,
:date, :chat, :forward_from,
VALUES (:update_id, :message_id, :user_id, :date, :chat_id, :forward_from,
:forward_date, :reply_to_message, :text)');
$update_id = $update->getUpdateId();
$message_id = $message->getMessageId();
$from = $message->getFrom()->toJSON();
$user_id = $message->getFrom()->getId();
$date = $message->getDate();
$chat = $message->getChat()->toJSON();
$forward_from = $message->getForwardFrom();
$forward_date = $message->getForwardDate();
$forward_date = $this->toTimestamp($message->getForwardDate());
$reply_to_message = $message->getReplyToMessage();
if (is_object($reply_to_message)) {
$reply_to_message = $reply_to_message->toJSON();
}
$text = $message->getText();
$sth->bindParam(':update_id', $update_id, \PDO::PARAM_INT);
$sth->bindParam(':message_id', $message_id, \PDO::PARAM_INT);
$sth->bindParam(':user_id', $user_id, \PDO::PARAM_INT);
$sth->bindParam(':date', $date, \PDO::PARAM_INT);
$sth->bindParam(':chat', $chat, \PDO::PARAM_STR);
$sth->bindParam(':date', $date, \PDO::PARAM_STR);
$sth->bindParam(':chat_id', $chat_id, \PDO::PARAM_STR);
$sth->bindParam(':forward_from', $forward_from, \PDO::PARAM_STR);
$sth->bindParam(':forward_date', $forward_date, \PDO::PARAM_INT);
$sth->bindParam(':forward_date', $forward_date, \PDO::PARAM_STR);
$sth->bindParam(':reply_to_message', $reply_to_message, \PDO::PARAM_STR);
$sth->bindParam(':text', $text, \PDO::PARAM_STR);
......@@ -521,6 +574,97 @@ class Telegram
}
/**
* Send Message in all the active chat
*
* @param date string yyyy-mm-dd hh:mm:ss
*
* @return bool
*/
public function sendToActiveChats(
$callback_function,
array $data,
$send_chats = true,
$send_users = true,
$date_from = null,
$date_to = null
) {
if (empty($this->pdo)) {
return false;
}
$callback_path = __NAMESPACE__ .'\Request';
if (! method_exists($callback_path, $callback_function)) {
throw new TelegramException('Methods: '.$callback_function.' not found in class Request.');
}
if (!$send_chats & !$send_users) {
return false;
}
try {
$query = 'SELECT * ,
'.TB_CHATS.'.`id` AS `chat_id`,
'.TB_CHATS.'.`updated_at` AS `chat_updated_at`
FROM `'.TB_CHATS.'` LEFT JOIN `'.TB_USERS.'`
ON '.TB_CHATS.'.`id`='.TB_USERS.'.`id`';
//Building parts of query
$chat_or_user = '';
$where = [];
$tokens = [];
if ($send_chats & !$send_users) {
$where[] = TB_CHATS.'.`id` < 0';
} elseif (!$send_chats & $send_users) {
$where[] = TB_CHATS.'.`id` > 0';
}
if (! is_null($date_from)) {
$where[] = TB_CHATS.'.`updated_at` >= :date_from';
$tokens[':date_from'] = $date_from;
}
if (! is_null($date_to)) {
$where[] = TB_CHATS.'.`updated_at` <= :date_to';
$tokens[':date_to'] = $date_to;
}
$a=0;
foreach ($where as $part) {
if ($a) {
$query .= ' AND '.$part;
} else {
$query .= ' WHERE '.$part;
++$a;
}
}
echo $query."\n";
$sth = $this->pdo->prepare($query);
$sth->execute($tokens);
$results = [];
while ($row = $sth->fetch(\PDO::FETCH_ASSOC)) {
print_r($row);
$data['chat_id'] = $row['chat_id'];
$results[] = call_user_func_array($callback_path.'::'.$callback_function, array( $data));
}
} catch (PDOException $e) {
throw new TelegramException($e->getMessage());
}
return $results;
}
/**
*End DB Mehods
*
*/
/**
* Add custom commands path
......@@ -608,35 +752,6 @@ class Telegram
return $result['description'];
}
/**
* Enable MySQL integration
*
* @param array $credentials MySQL credentials
*
* @return string
*/
public function enableMySQL(array $credentials)
{
if (empty($credentials)) {
throw new TelegramException('MySQL credentials not provided!');
}
$this->mysql_credentials = $credentials;
$dsn = 'mysql:host=' . $credentials['host'] . ';dbname=' . $credentials['database'];
$options = array(\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',);
try {
$pdo = new \PDO($dsn, $credentials['user'], $credentials['password'], $options);
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_WARNING);
} catch (\PDOException $e) {
throw new TelegramException($e->getMessage());
}
$this->pdo = $pdo;
$this->mysql_enabled = true;
return $this;
}
/**
* Get available message types
*
......
......@@ -2,8 +2,8 @@ CREATE TABLE `messages` (
`update_id` bigint UNSIGNED COMMENT 'The update\'s unique identifier.',
`message_id` bigint COMMENT 'Unique message identifier',
`user_id` bigint COMMENT 'User identifier',
`date` int(11) UNSIGNED COMMENT 'Date the message was sent in Unix time',
`chat` CHAR(255) COMMENT 'User or GroupChat object. Conversation the message belongs to — user in case of a private message, GroupChat in case of a group',
`date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Date the message was sent in timestamp format',
`chat_id` bigint NOT NULL DEFAULT '0' COMMENT 'User or GroupChat object. Conversation the message belongs to — user in case of a private message, GroupChat in case of a group',
`forward_from` CHAR(255) DEFAULT '' COMMENT 'User object. For forwarded messages, sender of the original message',
`forward_date` int(11) UNSIGNED DEFAULT 0 COMMENT 'For forwarded messages, date the original message was sent in Unix time',
`reply_to_message` LONGTEXT COMMENT 'Message object. For replies, the original message. Note that the Message object in this field will not contain further reply_to_message fields even if it itself is a reply.',
......@@ -24,13 +24,37 @@ CREATE TABLE `messages` (
PRIMARY KEY (`update_id`),
KEY `message_id` (`message_id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE `users` (
`id` bigint UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Unique user identifier',
`username` CHAR(255) NOT NULL DEFAULT '' COMMENT 'User username',
`id` bigint NOT NULL DEFAULT '0' COMMENT 'Unique user identifier',
`first_name` CHAR(255) NOT NULL DEFAULT '' COMMENT 'User first name',
`last_name` CHAR(255) NOT NULL DEFAULT '' COMMENT 'User last name',
`last_name` CHAR(255) DEFAULT '' COMMENT 'User last name',
`username` CHAR(255) DEFAULT '' COMMENT 'User username',
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Entry date creation',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Entry date update',
PRIMARY KEY (`id`),
KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci
\ No newline at end of file
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE `chats` (
`id` bigint NOT NULL DEFAULT '0' COMMENT 'Unique user or chat identifier',
`title` CHAR(255) DEFAULT '' COMMENT 'chat title null if case of single chat with the bot',
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Entry date creation',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Entry date update',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
CREATE TABLE `users_chats` (
`user_id` bigint NOT NULL DEFAULT '0' COMMENT 'Unique user identifier',
`chat_id` bigint NOT NULL DEFAULT '0' COMMENT 'Unique user or chat identifier',
PRIMARY KEY (`user_id`, `chat_id`),
FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (`chat_id`) REFERENCES `chats` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment