Commit 95a6dced authored by MBoretto's avatar MBoretto

resolve merge conflicts

parents e060ae01 22bda564
sudo: false
dist: trusty
sudo: required
addons:
apt:
packages:
- mysql-server-5.6
- mysql-client-core-5.6
- mysql-client-5.6
language: php
......@@ -27,7 +35,7 @@ install:
- travis_retry composer install --no-interaction
before_script:
- mysql -e 'create database telegrambot; use telegrambot; source structure.sql;'
- mysql -u root -e 'create database telegrambot; use telegrambot; source structure.sql;'
script:
- ./vendor/bin/phpunit
......
......@@ -21,3 +21,8 @@ N: Armando Lüscher
E: armando@noplanman.ch
W: http://noplanman.ch
D: Maintainer and Collaborator
N: Jack'lul (alias)
E: jacklul@jacklul.com
W: http://jacklul.com
D: Maintainer and Collaborator
......@@ -34,6 +34,7 @@ A Telegram Bot based on the official [Telegram Bot API](https://core.telegram.or
- [Utils](#utils)
- [MySQL storage (Recommended)](#mysql-storage-recommended)
- [Channels Support](#channels-support)
- [Botan.io integration (Optional)](#botanio-integration-optional)
- [Commands](#commands)
- [Predefined Commands](#predefined-commands)
- [Custom Commands](#custom-commands)
......@@ -42,7 +43,7 @@ A Telegram Bot based on the official [Telegram Bot API](https://core.telegram.or
- [Set Admins](#set-admins)
- [Channel Administration](#channel-administration)
- [Upload and Download directory path](#upload-and-download-directory-path)
- [Logging](#logging)
- [Logging](doc/01-utils.md)
- [Documentation](#documentation)
- [Projects with this library](#projects-with-this-library)
- [Troubleshooting](#troubleshooting)
......@@ -66,14 +67,15 @@ and have interactions in a matter of minutes.
The Bot can:
- retrieve updates with webhook and getUpdate methods.
- supports all types and methods according to Telegram API (6 May 2016).
- supports all types and methods according to Telegram API (25 May 2016).
- supports supergroups.
- handle commands in chat with other bots.
- manage Channel from the bot admin interface.
- full support for **inline bots**.
- inline keyboard.
- Messages, InlineQuery and ChosenInlineQuery are stored in the Database.
- Conversation feature (**new!**)
- *Botan.io* integration and database cache system. (**new!**)
- Conversation feature
-----
This code is available on
......@@ -401,6 +403,27 @@ $telegram->enableExternalMysql($external_pdo_connection)
All methods implemented can be used to manage channels.
With [admin commands](#admin-commands) you can manage your channels directly with your bot private chat.
### Botan.io integration (Optional)
You can enable the integration using this line:
```php
$telegram->enableBotan('your_token');
```
Replace ```'your_token'``` with your Botan.io token, check [this page](https://github.com/botanio/sdk#creating-an-account) to see how to obtain one.
The following actions will be tracked:
- Commands (shown as `Command (/command_name)` in the stats
- Inline Queries, Chosen Inline Results and Callback Queries
- Messages sent to the bot (or replies in groups)
In order to use the URL shortener you must include the class ```use Longman\TelegramBot\Botan;``` and call it like this:
```Botan::shortenUrl('https://github.com/akalongman/php-telegram-bot', $user_id);```
Shortened URLs are cached in the database (if MySQL storage is enabled).
### Commands
#### Predefined Commands
......@@ -441,10 +464,14 @@ Inside *examples/Commands/* there are some samples that show how to use types.
#### Commands Configuration
With this method you can set some command specific parameters, for
example, google geocode/timezone api key for date command:
With this method you can set some command specific parameters:
```php
//Google geocode/timezone API key for date command
$telegram->setCommandConfig('date', ['google_api_key' => 'your_google_api_key_here']);
//OpenWeatherMap API key for weather command
$telegram->setCommandConfig('weather', ['owm_api_key' => 'your_owm_api_key_here']);
```
### Admin Commands
......@@ -489,27 +516,6 @@ $telegram->setDownloadPath('yourpath/Download');
$telegram->setUploadPath('yourpath/Upload');
```
### Logging
Thrown Exceptions are not stored by default. You can Enable this feature adding this line in your 'webhook.php' or 'getUpdates.php'
```php
Longman\TelegramBot\Logger::initialize('your_path/TelegramException.log');
```
Incoming update (json string from webhook and getUpdates) can be logged in a text file. Set those options with the methods:
```php
$telegram->setLogRequests(true);
$telegram->setLogPath($BOT_NAME . '.log');
```
Set verbosity to 3 to also log curl requests and responses from the bot to Telegram:
```php
$telegram->setLogRequests(true);
$telegram->setLogPath($BOT_NAME . '.log');
$telegram->setLogVerbosity(3);
```
## Documentation
Take a look at the repo [Wiki](https://github.com/akalongman/php-telegram-bot/wiki) for further information and tutorials!
......
......@@ -20,7 +20,9 @@
"require": {
"php": ">=5.5.0",
"ext-pdo": "*",
"ext-curl": "*"
"ext-curl": "*",
"monolog/monolog": "^1.19",
"guzzlehttp/guzzle": "~6.0"
},
"autoload": {
"psr-4": {
......
This diff is collapsed.
## Logging
Telegram bot library feats [Monolog](https://github.com/Seldaek/monolog) to store logs.
Logs are divided in those streams:
### Error
Collects all the exceptions throwned by the library:
```php
TelegramLog::initErrorLog($path . '/' . $BOT_NAME . '_error.log');
```
### Debug
Stores Curl messages with the server, useful for debugging:
```php
TelegramLog::initDebugLog($path . '/' . $BOT_NAME . '_debug.log');
```
### Raw data
Incoming updates (json string from webhook and getUpdates) can be logged in a text file. Set this option with the methods:
```php
TelegramLog::initUpdateLog($path . '/' . $BOT_NAME . '_update.log');
```
Why I need raw log?
Telegram api changes continuously and often happen that db schema is not uptodate with new entities/features. So can happen that your table schema would not be able to store valuable new information coming from Telegram.
If you store raw data you can port all updates on the newest table schema just using [this script](../utils/importFromLog.php).
Remember always backup first!!
## Stream and external sources
Error and Debug streams relies on the `bot_log` instance that can be provided from an external source:
```php
TelegramLog::initialize($monolog);
```
Raw data relies on the `bot_update_log` instance that feats a custom format for this kind of logs.
......@@ -13,6 +13,7 @@ namespace Longman\TelegramBot\Commands\UserCommands;
use Longman\TelegramBot\Commands\UserCommand;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\Entities\InlineKeyboardMarkup;
use Longman\TelegramBot\Entities\InlineKeyboardButton;
/**
* User "/inlinekeyboard" command
......@@ -22,8 +23,8 @@ class InlinekeyboardCommand extends UserCommand
/**#@+
* {@inheritdoc}
*/
protected $name = 'inlinekeyboard';
protected $description = 'Show a custom inline keybord with reply markup';
protected $name = 'Inlinekeyboard';
protected $description = 'Show inline keyboard';
protected $usage = '/inlinekeyboard';
protected $version = '0.0.1';
/**#@-*/
......@@ -34,104 +35,18 @@ class InlinekeyboardCommand extends UserCommand
public function execute()
{
$message = $this->getMessage();
$chat_id = $message->getChat()->getId();
$text = $message->getText(true);
$data = [];
$data['chat_id'] = $chat_id;
$data['text'] = 'Press a Button:';
//Keyboard examples
$inline_keyboards = [];
//0
$inline_keyboard[] = [
[
'text' => '<',
'callback_data' => 'go_left'
],
[
'text' => '^',
'callback_data' => 'go_up'
],
[
'text' => '>',
'callback_data' => 'go_right'
]
];
$inline_keyboards[] = $inline_keyboard;
unset($inline_keyboard);
//1
$inline_keyboard[] = [
[
'text' => 'open google.com',
'url' => 'google.com'
],
[
'text' => 'open youtube.com',
'url' => 'youtube.com'
]
];
$inline_keyboards[] = $inline_keyboard;
unset($inline_keyboard);
//2
$inline_keyboard[] = [
[
'text' => 'search \'test\' inline',
'switch_inline_query' => 'test'
],
[
'text' => 'search \'cats\' inline',
'switch_inline_query' => 'cats'
]
$inline_keyboard = [
new InlineKeyboardButton(['text' => 'inline', 'switch_inline_query' => 'true']),
new InlineKeyboardButton(['text' => 'callback', 'callback_data' => 'identifier']),
new InlineKeyboardButton(['text' => 'open url', 'url' => 'https://github.com/akalongman/php-telegram-bot']),
];
$inline_keyboard[] = [
[
'text' => 'search \'earth\' inline',
'switch_inline_query' => 'earth'
],
$data = [
'chat_id' => $message->getChat()->getId(),
'text' => 'inline keyboard',
'reply_markup' => new InlineKeyboardMarkup(['inline_keyboard' => [$inline_keyboard]]),
];
$inline_keyboards[] = $inline_keyboard;
unset($inline_keyboard);
//3
$inline_keyboard[] = [
[
'text' => 'open url',
'url' => 'https://github.com/akalongman/php-telegram-bot'
]
];
$inline_keyboard[] = [
[
'text' => 'switch to inline',
'switch_inline_query' => 'thumb up'
]
];
$inline_keyboard[] = [
[
'text' => 'send callback query',
'callback_data' => 'thumb up'
],
[
'text' => 'send callback query (no alert)',
'callback_data' => 'thumb down'
]
];
$inline_keyboards[] = $inline_keyboard;
unset($inline_keyboard);
$data['reply_markup'] = new InlineKeyboardMarkup(
[
'inline_keyboard' => $inline_keyboards[3],
]
);
return Request::sendMessage($data);
}
}
......@@ -4,8 +4,8 @@
//This configuration file is intented to run the bot with the webhook method
//Uncommented parameters must be filled
#bash script
#while true; do ./getUpdatesCLI.php; done
//bash script
//while true; do ./getUpdatesCLI.php; done
// Load composer
require __DIR__ . '/vendor/autoload.php';
......@@ -42,14 +42,18 @@ try {
//$telegram->setCommandConfig('date', ['google_api_key' => 'your_google_api_key_here']);
//// Logging
//$telegram->setLogRequests(true);
//$telegram->setLogPath($BOT_NAME . '.log');
//$telegram->setLogVerbosity(3);
//\Longman\TelegramBot\TelegramLog::initialize($your_external_monolog_instance);
//\Longman\TelegramBot\TelegramLog::initErrorLog($path . '/' . $BOT_NAME . '_error.log');
//\Longman\TelegramBot\TelegramLog::initDebugLog($path . '/' . $BOT_NAME . '_debug.log');
//\Longman\TelegramBot\TelegramLog::initUpdateLog($path . '/' . $BOT_NAME . '_update.log');
//// Set custom Upload and Download path
//$telegram->setDownloadPath('../Download');
//$telegram->setUploadPath('../Upload');
//// Botan.io integration
//$telegram->enableBotan('your_token');
// Handle telegram getUpdate request
$ServerResponse = $telegram->handleGetUpdates();
......@@ -61,6 +65,10 @@ try {
echo $ServerResponse->printError() . "\n";
}
} catch (Longman\TelegramBot\Exception\TelegramException $e) {
echo $e;
// log telegram errors
\Longman\TelegramBot\TelegramLog::error($e);
} catch (Longman\TelegramBot\Exception\TelegramLogException $e) {
//catch log initilization errors
echo $e;
}
......@@ -3,7 +3,7 @@
//This configuration file is intended to run the bot with the webhook method.
//Uncommented parameters must be filled
//Please notice that if you open this file with your browser you'll get the "Input is empty!" Exception.
//This is a normal behaviour because this address has to be reached only by Telegram server
//This is a normal behaviour because this address has to be reached only by Telegram server.
// Load composer
require __DIR__ . '/vendor/autoload.php';
......@@ -40,18 +40,26 @@ try {
//$telegram->setCommandConfig('date', ['google_api_key' => 'your_google_api_key_here']);
//// Logging
//$telegram->setLogRequests(true);
//$telegram->setLogPath($BOT_NAME . '.log');
//$telegram->setLogVerbosity(3);
//\Longman\TelegramBot\TelegramLog::initialize($your_external_monolog_instance);
//\Longman\TelegramBot\TelegramLog::initErrorLog($path . '/' . $BOT_NAME . '_error.log');
//\Longman\TelegramBot\TelegramLog::initDebugLog($path . '/' . $BOT_NAME . '_debug.log');
//\Longman\TelegramBot\TelegramLog::initUpdateLog($path . '/' . $BOT_NAME . '_update.log');
//// Set custom Upload and Download path
//$telegram->setDownloadPath('../Download');
//$telegram->setUploadPath('../Upload');
//// Botan.io integration
//$telegram->enableBotan('your_token');
// Handle telegram webhook request
$telegram->handle();
} catch (Longman\TelegramBot\Exception\TelegramException $e) {
// Silence is golden!
// log telegram errors
// Silence is gold!
// echo $e;
// log telegram errors
\Longman\TelegramBot\TelegramLog::error($e);
} catch (Longman\TelegramBot\Exception\TelegramLogException $e) {
// Silence is gold! Uncomment this to catch log initilization errors
//echo $e;
}
<?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;
use Longman\TelegramBot\Exception\TelegramException;
/**
* Class Botan
*
* Integration with http://botan.io statistics service for Telegram bots
*/
class Botan
{
/**
* @var string Tracker request url
*/
protected static $track_url = 'https://api.botan.io/track?token=#TOKEN&uid=#UID&name=#NAME';
/**
* @var string Url Shortener request url
*/
protected static $shortener_url = 'https://api.botan.io/s/?token=#TOKEN&user_ids=#UID&url=#URL';
/**
* @var string Yandex AppMetrica application key
*/
protected static $token = '';
/**
* @var string The actual command that is going to be reported
*/
public static $command = '';
/**
* Initilize botan
*/
public static function initializeBotan($token)
{
if (empty($token) || !is_string($token)) {
throw new TelegramException('Botan token should be a string!');
}
self::$token = $token;
BotanDB::initializeBotanDb();
}
/**
* Lock function to make sure only the first command is reported
* ( in case commands are calling other commands $telegram->executedCommand() )
*
* @param string $command
*/
public static function lock($command = '')
{
if (empty(self::$command)) {
self::$command = $command;
}
}
/**
* Track function
*
* @param string $input
* @param string $command
*
* @return bool|string
* @throws TelegramException
*/
public static function track($input, $command = '')
{
if (empty(self::$token) || $command != self::$command) {
return false;
}
if (empty($input)) {
throw new TelegramException('Input is empty!');
}
self::$command = '';
$obj = json_decode($input, true);
if (isset($obj['message'])) {
$data = $obj['message'];
$event_name = 'Message';
if (isset($obj['message']['entities']) && is_array($obj['message']['entities'])) {
foreach ($obj['message']['entities'] as $entity) {
if ($entity['type'] == 'bot_command' && $entity['offset'] == 0) {
if (strtolower($command) == 'generic') {
$command = 'Generic';
} elseif (strtolower($command) == 'genericmessage') {
$command = 'Generic Message';
} else {
$command = '/' . strtolower($command);
}
$event_name = 'Command (' . $command . ')';
break;
}
}
}
} elseif (isset($obj['inline_query'])) {
$data = $obj['inline_query'];
$event_name = 'Inline Query';
} elseif (isset($obj['chosen_inline_result'])) {
$data = $obj['chosen_inline_result'];
$event_name = 'Chosen Inline Result';
} elseif (isset($obj['callback_query'])) {
$data = $obj['callback_query'];
$event_name = 'Callback Query';
}
if (empty($event_name)) {
return false;
}
$uid = $data['from']['id'];
$request = str_replace(
['#TOKEN', '#UID', '#NAME'],
[self::$token, $uid, urlencode($event_name)],
self::$track_url
);
$options = [
'http' => [
'header' => 'Content-Type: application/json',
'method' => 'POST',
'content' => json_encode($data),
'ignore_errors' => true
]
];
$context = stream_context_create($options);
$response = @file_get_contents($request, false, $context);
$responseData = json_decode($response, true);
if ($responseData['status'] != 'accepted') {
error_log('Botan.io API replied with error: ' . $response);
}
return $responseData;
}
/**
* Url Shortener function
*
* @param $url
* @param $user_id
*
* @return string
* @throws TelegramException
*/
public static function shortenUrl($url, $user_id)
{
if (empty(self::$token)) {
return $url;
}
if (empty($user_id)) {
throw new TelegramException('User id is empty!');
}
$cached = BotanDB::selectShortUrl($user_id, $url);
if (!empty($cached[0]['short_url'])) {
return $cached[0]['short_url'];
}
$request = str_replace(
['#TOKEN', '#UID', '#URL'],
[self::$token, $user_id, urlencode($url)],
self::$shortener_url
);
$options = [
'http' => [
'ignore_errors' => true,
'timeout' => 3
]
];
$context = stream_context_create($options);
$response = @file_get_contents($request, false, $context);
if (!filter_var($response, FILTER_VALIDATE_URL) === false) {
BotanDB::insertShortUrl($user_id, $url, $response);
} else {
error_log('Botan.io API replied with error: ' . $response);
return $url;
}
return $response;
}
}
<?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;
use Longman\TelegramBot\DB;
use Longman\TelegramBot\Exception\TelegramException;
/**
* Class BotanDB
*/
class BotanDB extends DB
{
/**
* Initilize botan shortener table
*/
public static function initializeBotanDb()
{
if (!defined('TB_BOTAN_SHORTENER')) {
define('TB_BOTAN_SHORTENER', self::$table_prefix . 'botan_shortener');
}
}
/**
* Select cached shortened URL from the database
*
* @param $user_id
* @param $url
* @return bool|string
* @throws TelegramException
*/
public static function selectShortUrl($user_id, $url)
{
if (!self::isDbConnected()) {
return false;
}
try {
$sth = self::$pdo->prepare('SELECT * FROM `' . TB_BOTAN_SHORTENER . '`
WHERE `user_id` = :user_id AND `url` = :url
');
$sth->bindParam(':user_id', $user_id, \PDO::PARAM_INT);
$sth->bindParam(':url', $url, \PDO::PARAM_INT);
$sth->execute();
$results = $sth->fetchAll(\PDO::FETCH_ASSOC);
} catch (\Exception $e) {
throw new TelegramException($e->getMessage());
}
return $results;
}
/**
* Insert shortened URL into the database
*
* @param $user_id
* @param $url
* @param $short_url
* @return bool
* @throws TelegramException
*/
public static function insertShortUrl($user_id, $url, $short_url)
{
if (!self::isDbConnected()) {
return false;
}
try {
$sth = self::$pdo->prepare('INSERT INTO `' . TB_BOTAN_SHORTENER . '`
(
`user_id`, `url`, `short_url`, `created_at`
)
VALUES (
:user_id, :url, :short_url, :date
)
');
$created_at = self::getTimestamp();
$sth->bindParam(':user_id', $user_id);
$sth->bindParam(':url', $url);
$sth->bindParam(':short_url', $short_url);
$sth->bindParam(':date', $created_at);
$status = $sth->execute();
} catch (\Exception $e) {
throw new TelegramException($e->getMessage());
}
return $status;
}
}
......@@ -31,8 +31,6 @@ class SendtoallCommand extends AdminCommand
/**
* Execute command
*
* @todo Don't use empty, as a string of '0' is regarded to be empty
*
* @return boolean
*/
public function execute()
......@@ -42,7 +40,7 @@ class SendtoallCommand extends AdminCommand
$chat_id = $message->getChat()->getId();
$text = $message->getText(true);
if (empty($text)) {
if ($text === '') {
$text = 'Write the message to send: /sendtoall <message>';
} else {
$results = Request::sendToActiveChats(
......
......@@ -67,7 +67,7 @@ class SendtochannelCommand extends AdminCommand
switch ($state) {
case -1:
// getConfig has not been configured asking for channel to administer
if ($type != 'Message' || empty($text)) {
if ($type != 'Message' || $text === '') {
$this->conversation->notes['state'] = -1;
$this->conversation->update();
......@@ -116,7 +116,7 @@ class SendtochannelCommand extends AdminCommand
// no break
case 1:
insert:
if ($this->conversation->notes['last_message_id'] == $message->getMessageId() || ($type == 'Message' && empty($text))) {
if ($this->conversation->notes['last_message_id'] == $message->getMessageId() || ($type == 'Message' && $text === '')) {
$this->conversation->notes['state'] = 1;
$this->conversation->update();
......@@ -245,7 +245,7 @@ class SendtochannelCommand extends AdminCommand
$data = [];
$data['chat_id'] = $chat_id;
if (empty($text)) {
if ($text === '') {
$data['text'] = 'Usage: /sendtochannel <text>';
} else {
$channels = (array) $this->getConfig('your_channel');
......
<?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\SystemCommands;
use Longman\TelegramBot\Commands\SystemCommand;
/**
* Edited message command
*/
class EditedmessageCommand extends SystemCommand
{
/**#@+
* {@inheritdoc}
*/
protected $name = 'editedmessage';
protected $description = 'User edited message';
protected $version = '1.0.0';
/**#@-*/
/**
* {@inheritdoc}
*/
/*public function execute()
{
$update = $this->getUpdate();
$edited_message = $update->getEditedMessage();
}*/
}
......@@ -12,6 +12,7 @@ namespace Longman\TelegramBot\Commands\SystemCommands;
use Longman\TelegramBot\Commands\SystemCommand;
use Longman\TelegramBot\Entities\InlineQueryResultArticle;
use Longman\TelegramBot\Entities\InputTextMessageContent;
use Longman\TelegramBot\Request;
/**
......@@ -39,9 +40,9 @@ class InlinequeryCommand extends SystemCommand
$data = ['inline_query_id' => $inline_query->getId()];
$articles = [
['id' => '001', 'title' => 'https://core.telegram.org/bots/api#answerinlinequery', 'message_text' => 'you enter: ' . $query , 'input_message_content' => [ 'message_text' => $query ] ],
['id' => '002', 'title' => 'https://core.telegram.org/bots/api#answerinlinequery', 'message_text' => 'you enter: ' . $query , 'input_message_content' => [ 'message_text' => $query ] ],
['id' => '003', 'title' => 'https://core.telegram.org/bots/api#answerinlinequery', 'message_text' => 'you enter: ' . $query , 'input_message_content' => [ 'message_text' => $query ] ],
['id' => '001', 'title' => 'https://core.telegram.org/bots/api#answerinlinequery', 'message_text' => 'you enter: ' . $query , 'input_message_content' => new InputTextMessageContent([ 'message_text' => ' ' . $query ])],
['id' => '002', 'title' => 'https://core.telegram.org/bots/api#answerinlinequery', 'message_text' => 'you enter: ' . $query , 'input_message_content' => new InputTextMessageContent([ 'message_text' => ' ' . $query ])],
['id' => '003', 'title' => 'https://core.telegram.org/bots/api#answerinlinequery', 'message_text' => 'you enter: ' . $query , 'input_message_content' => new InputTextMessageContent([ 'message_text' => ' ' . $query ])],
];
$array_article = [];
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
This diff is collapsed.
......@@ -21,10 +21,8 @@ class Audio extends Entity
protected $mime_type;
protected $file_size;
public function __construct(array $data)
{
$this->file_id = isset($data['file_id']) ? $data['file_id'] : null;
if (empty($this->file_id)) {
throw new TelegramException('file_id is empty!');
......@@ -40,7 +38,6 @@ class Audio extends Entity
$this->title = isset($data['title']) ? $data['title'] : null;
$this->mime_type = isset($data['mime_type']) ? $data['mime_type'] : null;
$this->file_size = isset($data['file_size']) ? $data['file_size'] : null;
}
public function getFileId()
......@@ -57,10 +54,12 @@ class Audio extends Entity
{
return $this->performer;
}
public function getTitle()
{
return $this->title;
}
public function getMimeType()
{
return $this->mime_type;
......
......@@ -14,7 +14,6 @@ use Longman\TelegramBot\Exception\TelegramException;
class Chat extends Entity
{
protected $id;
protected $type;
protected $title;
......@@ -81,37 +80,31 @@ class Chat extends Entity
public function getId()
{
return $this->id;
}
public function getType()
{
return $this->type;
}
public function getTitle()
{
return $this->title;
}
public function getFirstName()
{
return $this->first_name;
}
public function getLastName()
{
return $this->last_name;
}
public function getUsername()
{
return $this->username;
}
......
<?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\Entities;
class ChatMember extends Entity
{
protected $user;
protected $status;
public function __construct(array $data)
{
$this->user = isset($data['user']) ? $data['user'] : null;
if (empty($this->user)) {
throw new TelegramException('user is empty!');
}
$this->user = new User($data['user']);
$this->status = isset($data['status']) ? $data['status'] : null;
if ($this->status === '') {
throw new TelegramException('status is empty!');
}
}
public function getUser()
{
return $this->user;
}
public function getStatus()
{
return $this->status;
}
}
......@@ -14,7 +14,6 @@ use Longman\TelegramBot\Exception\TelegramException;
class ChosenInlineResult extends Entity
{
protected $result_id;
protected $from;
protected $location;
......@@ -23,7 +22,6 @@ class ChosenInlineResult extends Entity
public function __construct(array $data)
{
$this->result_id = isset($data['result_id']) ? $data['result_id'] : null;
if (empty($this->result_id)) {
throw new TelegramException('result_id is empty!');
......
......@@ -14,7 +14,6 @@ use Longman\TelegramBot\Exception\TelegramException;
class Contact extends Entity
{
protected $phone_number;
protected $first_name;
protected $last_name;
......@@ -22,7 +21,6 @@ class Contact extends Entity
public function __construct(array $data)
{
$this->phone_number = isset($data['phone_number']) ? $data['phone_number'] : null;
if (empty($this->phone_number)) {
throw new TelegramException('phone_number is empty!');
......
......@@ -22,7 +22,6 @@ class Document extends Entity
public function __construct(array $data)
{
$this->file_id = isset($data['file_id']) ? $data['file_id'] : null;
if (empty($this->file_id)) {
throw new TelegramException('file_id is empty!');
......@@ -36,7 +35,6 @@ class Document extends Entity
$this->file_name = isset($data['file_name']) ? $data['file_name'] : null;
$this->mime_type = isset($data['mime_type']) ? $data['mime_type'] : null;
$this->file_size = isset($data['file_size']) ? $data['file_size'] : null;
}
public function getFileId()
......@@ -46,21 +44,21 @@ class Document extends Entity
public function getThumb()
{
return $this->thumb;
return $this->thumb;
}
public function getFileName()
{
return $this->file_name;
return $this->file_name;
}
public function getMimeType()
{
return $this->mime_type;
return $this->mime_type;
}
public function getFileSize()
{
return $this->file_size;
return $this->file_size;
}
}
......@@ -14,10 +14,8 @@ class Entity
{
protected $bot_name;
public function getBotName()
{
return $this->bot_name;
}
......@@ -77,6 +75,9 @@ class Entity
} elseif ($array_of_array_obj) {
foreach ($object->$name as $elm) {
$temp = null;
if (!is_array($elm) && !is_object($elm)) {
continue;
}
foreach ($elm as $obj) {
$temp[] = $this->reflect($obj);
}
......
......@@ -20,7 +20,6 @@ class File extends Entity
public function __construct(array $data)
{
$this->file_id = isset($data['file_id']) ? $data['file_id'] : null;
if (empty($this->file_id)) {
throw new TelegramException('file_id is empty!');
......@@ -29,7 +28,6 @@ class File extends Entity
$this->file_size = isset($data['file_size']) ? $data['file_size'] : null;
$this->file_path = isset($data['file_path']) ? $data['file_path'] : null;
}
public function getFileId()
......@@ -39,11 +37,11 @@ class File extends Entity
public function getFileSize()
{
return $this->file_size;
return $this->file_size;
}
public function getFilePath()
{
return $this->file_path;
return $this->file_path;
}
}
......@@ -19,6 +19,9 @@ class InlineKeyboardButton extends Entity
protected $callback_data;
protected $switch_inline_query;
/**
* @todo check if only one of 'url, callback_data, switch_inline_query' fields is set, documentation states that only one of these can be used
*/
public function __construct($data = array())
{
$this->text = isset($data['text']) ? $data['text'] : null;
......@@ -30,12 +33,8 @@ class InlineKeyboardButton extends Entity
$this->callback_data = isset($data['callback_data']) ? $data['callback_data'] : null;
$this->switch_inline_query = isset($data['switch_inline_query']) ? $data['switch_inline_query'] : null;
if (empty($this->url) && empty($this->callback_data) && empty($this->switch_inline_query)) {
if ($this->url === '' && $this->callback_data === '' && $this->switch_inline_query === '') {
throw new TelegramException('You must use at least one of these fields: url, callback_data, switch_inline_query!');
}
/*
* @todo check if only one of 'url, callback_data, switch_inline_query' fields is set, documentation states that only one of these can be used
*/
}
}
......@@ -16,9 +16,6 @@ class InlineKeyboardMarkup extends Entity
{
protected $inline_keyboard;
/*
* @todo check for InlineKeyboardButton elements
*/
public function __construct($data = array())
{
if (isset($data['inline_keyboard'])) {
......
......@@ -14,7 +14,6 @@ use Longman\TelegramBot\Exception\TelegramException;
class InlineQuery extends Entity
{
protected $id;
protected $from;
protected $location;
......@@ -23,7 +22,6 @@ class InlineQuery extends Entity
public function __construct(array $data)
{
$this->id = isset($data['id']) ? $data['id'] : null;
if (empty($this->id)) {
throw new TelegramException('id is empty!');
......@@ -48,18 +46,22 @@ class InlineQuery extends Entity
{
return $this->id;
}
public function getFrom()
{
return $this->from;
}
public function getLocation()
{
return $this->location;
}
public function getQuery()
{
return $this->query;
}
public function getOffset()
{
return $this->offset;
......
......@@ -35,8 +35,19 @@ class InlineQueryResult extends Entity
{
return $this->type;
}
public function getId()
{
return $this->id;
}
public function getInputMessageContent()
{
return $this->input_message_content;
}
public function getReplyMarkup()
{
return $this->reply_markup;
}
}
......@@ -45,7 +45,6 @@ class InlineQueryResultArticle extends InlineQueryResult
$this->thumb_url = isset($data['thumb_url']) ? $data['thumb_url'] : null;
$this->thumb_width = isset($data['thumb_width']) ? $data['thumb_width'] : null;
$this->thumb_height = isset($data['thumb_height']) ? $data['thumb_height'] : null;
}
public function getTitle()
......
<?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\Entities;
use Longman\TelegramBot\Exception\TelegramException;
class InlineQueryResultCachedAudio extends InlineQueryResult
{
protected $audio_file_id;
public function __construct(array $data)
{
parent::__construct($data);
$this->type = 'audio';
$this->audio_file_id = isset($data['audio_file_id']) ? $data['audio_file_id'] : null;
if (empty($this->audio_file_id)) {
throw new TelegramException('audio_file_id is empty!');
}
}
public function getAudioFileId()
{
return $this->audio_file_id;
}
}
<?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\Entities;
use Longman\TelegramBot\Exception\TelegramException;
class InlineQueryResultCachedDocument extends InlineQueryResult
{
protected $document_file_id;
protected $title;
protected $description;
protected $caption;
public function __construct(array $data)
{
parent::__construct($data);
$this->type = 'document';
$this->document_file_id = isset($data['document_file_id']) ? $data['document_file_id'] : null;
if (empty($this->document_file_id)) {
throw new TelegramException('document_file_id is empty!');
}
$this->title = isset($data['title']) ? $data['title'] : null;
if (empty($this->title)) {
throw new TelegramException('title is empty!');
}
$this->description = isset($data['description']) ? $data['description'] : null;
$this->caption = isset($data['caption']) ? $data['caption'] : null;
}
public function getDocumentFileId()
{
return $this->document_file_id;
}
public function getTitle()
{
return $this->title;
}
public function getDescription()
{
return $this->description;
}
public function getCaption()
{
return $this->caption;
}
}
<?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\Entities;
use Longman\TelegramBot\Exception\TelegramException;
class InlineQueryResultCachedGif extends InlineQueryResult
{
protected $gif_file_id;
protected $title;
protected $description;
protected $caption;
public function __construct(array $data)
{
parent::__construct($data);
$this->type = 'gif';
$this->gif_file_id = isset($data['gif_file_id']) ? $data['gif_file_id'] : null;
if (empty($this->gif_file_id)) {
throw new TelegramException('gif_file_id is empty!');
}
$this->title = isset($data['title']) ? $data['title'] : null;
$this->caption = isset($data['caption']) ? $data['caption'] : null;
}
public function getGifFileId()
{
return $this->gif_file_id;
}
public function getTitle()
{
return $this->title;
}
public function getCaption()
{
return $this->caption;
}
}
<?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\Entities;
use Longman\TelegramBot\Exception\TelegramException;
class InlineQueryResultCachedMpeg4Gif extends InlineQueryResult
{
protected $mpeg4_file_id;
protected $title;
protected $caption;
public function __construct(array $data)
{
parent::__construct($data);
$this->type = 'mpeg4_gif';
$this->mpeg4_file_id = isset($data['mpeg4_file_id']) ? $data['mpeg4_file_id'] : null;
if (empty($this->mpeg4_file_id)) {
throw new TelegramException('mpeg4_file_id is empty!');
}
$this->title = isset($data['title']) ? $data['title'] : null;
$this->caption = isset($data['caption']) ? $data['caption'] : null;
}
public function getMpeg4FileId()
{
return $this->mpeg4_file_id;
}
public function getTitle()
{
return $this->title;
}
public function getCaption()
{
return $this->caption;
}
}
<?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\Entities;
use Longman\TelegramBot\Exception\TelegramException;
class InlineQueryResultCachedPhoto extends InlineQueryResult
{
protected $photo_file_id;
protected $title;
protected $description;
protected $caption;
public function __construct(array $data)
{
parent::__construct($data);
$this->type = 'photo';
$this->photo_file_id = isset($data['photo_file_id']) ? $data['photo_file_id'] : null;
if (empty($this->photo_file_id)) {
throw new TelegramException('photo_file_id is empty!');
}
$this->title = isset($data['title']) ? $data['title'] : null;
$this->description = isset($data['description']) ? $data['description'] : null;
$this->caption = isset($data['caption']) ? $data['caption'] : null;
}
public function getPhotoFileId()
{
return $this->photo_file_id;
}
public function getTitle()
{
return $this->title;
}
public function getDescription()
{
return $this->description;
}
public function getCaption()
{
return $this->caption;
}
}
<?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\Entities;
use Longman\TelegramBot\Exception\TelegramException;
class InlineQueryResultCachedSticker extends InlineQueryResult
{
protected $sticker_file_id;
public function __construct(array $data)
{
parent::__construct($data);
$this->type = 'sticker';
$this->photo_file_id = isset($data['sticker_file_id']) ? $data['sticker_file_id'] : null;
if (empty($this->sticker_file_id)) {
throw new TelegramException('sticker_file_id is empty!');
}
}
public function getStickerFileId()
{
return $this->sticker_file_id;
}
}
<?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\Entities;
use Longman\TelegramBot\Exception\TelegramException;
class InlineQueryResultCachedVideo extends InlineQueryResult
{
protected $video_file_id;
protected $title;
protected $description;
protected $caption;
public function __construct(array $data)
{
parent::__construct($data);
$this->type = 'photo';
$this->video_file_id = isset($data['video_file_id']) ? $data['video_file_id'] : null;
if (empty($this->video_file_id)) {
throw new TelegramException('video_file_id is empty!');
}
$this->title = isset($data['title']) ? $data['title'] : null;
if (empty($this->title)) {
throw new TelegramException('title is empty!');
}
$this->description = isset($data['description']) ? $data['description'] : null;
$this->caption = isset($data['caption']) ? $data['caption'] : null;
}
public function getVideoFileId()
{
return $this->video_file_id;
}
public function getTitle()
{
return $this->title;
}
public function getDescription()
{
return $this->description;
}
public function getCaption()
{
return $this->caption;
}
}
<?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\Entities;
use Longman\TelegramBot\Exception\TelegramException;
class InlineQueryResultCachedVoice extends InlineQueryResult
{
protected $voice_file_id;
protected $title;
protected $description;
protected $caption;
public function __construct(array $data)
{
parent::__construct($data);
$this->type = 'voice';
$this->voice_file_id = isset($data['voice_file_id']) ? $data['voice_file_id'] : null;
if (empty($this->voice_file_id)) {
throw new TelegramException('voice_file_id is empty!');
}
$this->title = isset($data['title']) ? $data['title'] : null;
if (empty($this->title)) {
throw new TelegramException('title is empty!');
}
$this->description = isset($data['description']) ? $data['description'] : null;
$this->caption = isset($data['caption']) ? $data['caption'] : null;
}
public function getVoiceFileId()
{
return $this->voice_file_id;
}
public function getTitle()
{
return $this->title;
}
public function getDescription()
{
return $this->description;
}
public function getCaption()
{
return $this->caption;
}
}
......@@ -14,7 +14,6 @@ use Longman\TelegramBot\Exception\TelegramException;
class InlineQueryResultGif extends InlineQueryResult
{
protected $gif_url;
protected $gif_width;
protected $gif_height;
......@@ -43,29 +42,33 @@ class InlineQueryResultGif extends InlineQueryResult
$this->title = isset($data['title']) ? $data['title'] : null;
$this->caption = isset($data['caption']) ? $data['caption'] : null;
}
public function getGifUrl()
{
return $this->gif_url;
}
public function getGifWidth()
{
return $this->gif_width;
}
public function getGifHeight()
{
return $this->gif_height;
}
public function getThumbUrl()
{
return $this->thumb_url;
}
public function getTitle()
{
return $this->title;
}
public function getCaption()
{
return $this->caption;
......
......@@ -14,7 +14,6 @@ use Longman\TelegramBot\Exception\TelegramException;
class InlineQueryResultMpeg4Gif extends InlineQueryResult
{
protected $mpeg4_url;
protected $mpeg4_width;
protected $mpeg4_height;
......@@ -43,29 +42,33 @@ class InlineQueryResultMpeg4Gif extends InlineQueryResult
$this->title = isset($data['title']) ? $data['title'] : null;
$this->caption = isset($data['caption']) ? $data['caption'] : null;
}
public function getMpeg4Url()
{
return $this->mpeg4_url;
}
public function getMpeg4Width()
{
return $this->mpeg4_width;
}
public function getMpeg4Height()
{
return $this->mpeg4_height;
}
public function getThumbUrl()
{
return $this->thumb_url;
}
public function getTitle()
{
return $this->title;
}
public function getCaption()
{
return $this->caption;
......
......@@ -14,7 +14,6 @@ use Longman\TelegramBot\Exception\TelegramException;
class InlineQueryResultPhoto extends InlineQueryResult
{
protected $photo_url;
protected $photo_width;
protected $photo_height;
......@@ -45,33 +44,38 @@ class InlineQueryResultPhoto extends InlineQueryResult
$this->title = isset($data['title']) ? $data['title'] : null;
$this->description = isset($data['description']) ? $data['description'] : null;
$this->caption = isset($data['caption']) ? $data['caption'] : null;
}
public function getPhotoUrl()
{
return $this->photo_url;
}
public function getPhotoWidth()
{
return $this->photo_width;
}
public function getPhotoHeight()
{
return $this->photo_height;
}
public function getThumbUrl()
{
return $this->thumb_url;
}
public function getTitle()
{
return $this->title;
}
public function getDescription()
{
return $this->description;
}
public function getCaption()
{
return $this->caption;
......
......@@ -14,7 +14,6 @@ use Longman\TelegramBot\Exception\TelegramException;
class InlineQueryResultVideo extends InlineQueryResult
{
protected $video_url;
protected $mime_type;
protected $thumb_url;
......@@ -56,34 +55,42 @@ class InlineQueryResultVideo extends InlineQueryResult
{
return $this->video_url;
}
public function getMimeType()
{
return $this->mime_type;
}
public function getThumbUrl()
{
return $this->thumb_url;
}
public function getTitle()
{
return $this->title;
}
public function getCaption()
{
return $this->caption;
}
public function getVideoWidth()
{
return $this->video_width;
}
public function getVideoHeight()
{
return $this->video_height;
}
public function getVideoDuration()
{
return $this->video_duration;
}
public function getDescription()
{
return $this->description;
......
......@@ -20,18 +20,16 @@ class InputContactMessageContent extends InputMessageContent
public function __construct(array $data)
{
//parent::__construct($data);
$this->phone_number isset($data['phone_number']) ? $data['phone_number'] : null;
$this->phone_number = isset($data['phone_number']) ? $data['phone_number'] : null;
if (empty($this->phone_number)) {
throw new TelegramException('phone_number is empty!');
}
$this->first_name isset($data['first_name']) ? $data['first_name'] : null;
$this->first_name = isset($data['first_name']) ? $data['first_name'] : null;
if (empty($this->first_name)) {
throw new TelegramException('first_name is empty!');
}
$this->last_name isset($data['last_name']) ? $data['last_name'] : null;
$this->last_name = isset($data['last_name']) ? $data['last_name'] : null;
}
}
......@@ -19,14 +19,12 @@ class InputLocationMessageContent extends InputMessageContent
public function __construct(array $data)
{
//parent::__construct($data);
$this->latitude isset($data['latitude']) ? $data['latitude'] : null;
$this->latitude = isset($data['latitude']) ? $data['latitude'] : null;
if (empty($this->latitude)) {
throw new TelegramException('latitude is empty!');
}
$this->longitude isset($data['longitude']) ? $data['longitude'] : null;
$this->longitude = isset($data['longitude']) ? $data['longitude'] : null;
if (empty($this->longitude)) {
throw new TelegramException('longitude is empty!');
}
......
......@@ -20,14 +20,12 @@ class InputTextMessageContent extends InputMessageContent
public function __construct(array $data)
{
//parent::__construct($data);
$this->message_text isset($data['message_text']) ? $data['message_text'] : null;
$this->message_text = isset($data['message_text']) ? $data['message_text'] : null;
if (empty($this->message_text)) {
throw new TelegramException('message_text is empty!');
}
$this->parse_mode isset($data['parse_mode']) ? $data['parse_mode'] : null;
$this->disable_web_page_preview isset($data['disable_web_page_preview']) ? $data['disable_web_page_preview'] : null;
$this->parse_mode = isset($data['parse_mode']) ? $data['parse_mode'] : null;
$this->disable_web_page_preview = isset($data['disable_web_page_preview']) ? $data['disable_web_page_preview'] : null;
}
}
......@@ -22,28 +22,26 @@ class InputVenueMessageContent extends InputMessageContent
public function __construct(array $data)
{
//parent::__construct($data);
$this->latitude isset($data['latitude']) ? $data['latitude'] : null;
$this->latitude = isset($data['latitude']) ? $data['latitude'] : null;
if (empty($this->latitude)) {
throw new TelegramException('latitude is empty!');
}
$this->longitude isset($data['longitude']) ? $data['longitude'] : null;
$this->longitude = isset($data['longitude']) ? $data['longitude'] : null;
if (empty($this->longitude)) {
throw new TelegramException('longitude is empty!');
}
$this->title isset($data['title']) ? $data['title'] : null;
$this->title = isset($data['title']) ? $data['title'] : null;
if (empty($this->title)) {
throw new TelegramException('title is empty!');
}
$this->address isset($data['address']) ? $data['address'] : null;
$this->address = isset($data['address']) ? $data['address'] : null;
if (empty($this->address)) {
throw new TelegramException('address is empty!');
}
$this->foursquare_id isset($data['foursquare_id']) ? $data['foursquare_id'] : null;
$this->foursquare_id = isset($data['foursquare_id']) ? $data['foursquare_id'] : null;
}
}
......@@ -28,6 +28,8 @@ class Message extends Entity
protected $forward_date;
protected $edit_date;
protected $reply_to_message;
protected $text;
......@@ -122,7 +124,6 @@ class Message extends Entity
$this->forward_from = isset($data['forward_from']) ? $data['forward_from'] : null;
if (!empty($this->forward_from)) {
$this->forward_from = new User($this->forward_from);
}
$this->forward_from_chat = isset($data['forward_from_chat']) ? $data['forward_from_chat'] : null;
......@@ -132,6 +133,8 @@ class Message extends Entity
$this->forward_date = isset($data['forward_date']) ? $data['forward_date'] : null;
$this->edit_date = isset($data['edit_date']) ? $data['edit_date'] : null;
$this->text = isset($data['text']) ? $data['text'] : null;
$command = $this->getCommand();
if (!empty($command)) {
......@@ -361,6 +364,11 @@ class Message extends Entity
return $this->forward_date;
}
public function getEditDate()
{
return $this->edit_date;
}
public function getReplyToMessage()
{
return $this->reply_to_message;
......
......@@ -16,25 +16,30 @@ class MessageEntity extends Entity
protected $offset;
protected $length;
protected $url;
protected $user;
/**
* @todo check for type value from this list: https://core.telegram.org/bots/api#messageentity
*/
public function __construct(array $data)
{
$this->type = isset($data['type']) ? $data['type'] : null;
if (empty($this->type)) { // @todo check for value from this list: https://core.telegram.org/bots/api#messageentity
if (empty($this->type)) {
throw new TelegramException('type is empty!');
}
$this->offset = isset($data['offset']) ? $data['offset'] : null;
if (empty($this->offset) && $this->offset != 0) { // @todo this is not an ideal solution?
if ($this->offset === '') {
throw new TelegramException('offset is empty!');
}
$this->length = isset($data['length']) ? $data['length'] : null;
if (empty($this->length) && $this->offset != 0) { // @todo this is not an ideal solution?
if ($this->length === '') {
throw new TelegramException('length is empty!');
}
$this->url = isset($data['url']) ? $data['url'] : null;
$this->user = isset($data['user']) ? new User($data['user']) : null;
}
public function getType()
......@@ -56,4 +61,9 @@ class MessageEntity extends Entity
{
return $this->url;
}
public function getUser()
{
return $this->user;
}
}
......@@ -21,9 +21,6 @@ class ReplyKeyboardMarkup extends Entity
protected $one_time_keyboard;
protected $selective;
/*
* @todo check for KeyboardButton elements
*/
public function __construct($data = array())
{
if (isset($data['keyboard'])) {
......
......@@ -14,32 +14,42 @@ use Longman\TelegramBot\Exception\TelegramException;
class ServerResponse extends Entity
{
protected $ok;
protected $result;
protected $error_code;
protected $description;
public function __construct(array $data, $bot_name)
{
if (isset($data['ok']) & isset($data['result'])) {
if (is_array($data['result'])) {
if ($data['ok'] & !$this->isAssoc($data['result'])) {
//get update
if ($data['ok'] & !$this->isAssoc($data['result']) & !isset($data['result'][0]['user'])) {
//Get Update
foreach ($data['result'] as $update) {
$this->result[] = new Update($update, $bot_name);
}
} elseif ($data['ok'] & !$this->isAssoc($data['result']) & isset($data['result'][0]['user'])) {
//Response from getChatAdministrators
$this->result = [];
foreach ($data['result'] as $user) {
array_push($this->result, new ChatMember($user));
}
} elseif ($data['ok'] & $this->isAssoc($data['result'])) {
if (isset($data['result']['total_count'])) {
//getUserProfilePhotos
//Response from getUserProfilePhotos
$this->result = new UserProfilePhotos($data['result']);
} elseif (isset($data['result']['file_id'])) {
//Response getFile
//Response from getFile
$this->result = new File($data['result']);
} elseif (isset($data['result']['username'])) {
//Response getMe
//Response from getMe
$this->result = new User($data['result']);
} elseif (isset($data['result']['id'])) {
//Response from getChat
$this->result = new Chat($data['result']);
} elseif (isset($data['result']['user'])) {
//Response from getChatMember
$this->result = new ChatMember($data['result']);
} else {
//Response from sendMessage
$this->result = new Message($data['result'], $bot_name);
......@@ -50,17 +60,20 @@ class ServerResponse extends Entity
$this->error_code = null;
$this->description = null;
} else {
if ($data['ok'] & $data['result'] == true) {
if ($data['ok'] & $data['result'] === true) {
//Response from setWebhook set
$this->ok = $data['ok'];
$this->result = true;
$this->error_code = null;
if (isset($data['description'])) {
$this->description = $data['description'];
} else {
$this->description = '';
}
} elseif (is_numeric($data['result'])) {
//Response from getChatMembersCount
$this->result = $data['result'];
} else {
$this->ok = false;
$this->result = null;
......
......@@ -17,6 +17,7 @@ class Update extends Entity
protected $update_id;
protected $message;
protected $edited_message;
protected $inline_query;
protected $chosen_inline_result;
protected $callback_query;
......@@ -37,6 +38,12 @@ class Update extends Entity
$this->update_type = 'message';
}
$this->edited_message = isset($data['edited_message']) ? $data['edited_message'] : null;
if (!empty($this->edited_message)) {
$this->edited_message = new Message($this->edited_message, $bot_name);
$this->update_type = 'edited_message';
}
if (empty($update_id)) {
throw new TelegramException('update_id is empty!');
}
......@@ -69,6 +76,10 @@ class Update extends Entity
{
return $this->message;
}
public function getEditedMessage()
{
return $this->edited_message;
}
public function getInlineQuery()
{
return $this->inline_query;
......
......@@ -10,22 +10,9 @@
namespace Longman\TelegramBot\Exception;
use Longman\TelegramBot\Logger;
/**
* Main exception class used for exception handling
*/
class TelegramException extends \Exception
{
/**
* Exception constructor that writes the exception message to the logfile
*
* @param string $message Error message
* @param integer $code Error code
*/
public function __construct($message, $code = 0)
{
parent::__construct($message, $code);
Logger::logException(self::__toString());
}
}
<?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\Exception;
/**
* Main exception class used for exception handling
*/
class TelegramLogException extends \Exception
{
}
<?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;
/**
* Class Logger.
*/
class Logger
{
/**
* Exception log path
*
* @var string
*/
static protected $exception_log_path = null;
/**
* Initialize
*
* @param string $exception_log_path
*/
public static function initialize($exception_log_path)
{
self::$exception_log_path = $exception_log_path;
}
/**
* Log exception
*
* @param string $text
*
* @return bool
*/
public static function logException($text)
{
if (!is_null(self::$exception_log_path)) {
return file_put_contents(
self::$exception_log_path,
date('Y-m-d H:i:s', time()) . ' ' . $text . "\n",
FILE_APPEND
);
}
return 0;
}
}
This diff is collapsed.
......@@ -30,7 +30,7 @@ class Telegram
*
* @var string
*/
protected $version = '0.32.0';
protected $version = '0.33.0';
/**
* Telegram API key
......@@ -67,20 +67,6 @@ class Telegram
*/
protected $update;
/**
* Log verbose curl output
*
* @var bool
*/
protected $log_requests;
/**
* Log path
*
* @var string
*/
protected $log_path;
/**
* Upload path
*
......@@ -95,13 +81,6 @@ class Telegram
*/
protected $download_path;
/**
* Log verbosity
*
* @var int
*/
protected $log_verbosity = 1;
/**
* MySQL integration
*
......@@ -137,6 +116,13 @@ class Telegram
*/
protected $last_command_response;
/**
* Botan.io integration
*
* @var boolean
*/
protected $botan_enabled = false;
/**
* Constructor
*
......@@ -174,9 +160,9 @@ class Telegram
*
* @return Telegram
*/
public function enableMySql(array $credential, $table_prefix = null)
public function enableMySql(array $credential, $table_prefix = null, $encoding = 'utf8mb4')
{
$this->pdo = DB::initialize($credential, $this, $table_prefix);
$this->pdo = DB::initialize($credential, $this, $table_prefix, $encoding);
ConversationDB::initializeConversation();
$this->mysql_enabled = true;
return $this;
......@@ -225,6 +211,7 @@ class Telegram
require_once $file->getPathname();
$command_obj = $this->getCommandObject($command);
if ($command_obj instanceof Commands\Command) {
$commands[$command_name] = $command_obj;
......@@ -261,81 +248,6 @@ class Telegram
return null;
}
/**
* Set log requests
*
* 0 don't store
* 1 store the Curl verbose output with Telegram updates
*
* @param bool $log_requests
*
* @return Telegram
*/
public function setLogRequests($log_requests)
{
$this->log_requests = $log_requests;
return $this;
}
/**
* Get log requests
*
* @return bool
*/
public function getLogRequests()
{
return $this->log_requests;
}
/**
* Set log path
*
* @param string $log_path
*
* @return \Longman\TelegramBot\Telegram
*/
public function setLogPath($log_path)
{
$this->log_path = $log_path;
return $this;
}
/**
* Get log path
*
* @return string
*/
public function getLogPath()
{
return $this->log_path;
}
/**
* Set log Verbosity
*
* @param int $log_verbosity
*
* 1 only incoming updates from webhook and getUpdates
* 3 incoming updates from webhook and getUpdates and curl request info and response
*
* @return \Longman\TelegramBot\Telegram
*/
public function setLogVerbosity($log_verbosity)
{
$this->log_verbosity = $log_verbosity;
return $this;
}
/**
* Get log verbosity
*
* @return int
*/
public function getLogVerbosity()
{
return $this->log_verbosity;
}
/**
* Set custom input string for debug purposes
*
......@@ -379,6 +291,13 @@ class Telegram
*/
public function handleGetUpdates($limit = null, $timeout = null)
{
if (!DB::isDbConnected()) {
return new Entities\ServerResponse([
'ok' => false,
'description' => 'getUpdates needs MySQL connection!',
], $this->bot_name);
}
//DB Query
$last_update = DB::selectTelegramUpdate(1);
......@@ -448,7 +367,7 @@ class Telegram
$command = 'genericmessage';
$update_type = $this->update->getUpdateType();
if (in_array($update_type, ['inline_query', 'chosen_inline_result', 'callback_query'])) {
if (in_array($update_type, ['inline_query', 'chosen_inline_result', 'callback_query', 'edited_message'])) {
$command = $this->getCommandFromType($update_type);
} elseif ($update_type === 'message') {
$message = $this->update->getMessage();
......@@ -508,9 +427,19 @@ class Telegram
//Handle a generic command or non existing one
$this->last_command_response = $this->executeCommand('Generic');
} else {
//Botan.io integration, make sure only the command user executed is reported
if ($this->botan_enabled) {
Botan::lock($command);
}
//execute() method is executed after preExecute()
//This is to prevent executing a DB query without a valid connection
$this->last_command_response = $command_obj->preExecute();
//Botan.io integration, send report after executing the command
if ($this->botan_enabled) {
Botan::track($this->update, $command);
}
}
return $this->last_command_response;
......@@ -568,6 +497,14 @@ class Telegram
if ($user_id === null && $this->update !== null) {
if (($message = $this->update->getMessage()) && ($from = $message->getFrom())) {
$user_id = $from->getId();
} elseif (($inline_query = $this->update->getInlineQuery()) && ($from = $inline_query->getFrom())) {
$user_id = $from->getId();
} elseif (($chosen_inline_result = $this->update->getChosenInlineResult()) && ($from = $chosen_inline_result->getFrom())) {
$user_id = $from->getId();
} elseif (($callback_query = $this->update->getCallbackQuery()) && ($from = $callback_query->getFrom())) {
$user_id = $from->getId();
} elseif (($edited_message = $this->update->getEditedMessage()) && ($from = $edited_message->getFrom())) {
$user_id = $from->getId();
}
}
......@@ -785,4 +722,17 @@ class Telegram
{
return mb_strtoupper(mb_substr($str, 0, 1, $encoding), $encoding) . mb_strtolower(mb_substr($str, 1, mb_strlen($str), $encoding), $encoding);
}
/**
* Enable Botan.io integration
*
* @param $token
* @return Telegram
*/
public function enableBotan($token)
{
Botan::initializeBotan($token);
$this->botan_enabled = true;
return $this;
}
}
<?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;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\LineFormatter;
use Longman\TelegramBot\Exception\TelegramLogException;
/**
* Class TelegramLog.
*/
class TelegramLog
{
/**
* Monolog instance
*
* @var \Monolog\Logger
*/
static protected $monolog = null;
/**
* Monolog instance for update
*
* @var \Monolog\Logger
*/
static protected $monolog_update = null;
/**
* Path for error log
*
* @var string
*/
static protected $error_log_path = null;
/**
* Path for debug log
*
* @var string
*/
static protected $debug_log_path = null;
/**
* Path for update log
*
* @var string
*/
static protected $update_log_path = null;
/**
* Temporary stream handle for debug log
*
* @var null
*/
static protected $debug_log_temp_stream_handle = null;
/**
* Initialize
*
* Initilize monolog instance. Singleton
* Is possbile provide an external monolog instance
*
* @param \Monolog\Logger
*
* @return \Monolog\Logger
*/
public static function initialize(Logger $external_monolog = null)
{
if (self::$monolog === null) {
if ($external_monolog !== null) {
self::$monolog = $external_monolog;
foreach (self::$monolog->getHandlers() as $handler) {
if ($handler->getLevel() == 400) {
self::$error_log_path = true;
}
if ($handler->getLevel() == 100) {
self::$debug_log_path = true;
}
}
} else {
self::$monolog = new Logger('bot_log');
}
}
return self::$monolog;
}
/**
* Initialize error log
*
* @param string $path
*
* @return \Monolog\Logger
*/
public static function initErrorLog($path)
{
if ($path === null || $path === '') {
throw new TelegramLogException('Empty path for error log');
}
self::initialize();
self::$error_log_path = $path;
return self::$monolog->pushHandler(
(new StreamHandler(self::$error_log_path, Logger::ERROR))
->setFormatter(new LineFormatter(null, null, true))
);
}
/**
* Initialize debug log
*
* @param string $path
*
* @return \Monolog\Logger
*/
public static function initDebugLog($path)
{
if ($path === null || $path === '') {
throw new TelegramLogException('Empty path for debug log');
}
self::initialize();
self::$debug_log_path = $path;
return self::$monolog->pushHandler(
(new StreamHandler(self::$debug_log_path, Logger::DEBUG))
->setFormatter(new LineFormatter(null, null, true))
);
}
/**
* Get the stream handle of the temporary debug output
*
* @return mixed The stream if debug is active, else false
*/
public static function getDebugLogTempStream()
{
if (self::$debug_log_temp_stream_handle === null) {
if (self::isDebugLogActive()) {
self::$debug_log_temp_stream_handle = fopen('php://temp', 'w+');
} else {
return false;
}
}
return self::$debug_log_temp_stream_handle;
}
/**
* Write the temporary debug stream to log and close the stream handle
*
* @param string $message Message (with placeholder) to write to the debug log
*/
public static function endDebugLogTempStream($message = '%s')
{
if (self::$debug_log_temp_stream_handle !== null) {
rewind(self::$debug_log_temp_stream_handle);
self::debug(sprintf(
$message,
stream_get_contents(self::$debug_log_temp_stream_handle)
));
fclose(self::$debug_log_temp_stream_handle);
self::$debug_log_temp_stream_handle = null;
}
}
/**
* Initialize update log
*
* Initilize monolog instance. Singleton
* Is possbile provide an external monolog instance
*
* @param string $path
*
* @return \Monolog\Logger
*/
public static function initUpdateLog($path)
{
if ($path === null || $path === '') {
throw new TelegramLogException('Empty path for update log');
}
self::$update_log_path = $path;
if (self::$monolog_update === null) {
self::$monolog_update = new Logger('bot_update_log');
// Create a formatter
$output = "%message%\n";
$formatter = new LineFormatter($output);
// Update handler
$update_handler = new StreamHandler(self::$update_log_path, Logger::INFO);
$update_handler->setFormatter($formatter);
self::$monolog_update->pushHandler($update_handler);
}
return self::$monolog;
}
/**
* Is error log active
*
* @return bool
*/
public static function isErrorLogActive()
{
return (self::$error_log_path !== null);
}
/**
* Is debug log active
*
* @return bool
*/
public static function isDebugLogActive()
{
return (self::$debug_log_path !== null);
}
/**
* Is update log active
*
* @return bool
*/
public static function isUpdateLogActive()
{
return (self::$update_log_path !== null);
}
/**
* Report error log
*
* @param string $text
*/
public static function error($text)
{
if (self::isErrorLogActive()) {
self::$monolog->error($text);
}
}
/**
* Report debug log
*
* @param string $text
*/
public static function debug($text)
{
if (self::isDebugLogActive()) {
self::$monolog->debug($text);
}
}
/**
* Report update log
*
* @param string $text
*/
public static function update($text)
{
if (self::isUpdateLogActive()) {
self::$monolog_update->info($text);
}
}
}
This diff is collapsed.
......@@ -53,7 +53,7 @@ class TestHelpers
/**
* Set the value of a private/protected property of an object
*
* @param object $object Object that contains the private property
* @param object $object Object that contains the property
* @param string $property Name of the property who's value we want to set
* @param mixed $value The value to set to the property
*/
......@@ -65,6 +65,20 @@ class TestHelpers
$ref_property->setValue($object, $value);
}
/**
* Set the value of a private/protected static property of a class
*
* @param string $class Class that contains the static property
* @param string $property Name of the property who's value we want to set
* @param mixed $value The value to set to the property
*/
public static function setStaticProperty($class, $property, $value)
{
$ref_property = new \ReflectionProperty($class, $property);
$ref_property->setAccessible(true);
$ref_property->setValue(null, $value);
}
/**
* Return a simple fake Update object
*
......
......@@ -35,7 +35,7 @@ class ConversationTest extends TestCase
{
$credentials = [
'host' => '127.0.0.1',
'user' => 'travis',
'user' => 'root',
'password' => '',
'database' => 'telegrambot',
];
......
......@@ -22,26 +22,22 @@ use \Longman\TelegramBot\Entities\Message;
class MessageTest extends TestCase
{
/**
* @var \Longman\TelegramBot\Telegram
*/
* @var \Longman\TelegramBot\Telegram
*/
private $message;
/**
* setUp
*/
* setUp
*/
protected function setUp()
{
}
protected function generateMessage($string) {
//$string = addslashes($string);
$string = str_replace("\n", "\\n", $string);
$json = '{"message_id":961,"from":{"id":123,"first_name":"john","username":"john"},"chat":{"id":123,"title":null,"first_name":"john","last_name":null,"username":"null"},"date":1435920612,"text":"'.$string.'"}';
//$json = utf8_encode($json);
//$json = utf8_encode($json);
return json_decode($json, true);
}
/**
......@@ -56,8 +52,8 @@ class MessageTest extends TestCase
$this->assertEquals('help', $this->message->getCommand());
$this->assertEquals('/help', $this->message->getText());
$this->assertEquals('', $this->message->getText(true));
// text
// text
$this->message = new Message($this->generateMessage('some text'), 'testbot');
$this->assertEquals('', $this->message->getFullCommand());
......
<?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 Tests\Unit;
use Longman\TelegramBot\Exception\TelegramLogException;
use Longman\TelegramBot\TelegramLog;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Tests\TestHelpers;
/**
* @package TelegramTest
* @author Avtandil Kikabidze <akalongman@gmail.com>
* @copyright Avtandil Kikabidze <akalongman@gmail.com>
* @license http://opensource.org/licenses/mit-license.php The MIT License (MIT)
* @link http://www.github.com/akalongman/php-telegram-bot
*/
class TelegramLogTest extends TestCase
{
/**
* Logfile paths
*/
private $logfiles = [
'error' => '/tmp/errorlog.log',
'debug' => '/tmp/debuglog.log',
'update' => '/tmp/updatelog.log',
'external' => '/tmp/externallog.log',
];
/**
* setUp
*/
protected function setUp()
{
// Make sure no monolog instance is set before each test.
TestHelpers::setStaticProperty('Longman\TelegramBot\TelegramLog', 'monolog', null);
}
/**
* tearDown
*/
protected function tearDown()
{
// Make sure no logfiles exist.
foreach ($this->logfiles as $file) {
file_exists($file) && unlink($file);
}
}
/**
* @test
* @expectedException \Longman\TelegramBot\Exception\TelegramLogException
*/
public function newInstanceWithoutErrorPath()
{
TelegramLog::initErrorLog('');
}
/**
* @test
* @expectedException \Longman\TelegramBot\Exception\TelegramLogException
*/
public function newInstanceWithoutDebugPath()
{
TelegramLog::initDebugLog('');
}
/**
* @test
* @expectedException \Longman\TelegramBot\Exception\TelegramLogException
*/
public function newInstanceWithoutUpdatePath()
{
TelegramLog::initUpdateLog('');
}
/**
* @test
*/
public function testErrorStream()
{
$file = $this->logfiles['error'];
$this->assertFalse(file_exists($file));
TelegramLog::initErrorLog($file);
TelegramLog::error('my error');
$this->assertTrue(file_exists($file));
$this->assertContains('bot_log.ERROR: my error', file_get_contents($file));
}
/**
* @test
*/
public function testDebugStream()
{
$file = $this->logfiles['debug'];
$this->assertFalse(file_exists($file));
TelegramLog::initDebugLog($file);
TelegramLog::debug('my debug');
$this->assertTrue(file_exists($file));
$this->assertContains('bot_log.DEBUG: my debug', file_get_contents($file));
}
/**
* @test
*/
public function testUpdateStream()
{
$file = $this->logfiles['update'];
$this->assertFalse(file_exists($file));
TelegramLog::initUpdateLog($file);
TelegramLog::update('my update');
$this->assertTrue(file_exists($file));
$this->assertContains('my update', file_get_contents($file));
}
/**
* @test
*/
public function testExternalStream()
{
$file = $this->logfiles['external'];
$this->assertFalse(file_exists($file));
$external_monolog = new Logger('bot_update_log');
$external_monolog->pushHandler(new StreamHandler($file, Logger::ERROR));
$external_monolog->pushHandler(new StreamHandler($file, Logger::DEBUG));
TelegramLog::initialize($external_monolog);
TelegramLog::error('my error');
TelegramLog::debug('my debug');
$this->assertTrue(file_exists($file));
$file_contents = file_get_contents($file);
$this->assertContains('bot_update_log.ERROR: my error', $file_contents);
$this->assertContains('bot_update_log.DEBUG: my debug', $file_contents);
}
}
<?php
require __DIR__ . '/../vendor/autoload.php';
$filename='logfile.log';
$API_KEY = 'random';
$BOT_NAME = 'bot_name';
define('PHPUNIT_TESTSUITE', 'some value');
$CREDENTIALS = array('host'=>'localhost', 'user'=>'', 'password'=>'', 'database'=>'');
$update = null;
try {
// Create Telegram API object
$telegram = new Longman\TelegramBot\Telegram($API_KEY, $BOT_NAME);
$telegram->enableMySQL($CREDENTIALS);
foreach (new SplFileObject($filename) as $current_line) {
$json_decoded = json_decode($update, true);
if (!is_null($json_decoded)) {
echo $update . "\n\n";
$update = null;
if (empty($json_decoded)) {
echo "Empty update: \n";
echo $update . "\n\n";
continue;
}
$telegram->processUpdate(new Longman\TelegramBot\Entities\Update($json_decoded, $BOT_NAME));
}
$update .= $current_line;
}
} catch (Longman\TelegramBot\Exception\TelegramException $e) {
// log telegram errors
echo $e;
}
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