View source
<?php
namespace Drupal\rocket_chat_api\RocketChat;
use BadFunctionCallException;
use Drupal;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;
use stdClass;
class ApiClient {
const HTTP_GET = 'GET';
const HTTP_POST = 'POST';
private $client;
private $config;
private $loggedIn = FALSE;
public function isLoggedIn() : bool {
return $this->loggedIn;
}
public function __construct(RocketChatConfigInterface $config, $login = FALSE) {
$this->config = $config;
if (!empty($config)) {
$this->client = $this
->createClient($login);
$userToken = $this->config
->getElement("rocket_chat_uit");
if (empty($userToken)) {
$this->loggedIn = FALSE;
}
else {
$this->loggedIn = TRUE;
}
}
else {
$this->config = NULL;
}
}
private function createClient($login = FALSE) {
$userId = $this->config
->getElement("rocket_chat_uid");
$userToken = $this->config
->getElement("rocket_chat_uit");
$guzzleConfig = [
'base_uri' => $this->config
->getElement('rocket_chat_url', "http://localhost:3000") . '/api/',
'allow_redirects' => FALSE,
'timeout' => 60,
'debug' => $this->config
->isDebug(),
'headers' => [
'X-Auth-Token' => $userToken,
'X-User-Id' => $userId,
],
];
if ($login) {
unset($guzzleConfig['headers']);
}
$guzzleConfig['headers']['Content-Type'] = 'application/json';
return new GuzzleClient($guzzleConfig);
}
public function login($id = NULL, $token = NULL) {
$rocket = $this->config
->getElement('rocket_chat_url', "http://localhost:3000");
$oldClient = $this->client;
$this->client = $this
->createClient(TRUE);
$params = [
'user' => $id,
'password' => $token,
];
$result = $this
->postToRocketChat('login', [
'json' => $params,
]);
$validReturn = self::validateReturn($result);
if (!$validReturn && $result['body']['status'] !== 'success') {
$this->config
->notify("Login to {$rocket} was Unsuccessful.", 'error');
unset($this->client);
$this->client = $oldClient;
return FALSE;
}
else {
unset($oldClient);
$this->config
->setElement("rocket_chat_uid", $result['body']['data']['userId']);
unset($result['body']['data']['userId']);
$this->config
->setElement("rocket_chat_uit", $result['body']['data']['authToken']);
unset($result['body']['data']['authToken']);
$this->config
->notify("Login to {$rocket} was Successful.", 'status');
$this->client = $this
->createClient(FALSE);
$this->loggedIn = TRUE;
return TRUE;
}
}
public function ping() {
return $this
->info()['code'] === 200;
}
public function postToRocketChat($method = "info", array $options = []) {
return $this
->sendToRocketChat(ApiClient::HTTP_POST, $method, $options);
}
private function sendToRocketChat($httpVerb = ApiClient::HTTP_GET, $method = "info", array $options = []) {
$result = new stdClass();
if ($method !== "info") {
$method = "v1/{$method}";
}
$resultHeader = [];
$resultString = "";
$resultStatus = "BROKEN";
$resultCode = 0;
try {
switch ($httpVerb) {
case ApiClient::HTTP_GET:
$result = $this->client
->get($method, $options);
break;
case ApiClient::HTTP_POST:
$result = $this->client
->post($method, $options);
break;
default:
throw new ClientException("HTTP Verb is unsupported", NULL, NULL, NULL, NULL);
}
$resultString = (string) $result
->getBody();
$resultHeader = $result
->getHeaders();
$resultCode = $result
->getStatusCode();
$resultStatus = $result
->getReasonPhrase();
} catch (ServerException $e) {
$resultStatus = $e
->getMessage();
$resultCode = $e
->getCode();
$resultString = [];
$resultString['status'] = 'failed';
$resultString['response'] = $e
->getResponse();
$resultHeader['content-type'][0] = "Error";
} catch (ClientException $e) {
$resultStatus = $e
->getMessage();
$resultCode = $e
->getCode();
$resultString = [];
$resultString['status'] = 'failed';
$resultString['response'] = $e
->getResponse();
$resultHeader['content-type'][0] = "Error";
} catch (Exception $e) {
Drupal::messenger()
->addError("ERROR " . $e
->getMessage());
}
if (isset($resultHeader['content-type']) && !isset($resultHeader['Content-Type'])) {
$resultHeader['Content-Type'] = $resultHeader['content-type'];
}
if ($resultHeader['Content-Type'][0] == 'application/json') {
$jsonDecoder = $this->config
->getJsonDecoder();
$resultString = $jsonDecoder($resultString);
}
$returnValue = [];
$returnValue['result'] = $result;
$returnValue['body'] = $resultString;
$returnValue['status'] = $resultStatus;
$returnValue['code'] = $resultCode;
return $returnValue;
}
public static function validateReturn(array &$result) {
if (!isset($result)) {
return FALSE;
}
if (empty($result)) {
return FALSE;
}
if (!is_array($result)) {
return FALSE;
}
if (!isset($result['status'])) {
return FALSE;
}
if ($result['status'] = 'failed') {
return FALSE;
}
return TRUE;
}
public function whoAmI() {
return $this
->getFromRocketChat('me');
}
public function getFromRocketChat($method = "info", array $options = []) {
return $this
->sendToRocketChat(ApiClient::HTTP_GET, $method, $options);
}
public function info() {
return $this
->getFromRocketChat('info');
}
public function logout() {
$logoutResult = $this
->postToRocketChat('logout');
if (self::validateReturn($logoutResult)) {
$this->loggedIn = FALSE;
}
return $logoutResult;
}
public function sudo($otherUserId, $functionName, ...$args) {
$empty = "";
if ($functionName == 'login' || $functionName == 'logout') {
throw new BadFunctionCallException("{$functionName} must be used directly not through sudo.", 502);
}
$returnValue = NULL;
$originalConfig = $this->config;
$newConfig = new InMemoryConfig($this->config, $empty, $empty);
try {
$authToken = $this
->postToRocketChat('users.createToken', [
'json' => [
'userId' => $otherUserId,
],
]);
$newConfig
->setElement('rocket_chat_uid', $authToken['body']['data']['userId']);
$newConfig
->setElement('rocket_chat_uit', $authToken['body']['data']['authToken']);
$this->config = $newConfig;
$this->client = $this
->createClient(FALSE);
$returnValue = $this
->{$functionName}(...$args);
} catch (Exception $e) {
throw $e;
} finally {
$this->config = $originalConfig;
$this->client = $this
->createClient(FALSE);
}
return $returnValue;
}
public function usersInfo($userId = NULL, $userName = NULL) {
$req = [];
$req['query'] = [];
if (!empty($userId)) {
$req['query']['userId'] = $userId;
}
if (!empty($userName)) {
$req['query']['username'] = $userName;
}
return $this
->getFromRocketChat('users.info', $req);
}
public function usersList() {
return $this
->getFromRocketChat('users.list');
}
public function channelsCreate($name, array $members = []) {
$options["name"] = $name;
if (!empty($members)) {
$options['members'] = $members;
}
return $this
->postToRocketChat('channels.create', [
'json' => $options,
]);
}
public function channelsList($offset = NULL, $count = NULL) {
$req = [];
$req['query'] = [];
if (!empty($offset)) {
$req['query']['offset'] = $offset;
}
if (!empty($count)) {
$req['query']['count'] = $count;
}
if (empty($req)) {
unset($req);
$req = NULL;
}
return $this
->getFromRocketChat('channels.list', $req);
}
public function channelsInfo($roomId = NULL, $roomName = NULL) {
$req = [];
$req['query'] = [];
if (!empty($roomId)) {
$req['query']['roomId'] = $roomId;
}
if (!empty($roomName)) {
$req['query']['roomName'] = $roomName;
}
return $this
->getFromRocketChat('channels.info', $req);
}
public function channelsHistory($roomId, $unreads = NULL, $inclusive = NULL, $count = NULL, $latest = NULL, $oldest = NULL) {
$req = [];
$req['query'] = [];
$req['query']['roomId'] = $roomId;
if (!empty($latest)) {
$req['query']['latest'] = $latest;
}
if (!empty($oldest)) {
$req['query']['oldest'] = $oldest;
}
if (isset($inclusive)) {
$req['query']['inclusive'] = $inclusive;
}
if (!empty($count)) {
$req['query']['count'] = $count;
}
if (isset($unreads)) {
$req['query']['unreads'] = $unreads;
}
return $this
->getFromRocketChat('channels.history', $req);
}
public function postMessage($roomId = NULL, $channel = NULL, $text = NULL, $alias = NULL, $emoji = NULL, $avatar = NULL, $attachments = NULL) {
$params = [];
if (!empty($roomId)) {
$params['roomId'] = $roomId;
}
if (!empty($channel)) {
$params['channel'] = $channel;
}
if (!empty($text)) {
$params['text'] = $text;
}
if (!empty($alias)) {
$params['alias'] = $alias;
}
if (!empty($emoji)) {
$params['emoji'] = $emoji;
}
if (!empty($avatar)) {
$params['avatar'] = $avatar;
}
if (!empty($attachments)) {
$params['attachments'] = $attachments;
}
return $this
->postToRocketChat('chat.postMessage', [
'json' => $params,
]);
}
}