Fix and improve User commands.

parent c9e38bc5
......@@ -42,7 +42,7 @@ class CancelCommand extends UserCommand
/**
* @var string
*/
protected $version = '0.1.1';
protected $version = '0.2.0';
/**
* @var bool
......@@ -53,6 +53,7 @@ class CancelCommand extends UserCommand
* Command execute method
*
* @return \Longman\TelegramBot\Entities\ServerResponse
* @throws \Longman\TelegramBot\Exception\TelegramException
*/
public function execute()
{
......@@ -72,22 +73,13 @@ class CancelCommand extends UserCommand
return $this->hideKeyboard($text);
}
/**
* Execute no db
*
* @return \Longman\TelegramBot\Entities\ServerResponse
*/
public function executeNoDb()
{
return $this->hideKeyboard('Nothing to cancel.');
}
/**
* Hide the keyboard and output a text
*
* @param string $text
*
* @return \Longman\TelegramBot\Entities\ServerResponse
* @throws \Longman\TelegramBot\Exception\TelegramException
*/
private function hideKeyboard($text)
{
......@@ -99,4 +91,15 @@ class CancelCommand extends UserCommand
]
);
}
/**
* Execute no db
*
* @return \Longman\TelegramBot\Entities\ServerResponse
* @throws \Longman\TelegramBot\Exception\TelegramException
*/
public function executeNoDb()
{
return $this->hideKeyboard('Nothing to cancel.');
}
}
......@@ -10,11 +10,13 @@
namespace Longman\TelegramBot\Commands\UserCommands;
use DateTime;
use DateTimeZone;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Longman\TelegramBot\Commands\UserCommand;
use Longman\TelegramBot\Exception\TelegramException;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\TelegramLog;
/**
* User "/date" command
......@@ -39,7 +41,7 @@ class DateCommand extends UserCommand
/**
* @var string
*/
protected $version = '1.3.0';
protected $version = '1.4.0';
/**
* Guzzle Client object
......@@ -74,8 +76,7 @@ class DateCommand extends UserCommand
*
* @param string $location
*
* @return array|boolean
* @throws \Longman\TelegramBot\Exception\TelegramException
* @return array
*/
private function getCoordinates($location)
{
......@@ -89,14 +90,16 @@ class DateCommand extends UserCommand
try {
$response = $this->client->get($path, ['query' => $query]);
} catch (RequestException $e) {
throw new TelegramException($e->getMessage());
TelegramLog::error($e->getMessage());
return [];
}
if (!($result = $this->validateResponseData($response->getBody()))) {
return false;
if (!($data = $this->validateResponseData($response->getBody()))) {
return [];
}
$result = $result['results'][0];
$result = $data['results'][0];
$lat = $result['geometry']['location']['lat'];
$lng = $result['geometry']['location']['lng'];
$acc = $result['geometry']['location_type'];
......@@ -111,8 +114,7 @@ class DateCommand extends UserCommand
* @param string $lat
* @param string $lng
*
* @return array|boolean
* @throws \Longman\TelegramBot\Exception\TelegramException
* @return array
*/
private function getDate($lat, $lng)
{
......@@ -123,7 +125,7 @@ class DateCommand extends UserCommand
$query = [
'location' => urlencode($lat) . ',' . urlencode($lng),
'timestamp' => urlencode($timestamp)
'timestamp' => urlencode($timestamp),
];
if ($this->google_api_key !== null) {
......@@ -133,16 +135,18 @@ class DateCommand extends UserCommand
try {
$response = $this->client->get($path, ['query' => $query]);
} catch (RequestException $e) {
throw new TelegramException($e->getMessage());
TelegramLog::error($e->getMessage());
return [];
}
if (!($result = $this->validateResponseData($response->getBody()))) {
return false;
if (!($data = $this->validateResponseData($response->getBody()))) {
return [];
}
$local_time = $timestamp + $result['rawOffset'] + $result['dstOffset'];
$local_time = $timestamp + $data['rawOffset'] + $data['dstOffset'];
return [$local_time, $result['timeZoneId']];
return [$local_time, $data['timeZoneId']];
}
/**
......@@ -150,48 +154,48 @@ class DateCommand extends UserCommand
*
* @param string $data
*
* @return bool|array
* @return array
*/
private function validateResponseData($data)
{
if (empty($data)) {
return false;
return [];
}
$data = json_decode($data, true);
if (empty($data)) {
return false;
return [];
}
if (isset($data['status']) && $data['status'] !== 'OK') {
return false;
return [];
}
return $data;
}
/**
* Get formatted date
* Get formatted date at the passed location
*
* @param string $location
*
* @return string
* @throws \Longman\TelegramBot\Exception\TelegramException
*/
private function getFormattedDate($location)
{
if (empty($location)) {
if ($location === null || $location === '') {
return 'The time in nowhere is never';
}
list($lat, $lng, $acc, $types) = $this->getCoordinates($location);
list($lat, $lng) = $this->getCoordinates($location);
if (empty($lat) || empty($lng)) {
return 'It seems that in "' . $location . '" they do not have a concept of time.';
}
list($local_time, $timezone_id) = $this->getDate($lat, $lng);
$date_utc = new \DateTime(gmdate('Y-m-d H:i:s', $local_time), new \DateTimeZone($timezone_id));
$date_utc = new DateTime(gmdate('Y-m-d H:i:s', $local_time), new DateTimeZone($timezone_id));
return 'The local time in ' . $timezone_id . ' is: ' . $date_utc->format($this->date_format);
}
......@@ -200,6 +204,7 @@ class DateCommand extends UserCommand
* Command execute method
*
* @return mixed
* @throws \Longman\TelegramBot\Exception\TelegramException
*/
public function execute()
{
......@@ -214,9 +219,9 @@ class DateCommand extends UserCommand
$chat_id = $message->getChat()->getId();
$location = $message->getText(true);
if (empty($location)) {
$text = 'You must specify location in format: /date <city>';
} else {
$text = 'You must specify location in format: /date <city>';
if ($location !== '') {
$text = $this->getFormattedDate($location);
}
......
......@@ -36,12 +36,13 @@ class EchoCommand extends UserCommand
/**
* @var string
*/
protected $version = '1.0.1';
protected $version = '1.1.0';
/**
* Command execute method
*
* @return mixed
* @throws \Longman\TelegramBot\Exception\TelegramException
*/
public function execute()
{
......
......@@ -10,6 +10,7 @@
namespace Longman\TelegramBot\Commands\UserCommands;
use Longman\TelegramBot\Commands\Command;
use Longman\TelegramBot\Commands\UserCommand;
use Longman\TelegramBot\Request;
......@@ -36,12 +37,13 @@ class HelpCommand extends UserCommand
/**
* @var string
*/
protected $version = '1.0.1';
protected $version = '1.1.0';
/**
* Command execute method
*
* @return mixed
* @throws \Longman\TelegramBot\Exception\TelegramException
*/
public function execute()
{
......@@ -52,26 +54,43 @@ class HelpCommand extends UserCommand
$command = trim($message->getText(true));
//Only get enabled Admin and User commands
$commands = array_filter($this->telegram->getCommandsList(), function ($command) {
return (!$command->isSystemCommand() && $command->isEnabled());
/** @var Command[] $command_objs */
$command_objs = array_filter($this->telegram->getCommandsList(), function ($command_obj) {
/** @var Command $command_obj */
return !$command_obj->isSystemCommand() && $command_obj->isEnabled();
});
//If no command parameter is passed, show the list
if ($command === '') {
$text = $this->telegram->getBotName() . ' v. ' . $this->telegram->getVersion() . "\n\n";
$text .= 'Commands List:' . "\n";
foreach ($commands as $command) {
$text .= '/' . $command->getName() . ' - ' . $command->getDescription() . "\n";
$text = sprintf(
'%s v. %s' . PHP_EOL . PHP_EOL . 'Commands List:' . PHP_EOL,
$this->telegram->getBotName(),
$this->telegram->getVersion()
);
foreach ($command_objs as $command) {
$text .= sprintf(
'/%s - %s' . PHP_EOL,
$command->getName(),
$command->getDescription()
);
}
$text .= "\n" . 'For exact command help type: /help <command>';
$text .= PHP_EOL . 'For exact command help type: /help <command>';
} else {
$command = str_replace('/', '', $command);
if (isset($commands[$command])) {
$command = $commands[$command];
$text = 'Command: ' . $command->getName() . ' v' . $command->getVersion() . "\n";
$text .= 'Description: ' . $command->getDescription() . "\n";
$text .= 'Usage: ' . $command->getUsage();
if (isset($command_objs[$command])) {
/** @var Command $command_obj */
$command_obj = $command_objs[$command];
$text = sprintf(
'Command: %s v%s' . PHP_EOL .
'Description: %s' . PHP_EOL .
'Usage: %s',
$command_obj->getName(),
$command_obj->getVersion(),
$command_obj->getDescription(),
$command_obj->getUsage()
);
} else {
$text = 'No help available: Command /' . $command . ' not found';
}
......
......@@ -36,20 +36,20 @@ class SlapCommand extends UserCommand
/**
* @var string
*/
protected $version = '1.0.1';
protected $version = '1.1.0';
/**
* Command execute method
*
* @return mixed
* @throws \Longman\TelegramBot\Exception\TelegramException
*/
public function execute()
{
$message = $this->getMessage();
$chat_id = $message->getChat()->getId();
$message_id = $message->getMessageId();
$text = $message->getText(true);
$chat_id = $message->getChat()->getId();
$text = $message->getText(true);
$sender = '@' . $message->getFrom()->getUsername();
......
......@@ -10,6 +10,7 @@
namespace Longman\TelegramBot\Commands\UserCommands;
use Longman\TelegramBot\Entities\PhotoSize;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\Conversation;
use Longman\TelegramBot\Commands\UserCommand;
......@@ -40,7 +41,7 @@ class SurveyCommand extends UserCommand
/**
* @var string
*/
protected $version = '0.2.0';
protected $version = '0.3.0';
/**
* @var bool
......@@ -58,6 +59,7 @@ class SurveyCommand extends UserCommand
* Command execute method
*
* @return mixed
* @throws \Longman\TelegramBot\Exception\TelegramException
*/
public function execute()
{
......@@ -65,186 +67,206 @@ class SurveyCommand extends UserCommand
$chat = $message->getChat();
$user = $message->getFrom();
$text = $message->getText(true);
$text = trim($message->getText(true));
$chat_id = $chat->getId();
$user_id = $user->getId();
//Preparing Respose
$data = [];
//Preparing Response
$data = [
'chat_id' => $chat_id,
];
if ($chat->isGroupChat() || $chat->isSuperGroup()) {
//reply to message id is applied by default
//Force reply is applied by default to so can work with privacy on
//Force reply is applied by default so it can work with privacy on
$data['reply_markup'] = new ForceReply(['selective' => true]);
}
$data['chat_id'] = $chat_id;
//Conversation start
$this->conversation = new Conversation($user_id, $chat_id, $this->getName());
$notes = &$this->conversation->notes;
//cache data from the tracking session if any
if (!isset($this->conversation->notes['state'])) {
$state = '0';
} else {
$state = $this->conversation->notes['state'];
$state = 0;
if (isset($notes['state'])) {
$state = $notes['state'];
}
//state machine
//entrypoint of the machine state if given by the track
//Every time the step is achived the track is updated
$result = Request::emptyResponse();
//State machine
//Entrypoint of the machine state if given by the track
//Every time a step is achieved the track is updated
switch ($state) {
case 0:
if (empty($text)) {
$this->conversation->notes['state'] = 0;
if ($text === '') {
$notes['state'] = 0;
$this->conversation->update();
$data['text'] = 'Type your name:';
$data['reply_markup'] = new ReplyKeyBoardHide(['selective' => true]);
$result = Request::sendMessage($data);
$result = Request::sendMessage($data);
break;
}
$this->conversation->notes['name'] = $text;
$text = '';
$notes['name'] = $text;
$text = '';
// no break
case 1:
if (empty($text)) {
$this->conversation->notes['state'] = 1;
if ($text === '') {
$notes['state'] = 1;
$this->conversation->update();
$data['text'] = 'Type your surname:';
$result = Request::sendMessage($data);
$result = Request::sendMessage($data);
break;
}
$this->conversation->notes['surname'] = $text;
++$state;
$text = '';
$notes['surname'] = $text;
$text = '';
// no break
case 2:
if (empty($text) || !is_numeric($text)) {
$this->conversation->notes['state'] = 2;
if ($text === '' || !is_numeric($text)) {
$notes['state'] = 2;
$this->conversation->update();
$data['text'] = 'Type your age:';
if (!empty($text) && !is_numeric($text)) {
$data['text'] = 'Type your age, must be a number';
if ($text !== '') {
$data['text'] = 'Type your age, must be a number:';
}
$result = Request::sendMessage($data);
break;
}
$this->conversation->notes['age'] = $text;
$text = '';
$notes['age'] = $text;
$text = '';
// no break
case 3:
if (empty($text) || !($text == 'M' || $text == 'F')) {
$this->conversation->notes['state'] = 3;
if ($text === '' || !($text === 'M' || $text === 'F')) {
$notes['state'] = 3;
$this->conversation->update();
$keyboard = [['M', 'F']];
$reply_keyboard_markup = new ReplyKeyboardMarkup(
$data['reply_markup'] = new ReplyKeyboardMarkup(
[
'keyboard' => $keyboard,
'keyboard' => [['M', 'F']],
'resize_keyboard' => true,
'one_time_keyboard' => true,
'selective' => true
'selective' => true,
]
);
$data['reply_markup'] = $reply_keyboard_markup;
$data['text'] = 'Select your gender:';
if (!empty($text) && !($text == 'M' || $text == 'F')) {
$data['text'] = 'Select your gender:';
if ($text !== '') {
$data['text'] = 'Select your gender, choose a keyboard option:';
}
$result = Request::sendMessage($data);
break;
}
$this->conversation->notes['gender'] = $text;
$text = '';
$notes['gender'] = $text;
// no break
case 4:
if (is_null($message->getLocation())) {
$this->conversation->notes['state'] = 4;
if ($message->getLocation() === null) {
$notes['state'] = 4;
$this->conversation->update();
$data['reply_markup'] = new ReplyKeyboardMarkup(
[
'keyboard' => [
[
[
'text' => 'Share Location',
'request_location' => true
'request_location' => true,
],
]
],
],
'resize_keyboard' => true,
'one_time_keyboard' => true,
'selective' => true,
]
);
$data['text'] = 'Share your location:';
$result = Request::sendMessage($data);
$data['text'] = 'Share your location:';
$result = Request::sendMessage($data);
break;
}
$this->conversation->notes['longitude'] = $message->getLocation()->getLongitude();
$this->conversation->notes['latitude'] = $message->getLocation()->getLatitude();
$notes['longitude'] = $message->getLocation()->getLongitude();
$notes['latitude'] = $message->getLocation()->getLatitude();
// no break
case 5:
if (is_null($message->getPhoto())) {
$this->conversation->notes['state'] = 5;
if ($message->getPhoto() === null) {
$notes['state'] = 5;
$this->conversation->update();
$data['text'] = 'Insert your picture:';
$data['reply_markup'] = new ReplyKeyBoardHide(['selective' => true]);
$result = Request::sendMessage($data);
$data['text'] = 'Insert your picture:';
$result = Request::sendMessage($data);
break;
}
$this->conversation->notes['photo_id'] = $message->getPhoto()[0]->getFileId();
/** @var PhotoSize $photo */
$photo = $message->getPhoto()[0];
$notes['photo_id'] = $photo->getFileId();
// no break
case 6:
if (is_null($message->getContact())) {
$this->conversation->notes['state'] = 6;
if ($message->getContact() === null) {
$notes['state'] = 6;
$this->conversation->update();
$data['text'] = 'Share your contact information:';
$data['reply_markup'] = new ReplyKeyboardMarkup(
[
'keyboard' => [
[
[
'text' => 'Share Contact',
'request_contact' => true
'request_contact' => true,
],
]
],
],
'resize_keyboard' => true,
'one_time_keyboard' => true,
'selective' => true,
]
);
$result = Request::sendMessage($data);
$data['text'] = 'Share your contact information:';
$result = Request::sendMessage($data);
break;
}
$this->conversation->notes['phone_number'] = $message->getContact()->getPhoneNumber();
$notes['phone_number'] = $message->getContact()->getPhoneNumber();
// no break
case 7:
$this->conversation->update();
$out_text = '/Survey result:' . "\n";
unset($this->conversation->notes['state']);
foreach ($this->conversation->notes as $k => $v) {
$out_text .= "\n" . ucfirst($k) . ': ' . $v;
$out_text = '/Survey result:' . PHP_EOL;
unset($notes['state']);
foreach ($notes as $k => $v) {
$out_text .= PHP_EOL . ucfirst($k) . ': ' . $v;
}
$data['photo'] = $this->conversation->notes['photo_id'];
$data['photo'] = $notes['photo_id'];
$data['reply_markup'] = new ReplyKeyBoardHide(['selective' => true]);
$data['caption'] = $out_text;
$this->conversation->stop();
$result = Request::sendPhoto($data);
break;
}
return $result;
}
}
......@@ -10,11 +10,12 @@
namespace Longman\TelegramBot\Commands\UserCommands;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Longman\TelegramBot\Commands\UserCommand;
use Longman\TelegramBot\Exception\TelegramException;
use Longman\TelegramBot\Request;
use Longman\TelegramBot\TelegramLog;
/**
* User "/weather" command
......@@ -39,7 +40,7 @@ class WeatherCommand extends UserCommand
/**
* @var string
*/
protected $version = '1.1.0';
protected $version = '1.2.0';
/**
* Base URI for OpenWeatherMap API
......@@ -54,7 +55,6 @@ class WeatherCommand extends UserCommand
* @param string $location
*
* @return string
* @throws \Longman\TelegramBot\Exception\TelegramException
*/
private function getWeatherData($location)
{
......@@ -69,7 +69,9 @@ class WeatherCommand extends UserCommand
try {
$response = $client->get($path, ['query' => $query]);
} catch (RequestException $e) {
throw new TelegramException($e->getMessage());
TelegramLog::error($e->getMessage());
return '';
}
return (string)$response->getBody();
......@@ -80,13 +82,13 @@ class WeatherCommand extends UserCommand
*
* @param array $data
*
* @return bool|string
* @return string
*/
private function getWeatherString(array $data)
{
try {
if (empty($data) || $data['cod'] !== 200) {
return false;
if (!(isset($data['cod']) && $data['cod'] === 200)) {
return '';
}
//http://openweathermap.org/weather-conditions
......@@ -101,16 +103,18 @@ class WeatherCommand extends UserCommand
$conditions_now = strtolower($data['weather'][0]['main']);
return sprintf(
'The temperature in %1$s (%2$s) is %3$s°C' . "\n" .
'Current conditions are: %4$s%5$s',
'The temperature in %s (%s) is %s°C' . "\n" .
'Current conditions are: %s%s',
$data['name'], //city
$data['sys']['country'], //country
$data['main']['temp'], //temperature
$data['weather'][0]['description'], //description of weather
(isset($conditions[$conditions_now])) ? $conditions[$conditions_now] : ''
isset($conditions[$conditions_now]) ? $conditions[$conditions_now] : ''
);
} catch (\Exception $e) {
return false;
} catch (Exception $e) {
TelegramLog::error($e->getMessage());
return '';
}
}
......@@ -118,6 +122,7 @@ class WeatherCommand extends UserCommand
* Command execute method
*
* @return mixed
* @throws \Longman\TelegramBot\Exception\TelegramException
*/
public function execute()
{
......@@ -126,11 +131,12 @@ class WeatherCommand extends UserCommand
$text = '';
if (trim($this->getConfig('owm_api_key'))) {
if ($location = trim($message->getText(true))) {
$location = trim($message->getText(true));
if ($location !== '') {
if ($weather_data = json_decode($this->getWeatherData($location), true)) {
$text = $this->getWeatherString($weather_data);
}
if (!$text) {
if ($text === '') {
$text = 'Cannot find weather for location: ' . $location;
}
} else {
......
......@@ -14,6 +14,8 @@ namespace Longman\TelegramBot\Commands\UserCommands;
use Longman\TelegramBot\Commands\UserCommand;
use Longman\TelegramBot\Entities\File;
use Longman\TelegramBot\Entities\PhotoSize;
use Longman\TelegramBot\Entities\UserProfilePhotos;
use Longman\TelegramBot\Request;
/**
......@@ -39,81 +41,86 @@ class WhoamiCommand extends UserCommand
/**
* @var string
*/
protected $version = '1.0.1';
/**
* @var bool
*/
protected $public = true;
protected $version = '1.1.0';
/**
* Command execute method
*
* @return mixed
* @throws \Longman\TelegramBot\Exception\TelegramException
*/
public function execute()
{
$message = $this->getMessage();
$user_id = $message->getFrom()->getId();
$from = $message->getFrom();
$user_id = $from->getId();
$chat_id = $message->getChat()->getId();
$message_id = $message->getMessageId();
$text = $message->getText(true);
//Send chat action
Request::sendChatAction(['chat_id' => $chat_id, 'action' => 'typing']);
$caption = 'Your Id: ' . $user_id . "\n";
$caption .= 'Name: ' . $message->getFrom()->getFirstName()
. ' ' . $message->getFrom()->getLastName() . "\n";
$caption .= 'Username: ' . $message->getFrom()->getUsername();
//Fetch user profile photo
$limit = 10;
$offset = null;
$ServerResponse = Request::getUserProfilePhotos([
'user_id' => $user_id,
'limit' => $limit,
'offset' => $offset,
]);
//Check if the request isOK
if ($ServerResponse->isOk()) {
$UserProfilePhoto = $ServerResponse->getResult();
$totalcount = $UserProfilePhoto->getTotalCount();
} else {
$totalcount = 0;
}
$data = [
'chat_id' => $chat_id,
'reply_to_message_id' => $message_id,
];
if ($totalcount > 0) {
$photos = $UserProfilePhoto->getPhotos();
//I pick the latest photo with the hight definition
$photo = $photos[0][2];
$file_id = $photo->getFileId();
$data['photo'] = $file_id;
$data['caption'] = $caption;
$result = Request::sendPhoto($data);
//Send chat action
Request::sendChatAction([
'chat_id' => $chat_id,
'action' => 'typing',
]);
$caption = sprintf(
'Your Id: %d' . PHP_EOL .
'Name: %s %s' . PHP_EOL .
'Username: %s',
$user_id,
$from->getFirstName(),
$from->getLastName(),
$from->getUsername()
);
//Download the image pictures
//Download after send message response to speedup response
$file_id = $photo->getFileId();
$ServerResponse = Request::getFile(['file_id' => $file_id]);
if ($ServerResponse->isOk()) {
Request::downloadFile($ServerResponse->getResult());
//Fetch user profile photo
$limit = 10;
$offset = null;
$response = Request::getUserProfilePhotos(
[
'user_id' => $user_id,
'limit' => $limit,
'offset' => $offset,
]
);
if ($response->isOk()) {
/** @var UserProfilePhotos $user_profile_photos */
$user_profile_photos = $response->getResult();
if ($user_profile_photos->getTotalCount() > 0) {
$photos = $user_profile_photos->getPhotos();
/** @var PhotoSize $photo */
$photo = $photos[0][2];
$file_id = $photo->getFileId();
$data['photo'] = $file_id;
$data['caption'] = $caption;
$result = Request::sendPhoto($data);
//Download the photo after send message response to speedup response
$response2 = Request::getFile(['file_id' => $file_id]);
if ($response2->isOk()) {
/** @var File $photo_file */
$photo_file = $response2->getResult();
Request::downloadFile($photo_file);
}
return $result;
}
} else {
//No Photo just send text
$data['text'] = $caption;
$result = Request::sendMessage($data);
}
return $result;
//No Photo just send text
$data['text'] = $caption;
return Request::sendMessage($data);
}
}
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