PHP Classes

File: src/TelegramCliWrapper.php

Recommend this page to a friend!
  Classes of Joseluis Laso   PHP Telegram CLI Wrapper   src/TelegramCliWrapper.php   Download  
File: src/TelegramCliWrapper.php
Role: Class source
Content type: text/plain
Description: Class source
Class: PHP Telegram CLI Wrapper
Send messages and other commands to Telegram users
Author: By
Last change: solving some warning trying to debug arrays
Date: 8 years ago
Size: 10,916 bytes
 

Contents

Class file image Download
<?php /** * @author: Joseluis Laso * based on the project https://github.com/zyberspace/php-telegram-cli-client */ namespace TelegramCliWrapper; use TelegramCliWrapper\Models\Dialog; use TelegramCliWrapper\Models\User; class TelegramCliWrapper { /** @var bool */ protected $debug = false; protected $socket; /** @var string */ protected $errorMessage = null; /** @var int */ protected $errorCode = null; /** argument types */ const PEER_ARG = 1; const MSG_ARG = 2; const PEER_LIST_ARG = 3; const TITLE_ARG = 4; const NAME_ARG = 5; const SURNAME_ARG = 6; const PHONE_ARG = 7; const NUMBER_ARG = 8; const URL_ARG = 9; /** * TelegramCliWrapper constructor. */ public function __construct($telegramSocket = "unix:///tmp/tg.sck", $debug = false) { $this->debug = $debug; $this->socket = stream_socket_client($telegramSocket); if (false === $this->socket) { throw new \Exception(sprintf('Could not connect to socket "%s"', $telegramSocket)); } // need to get dialog list in order that the rest of functions work $this->dialog_list(); } public function __destruct() { fclose($this->socket); } protected $map = array( 'status_online' => array(), 'status_offline' => array(), 'contact_list' => array(), 'get_self' => array(), 'stats' => array(), 'quit' => array(), 'send_typing' => array(), //sends message to the peer 'msg' => array( 'peer' => self::PEER_ARG, 'msg' => self::MSG_ARG, ), 'del_contact' => array( 'peer' => self::PEER_ARG, ), 'delete_msg' => array( 'msg_seqno' => self::MSG_ARG, ), 'delete_history' => array( 'peer' => self::PEER_ARG, ), 'chat_delete_user' => array( 'peer' => self::PEER_ARG, ), 'mark_read' => array( 'peer' => self::PEER_ARG, ), 'dialog_list' => array(), 'chat_info' => array( 'peer' => self::PEER_ARG, ), 'user_info' => array( 'peer' => self::PEER_ARG, ), 'block_user' => array( 'peer' => self::PEER_ARG, ), 'unblock_user' => array( 'peer' => self::PEER_ARG, ), 'broadcast' => array( 'peer_list' => self::PEER_LIST_ARG, 'msg' => self::MSG_ARG, ), 'create_group_chat' => array( 'title' => self::TITLE_ARG, 'peer_list' => self::PEER_LIST_ARG, ), 'rename_chat' => array( 'peer' => self::PEER_ARG, 'title' => self::TITLE_ARG, ), 'set_profile_name' => array( 'name' => self::NAME_ARG, 'surname' => self::SURNAME_ARG, ), 'send_photo' => array( 'peer' => self::PEER_ARG, 'photo' => self::URL_ARG, ), 'add_contact' => array( 'phone' => self::PHONE_ARG, 'name' => self::NAME_ARG, 'surname' => self::SURNAME_ARG, ), 'chat_add_user' => array( 'chat' => self::NAME_ARG, 'user' => self::NAME_ARG, 'num_of_msgs' => self::NUMBER_ARG, ), 'rename_contact' => array( 'peer' => self::PEER_ARG, 'name' => self::NAME_ARG, 'surname' => self::NAME_ARG, ), 'history' => array( 'peer' => self::PEER_ARG, 'limit' => self::NUMBER_ARG, ), ); /** * @param $name * @param array $args * @return bool|mixed * @throws \Exception */ public function __call($name, $args = array()) { $method = trim(strtolower($name)); $this->debug("Executing command '%s(%s)'\n", $method, implode(",",$args)); if (isset($this->map[$method])) { $methodDef = $this->map[$method]; if (count($args) != count($methodDef)) { throw new \Exception(sprintf("wrong number of parameters passed to '%s'", $method)); } $arguments = array(); if (count($methodDef)) { foreach ($methodDef as $fld => $methodArg) { $this->debug("'%s' => '%s'\n", $fld, $methodArg); switch ($methodArg) { case self::PEER_ARG: $arguments[] = $this->escapePeer(array_shift($args)); break; case self::NUMBER_ARG: $arguments[] = intval(array_shift($args)); break; case self::PHONE_ARG: $phoneNumber = array_shift($args); $processedPhoneNumber = preg_replace('%[^0-9]%', '', (string)$phoneNumber); if (empty($processedPhoneNumber)) { throw new \Exception("Number '%s' is not a real number", $phoneNumber); } $arguments[] = $processedPhoneNumber; break; case self::PEER_LIST_ARG: $arguments[] = $this->formatPeerList(array_shift($args)); break; case self::MSG_ARG: case self::NAME_ARG: case self::SURNAME_ARG: case self::TITLE_ARG: $arguments[] = $this->escapeStringArgument(array_shift($args)); break; case self::URL_ARG: $arguments[] = array_shift($args); break; } } } switch ($method) { case "chat_delete_user": // chat_delete_user needs to send twice the user name to be sure of the deletion $a = $arguments[] = array_shift($arguments); $arguments[] = $a; break; } $result = $this->execCommand($method, $arguments); $this->debug("Result of '%s' is '%s'\n", $method, $result); return $result; } else { throw new \Exception(sprintf("Unrecognized '%s' invoked\n", $method)); } } protected function debug() { if (!$this->debug) { return; } $args = func_get_args(); if (count($args) === 1) { print $args[0]; return; } $format = array_shift($args); foreach ($args as $k=>$arg) { if (!is_string($arg)) { $args[$k] = print_r($arg, true); } } vprintf($format, $args); } /** * @return string */ protected function getErrorMessage() { return $this->errorMessage; } /** * @return int */ protected function getErrorCode() { return $this->errorCode; } /** * @param $method * @param array $args * @return bool|mixed */ protected function execCommand($method, $args = array()) { $command = $method . ' ' . implode(' ', $args); $this->debug("::execCommand:: Executing command '%s'\n", $command); fwrite($this->socket, str_replace("\n", '\n', $command) . PHP_EOL); $answer = fgets($this->socket); //"ANSWER $bytes" or false if an error occurred if (is_string($answer)) { if (substr($answer, 0, 7) === 'ANSWER ') { $bytes = ((int)substr($answer, 7)) + 1; //+1 because the json-return seems to miss one byte if ($bytes > 0) { $bytesRead = 0; $jsonString = ''; //Run fread() till we have all the bytes we want //(as fread() can only read a maximum of 8192 bytes from a read-buffered stream at once) do { $jsonString .= fread($this->socket, $bytes - $bytesRead); $bytesRead = strlen($jsonString); } while ($bytesRead < $bytes); $json = json_decode($jsonString); if (!isset($json->error)) { //Reset error-message and error-code $this->errorMessage = null; $this->errorCode = null; //For "status_online" and "status_offline" if (isset($json->result) && $json->result === 'SUCCESS') { return true; } //Return json-object return $json; } else { $this->errorMessage = $json->error; $this->errorCode = $json->error_code; } } } } return false; } protected function escapeStringArgument($argument) { return '"' . addslashes($argument) . '"'; } protected function escapePeer($peer) { return str_replace(' ', '_', $peer); } protected function formatPeerList(array $peerList) { return implode(' ', array_map(array($this, 'escapePeer'), $peerList)); } protected function formatFileName($fileName) { return $this->escapeStringArgument(realpath($fileName)); } /** * return the list of users with active dialogs * * @return User[] */ public function getDialogList() { $dialogList = $this->dialog_list(); return User::fromArray($dialogList); } /** * return the list of dialogs of the peer passed * recover messages mark it as read * * @param string $peer * @return Dialog[] */ public function getHistory($peer, $numMsgs) { $history = $this->history($peer, $numMsgs); return Dialog::fromArray($history); } /** * @return User */ public function whoAmI() { return new User($this->get_self()); } /** * @param string $peer * @return User */ public function getUserInfo($peer) { return new User($this->user_info($peer)); } /** * @return User[] */ public function getContactList() { return User::fromArray($this->contact_list()); } /** * @param User $user * @return mixed */ public function addContact(User $user) { return $this->add_contact($user->phone, $user->first_name, $user->last_name); } }