You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
5.9 KiB
245 lines
5.9 KiB
<?php
|
|
|
|
/**
|
|
* This file is part of the PHP Telegram Bot example-bot package.
|
|
* https://github.com/php-telegram-bot/example-bot/
|
|
*
|
|
* (c) PHP Telegram Bot Team
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
/**
|
|
* User "/date" command
|
|
*
|
|
* Shows the date and time of the location passed as the parameter.
|
|
*
|
|
* A Google API key is required for this command!
|
|
* You can be set in your config.php file:
|
|
* ['commands']['configs']['date'] => ['google_api_key' => 'your_google_api_key_here']
|
|
*/
|
|
|
|
namespace Longman\TelegramBot\Commands\UserCommands;
|
|
|
|
use GuzzleHttp\Client;
|
|
use GuzzleHttp\Exception\RequestException;
|
|
use Longman\TelegramBot\Commands\UserCommand;
|
|
use Longman\TelegramBot\Entities\ServerResponse;
|
|
use Longman\TelegramBot\Exception\TelegramException;
|
|
use Longman\TelegramBot\Request;
|
|
use Longman\TelegramBot\TelegramLog;
|
|
|
|
class DateCommand extends UserCommand
|
|
{
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $name = 'date';
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $description = 'Show date/time by location';
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $usage = '/date <location>';
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $version = '1.5.0';
|
|
|
|
/**
|
|
* Guzzle Client object
|
|
*
|
|
* @var Client
|
|
*/
|
|
private $client;
|
|
|
|
/**
|
|
* Base URI for Google Maps API
|
|
*
|
|
* @var string
|
|
*/
|
|
private $google_api_base_uri = 'https://maps.googleapis.com/maps/api/';
|
|
|
|
/**
|
|
* The Google API Key from the command config
|
|
*
|
|
* @var string
|
|
*/
|
|
private $google_api_key;
|
|
|
|
/**
|
|
* Date format
|
|
*
|
|
* @var string
|
|
*/
|
|
private $date_format = 'd-m-Y H:i:s';
|
|
|
|
/**
|
|
* Get coordinates of passed location
|
|
*
|
|
* @param string $location
|
|
*
|
|
* @return array
|
|
*/
|
|
private function getCoordinates($location): array
|
|
{
|
|
$path = 'geocode/json';
|
|
$query = ['address' => urlencode($location)];
|
|
|
|
if ($this->google_api_key !== null) {
|
|
$query['key'] = $this->google_api_key;
|
|
}
|
|
|
|
try {
|
|
$response = $this->client->get($path, ['query' => $query]);
|
|
} catch (RequestException $e) {
|
|
TelegramLog::error($e->getMessage());
|
|
|
|
return [];
|
|
}
|
|
|
|
if (!($data = $this->validateResponseData($response->getBody()))) {
|
|
return [];
|
|
}
|
|
|
|
$result = $data['results'][0];
|
|
$lat = $result['geometry']['location']['lat'];
|
|
$lng = $result['geometry']['location']['lng'];
|
|
$acc = $result['geometry']['location_type'];
|
|
$types = $result['types'];
|
|
|
|
return [$lat, $lng, $acc, $types];
|
|
}
|
|
|
|
/**
|
|
* Get date for location passed via coordinates
|
|
*
|
|
* @param string $lat
|
|
* @param string $lng
|
|
*
|
|
* @return array
|
|
* @throws \Exception
|
|
*/
|
|
private function getDate($lat, $lng): array
|
|
{
|
|
$path = 'timezone/json';
|
|
|
|
$date_utc = new \DateTimeImmutable(null, new \DateTimeZone('UTC'));
|
|
$timestamp = $date_utc->format('U');
|
|
|
|
$query = [
|
|
'location' => urlencode($lat) . ',' . urlencode($lng),
|
|
'timestamp' => urlencode($timestamp),
|
|
];
|
|
|
|
if ($this->google_api_key !== null) {
|
|
$query['key'] = $this->google_api_key;
|
|
}
|
|
|
|
try {
|
|
$response = $this->client->get($path, ['query' => $query]);
|
|
} catch (RequestException $e) {
|
|
TelegramLog::error($e->getMessage());
|
|
|
|
return [];
|
|
}
|
|
|
|
if (!($data = $this->validateResponseData($response->getBody()))) {
|
|
return [];
|
|
}
|
|
|
|
$local_time = $timestamp + $data['rawOffset'] + $data['dstOffset'];
|
|
|
|
return [$local_time, $data['timeZoneId']];
|
|
}
|
|
|
|
/**
|
|
* Evaluate the response data and see if the request was successful
|
|
*
|
|
* @param string $data
|
|
*
|
|
* @return array
|
|
*/
|
|
private function validateResponseData($data): array
|
|
{
|
|
if (empty($data)) {
|
|
return [];
|
|
}
|
|
|
|
$data = json_decode($data, true);
|
|
if (empty($data)) {
|
|
return [];
|
|
}
|
|
|
|
if (isset($data['status']) && $data['status'] !== 'OK') {
|
|
return [];
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Get formatted date at the passed location
|
|
*
|
|
* @param string $location
|
|
*
|
|
* @return string
|
|
* @throws \Exception
|
|
*/
|
|
private function getFormattedDate($location): string
|
|
{
|
|
if ($location === null || $location === '') {
|
|
return 'The time in nowhere is never';
|
|
}
|
|
|
|
[$lat, $lng] = $this->getCoordinates($location);
|
|
if (empty($lat) || empty($lng)) {
|
|
return 'It seems that in "' . $location . '" they do not have a concept of time.';
|
|
}
|
|
|
|
[$local_time, $timezone_id] = $this->getDate($lat, $lng);
|
|
|
|
$date_utc = new \DateTimeImmutable(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);
|
|
}
|
|
|
|
/**
|
|
* Main command execution
|
|
*
|
|
* @return ServerResponse
|
|
* @throws TelegramException
|
|
*/
|
|
public function execute(): ServerResponse
|
|
{
|
|
// First we set up the necessary member variables.
|
|
$this->client = new Client(['base_uri' => $this->google_api_base_uri]);
|
|
if (($this->google_api_key = trim($this->getConfig('google_api_key'))) === '') {
|
|
$this->google_api_key = null;
|
|
}
|
|
|
|
$message = $this->getMessage();
|
|
|
|
$chat_id = $message->getChat()->getId();
|
|
$location = $message->getText(true);
|
|
|
|
$text = 'You must specify location in format: /date <city>';
|
|
|
|
if ($location !== '') {
|
|
$text = $this->getFormattedDate($location);
|
|
}
|
|
|
|
$data = [
|
|
'chat_id' => $chat_id,
|
|
'text' => $text,
|
|
];
|
|
|
|
return Request::sendMessage($data);
|
|
}
|
|
}
|