Last active
July 18, 2019 05:59
-
-
Save emrancu/0f60d8b1dde42b13ccb6ffa7843d8baf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Controllers\Gmail; | |
use App\Http\Controllers\Assets\RequestHandlerController; | |
use App\Models\Core\Bot; | |
use App\Models\Core\IntentFlow; | |
use App\Models\Core\Question; | |
use App\Models\Elements\CRM\Contact; | |
use App\Models\Facebook\Audiences\Attribute; | |
use App\Models\Integrations\CalendarIntegration; | |
use App\Utilities\NLP\ConfusedQuestions; | |
use App\Utilities\NLP\NLPHandler; | |
use function foo\func; | |
use GuzzleHttp\Client; | |
use GuzzleHttp\Exception\GuzzleException; | |
use Illuminate\Http\JsonResponse; | |
use Sentinel; | |
use App\Models\Facebook\Audiences\Audiences; | |
use Illuminate\Http\Request; | |
use App\Http\Controllers\Controller; | |
use Google_Client; | |
use Illuminate\Support\Facades\Cache; | |
use Illuminate\Support\Facades\Log; | |
use Illuminate\Support\Facades\Session; | |
use Illuminate\Support\Facades\Redirect; | |
use App\Models\Gmail\GmailBot; | |
use Webpatser\Uuid\Uuid; | |
use Illuminate\Support\Str; | |
class GmailController extends Controller | |
{ | |
public $client; | |
public $accessToken; | |
public $tokenInfo; | |
public $header; | |
public $refreshToken; | |
public $emailAddress; | |
public $userInfoFromDb; | |
public $answer; | |
public $nlpData; | |
public $intentAnswer; | |
public $intents = null; | |
public function __construct() | |
{ | |
$this->client = new Google_Client(); | |
$this->client->setClientId(config('chatbot.GMAIL_CONFIG.CLIENT_ID')); | |
$this->client->setClientSecret(config('chatbot.GMAIL_CONFIG.CLIENT_SECRET')); | |
$this->client->setRedirectUri(config('chatbot.GMAIL_CONFIG.REDIRECT_URL')); | |
//$this->client->setRedirectUri("https://41579ef5.ngrok.io/api/gmail/token"); | |
$this->client->setDeveloperKey('AIzaSyAoIcllkW9PswynNsc4HrbHIv38Gw1Sh1k'); | |
$this->client->addScope('https://mail.google.com/'); | |
$this->client->addScope('https://www.googleapis.com/auth/calendar'); | |
$this->client->setAccessType('offline'); | |
$this->client->setApprovalPrompt('force'); | |
} | |
/** | |
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View | |
*/ | |
public function index() { | |
return view("gmail.create"); | |
} | |
/** | |
* @param $mail_address | |
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View | |
*/ | |
public function dashboard($mail_address) | |
{ | |
$bot_key = $mail_address; | |
$botType = Bot::findBotType($bot_key); | |
return view("gmail.index", compact('bot_key', 'mail_address', 'botType')); | |
} | |
/** | |
* @return bool | |
* @throws GuzzleException | |
*/ | |
public function create() | |
{ | |
$this->accessToken = Cache::get('token') ? Cache::get('token') : $this->getToken(); | |
if ($this->accessToken) { | |
$this->header = [ | |
'Content-type' => 'application/json', | |
'Authorization' => 'Bearer ' . $this->accessToken | |
]; | |
// For watch property | |
$data = [ | |
"topicName" => "projects/cl-gmail/topics/cl-mail-pusher", | |
"labelIds" => ["INBOX"] | |
]; | |
$watchUrl = "https://www.googleapis.com/gmail/v1/users/me/watch"; | |
$watchResult = json_decode(RequestHandlerController::sendRequest($watchUrl, 'post', $this->header, $data)); | |
Cache::put('updatedHistoryId', $watchResult->historyId, $watchResult->expiration); | |
$user = Sentinel::getUser(); | |
$uniqueBotKey = Str::orderedUuid(); | |
$botData = [ | |
'id' => $uniqueBotKey, | |
'bot_name' => 'Gmail Bot', //Cache::get('botName'), | |
'bot_key' => $uniqueBotKey, | |
'mail_address' => Cache::get('mailAddress'), | |
'refresh_token' => Cache::get('refreshToken'), | |
'access_token' => Cache::get('token'), | |
'updated_history_id' => Cache::get('updatedHistoryId'), | |
'user_id' => $user->id | |
]; | |
$checkBot = GmailBot::whereMailAddress( Cache::get('mailAddress'))->first(); | |
if ($checkBot) { | |
$checkBot->update([ | |
'refresh_token' => Cache::get('refreshToken'), | |
'access_token' => Cache::get('token'), | |
]); | |
Cache::forget('botName'); | |
Cache::forget('mailAddress'); | |
Cache::forget('refreshToken'); | |
Cache::forget('accessToken'); | |
Cache::forget('updatedHistoryId'); | |
Cache::forget('token'); | |
return redirect('gmail-bots')->with(['error' => 'A bot has already been created against this Gmail address.']); | |
} | |
GmailBot::create($botData); | |
Cache::forget('botName'); | |
Cache::forget('mailAddress'); | |
Cache::forget('refreshToken'); | |
Cache::forget('accessToken'); | |
Cache::forget('updatedHistoryId'); | |
Cache::forget('token'); | |
//need appropriate route | |
//return redirect()->route('dummy route'); | |
return Redirect::to('gmail-bots'); | |
} | |
return true; | |
} | |
/** | |
* @return bool|\Illuminate\Http\RedirectResponse|string | |
* @throws GuzzleException | |
*/ | |
public function getToken() | |
{ | |
if (!isset($_GET['code'])) { | |
$auth_url = $this->client->createAuthUrl(); | |
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL)); | |
exit(); | |
} elseif (isset($_GET['code'])) { | |
$this->tokenInfo = $this->client->fetchAccessTokenWithAuthCode($_GET['code']); | |
$this->client->setAccessToken($this->tokenInfo); | |
$this->refreshToken = $this->client->getRefreshToken(); | |
//if refreshToken is null, means bot already exits. So return to home | |
if ($this->refreshToken == null) { | |
//need appropriate route | |
//return redirect()->route('dummy route'); | |
return redirect()->back()->with(['error' => 'Email is already used']); | |
} | |
$this->emailAddress = $this->getUserMailAddress($this->tokenInfo['access_token']); | |
Cache::put('mailAddress', $this->emailAddress, 15); | |
Cache::put('refreshToken', $this->refreshToken, '15'); | |
Cache::put('accessToken_' . $this->emailAddress, $this->tokenInfo['access_token'], now()->addSeconds($this->tokenInfo['expires_in'])); | |
Cache::put('token', $this->tokenInfo['access_token'], 15); | |
return redirect()->route('gmail.create'); | |
} | |
return false; | |
} | |
/** | |
* @param Request $request | |
* @return \Illuminate\Contracts\Routing\ResponseFactory|JsonResponse|\Illuminate\Http\Response | |
* @throws GuzzleException | |
*/ | |
public function webhook(Request $request) | |
{ | |
try { | |
//Extracting mail address from webhook notification | |
$rcvdNotificationData = base64_decode(strtr($request->message['data'], '-_', '+/')); | |
$mailAndHistoryData = json_decode($rcvdNotificationData); | |
$userMailId = $mailAndHistoryData->emailAddress; | |
//Getting user details from db for further use | |
$this->userInfoFromDb = GmailBot::whereMailAddress($userMailId)->first(); | |
//Checking if the user access_token expires or not | |
if (!Cache::has('accessToken_' . $userMailId)) { | |
$this->tokenInfo = $this->client->fetchAccessTokenWithRefreshToken($this->userInfoFromDb->refresh_token); | |
Cache::put('accessToken_' . $userMailId, $this->tokenInfo['access_token'], now()->addSeconds($this->tokenInfo['expires_in'])); | |
} | |
$header = [ | |
'Content-type' => 'application/json', | |
'Authorization' => 'Bearer ' . Cache::get('accessToken_' . $userMailId) | |
]; | |
//getting all new email data in between two history id | |
$historyData = $this->getHistoryData($header, $this->userInfoFromDb->updated_history_id); | |
//updating history id for next webhook operation | |
$updatedHistoryId = $mailAndHistoryData->historyId; | |
$this->userInfoFromDb->update(['updated_history_id' => $updatedHistoryId]); | |
if ($historyData && count($historyData) > 0) { | |
$this->mailSendingProcedure($historyData, $header); | |
} | |
return response('success', '200'); | |
} catch (\Exception $ex) { | |
return response()->json('success', 200); | |
} | |
} | |
/** | |
* @param $token | |
* @return mixed | |
* @throws GuzzleException | |
*/ | |
public function getUserMailAddress($token) | |
{ | |
$header = [ | |
'Content-type' => 'application/json', | |
'Authorization' => 'Bearer ' . $token | |
]; | |
$url = "https://www.googleapis.com/gmail/v1/users/me/profile"; | |
$userInfo = json_decode(RequestHandlerController::sendRequest($url, 'get', $header)); | |
$this->emailAddress = $userInfo->emailAddress; | |
return $this->emailAddress; | |
} | |
/** | |
* @param $header | |
* @param $updatedHistoryIdFromDb | |
* @return mixed | |
* @throws GuzzleException | |
*/ | |
public function getHistoryData($header, $updatedHistoryIdFromDb) | |
{ | |
$historyUrl = "https://www.googleapis.com/gmail/v1/users/me/history?historyTypes=messageAdded&startHistoryId=" . $updatedHistoryIdFromDb; // its the 1 step back history id from webhook. get it from db | |
$historyDataList = json_decode(RequestHandlerController::sendRequest($historyUrl, 'get', $header), true); | |
return array_get($historyDataList, 'history'); | |
} | |
/** | |
* @param $historyData | |
* @param $header | |
* @throws \Exception | |
* @throws GuzzleException | |
*/ | |
public function mailSendingProcedure($historyData, $header) | |
{ | |
//listing all new email ids from $historyData | |
$mailIdsFromHistoryList = array(); | |
foreach ($historyData as $key => $value) { | |
$mailIdsFromHistoryList[$key] = $value['messages'][0]['id']; | |
} | |
for ($i = 0; $i < sizeof($mailIdsFromHistoryList); $i++) { | |
//mail details work steps | |
$mailId = $mailIdsFromHistoryList[$i]; | |
//operation by individual mail ids. | |
$mailUrl = "https://www.googleapis.com/gmail/v1/users/me/messages/" . $mailId; | |
$mailDetails = RequestHandlerController::sendRequest($mailUrl, 'get', $header); | |
$decodedMailDetails = json_decode($mailDetails); | |
if (in_array('INBOX', $decodedMailDetails->labelIds)) { | |
$mailInfo = $this->extractMailInformation($decodedMailDetails); | |
if ($mailInfo['inReplyTo'] == null) { | |
$this->createAudienceForGmailBot($mailInfo); | |
} | |
$this->replyOfMail($mailInfo); | |
} | |
} | |
} | |
/** | |
* @param $decodedMailDetails | |
* @return array | |
* @throws GuzzleException | |
*/ | |
public function extractMailInformation($decodedMailDetails) | |
{ | |
//13 variables | |
$senderNameAndMail = null; | |
$senderMail = null; | |
$senderName = null; | |
$receivedAt = null; | |
$timeZone = null; | |
$mailBody = null; | |
$messageId = null; | |
$subject = null; | |
$receiverNameMail = null; | |
$receiverMail = null; | |
$threadId = null; | |
$reference = null; | |
$inReplyTo = null; | |
foreach ($decodedMailDetails->payload->headers as $headData) { | |
switch ($headData->name) { | |
case 'From': | |
$senderNameAndMail = $headData->value; | |
break; | |
case 'Return-Path': | |
$senderMail = trim(str_replace(['<', '>'], '', $headData->value)); | |
break; | |
case 'Date': | |
$receivedAt = $headData->value; | |
break; | |
case 'Message-ID': | |
$messageId = $headData->value; | |
break; | |
case 'Subject': | |
$subject = $headData->value; | |
break; | |
case 'To': | |
$receiverNameMail = $headData->value; | |
break; | |
case 'Delivered-To': | |
$receiverMail = $headData->value; | |
break; | |
case 'References': | |
$reference = $headData->value; | |
break; | |
case 'In-Reply-To': | |
$inReplyTo = $headData->value; | |
break; | |
} | |
} | |
//text | |
$mailBody = base64_decode(strtr($decodedMailDetails->payload->parts[0]->body->data, '-_', '+/')); | |
//Log::info('raw data: ' . $decodedMailDetails->payload->parts[0]->body->data); | |
$senderName = trim(str_replace([$senderMail, '<', '>', '"'], '', $senderNameAndMail)); | |
$receiverName = trim(str_replace([$receiverMail, '<', '>', '"'], '', $receiverNameMail)); | |
$timeZone = substr($receivedAt, -5); | |
$threadId = $decodedMailDetails->threadId; | |
// Extracting body and signature from mailbody | |
$bodyAndSignature = $this->mailBodyExtractorFromPythonEndpoint($mailBody); | |
$decodedBodyAndSignature = json_decode($bodyAndSignature); | |
$contactNum = $this->getContactNum($decodedBodyAndSignature->signature); | |
return [ | |
'senderNameAndMail' => $senderNameAndMail, | |
'senderMail' => $senderMail, | |
'senderName' => $senderName, | |
'receivedAt' => $receivedAt, | |
'mailBody' => trim($decodedBodyAndSignature->body), | |
'messageId' => $messageId, | |
'subject' => $subject, | |
'receiverNameMail' => $receiverNameMail, | |
'receiverMail' => $receiverMail, | |
'receiverName' => $receiverName, | |
'timeZone' => $timeZone, | |
'threadId' => $threadId, | |
'reference' => $reference, | |
'inReplyTo' => $inReplyTo, | |
'signature' => $decodedBodyAndSignature->signature, | |
'contact' => $contactNum, | |
'body_intent' => $decodedBodyAndSignature->appointment | |
]; | |
} | |
/** | |
* @param $SignatureData | |
* @return mixed | |
* @throws GuzzleException | |
*/ | |
public function getContactNum($SignatureData) | |
{ | |
$signatureHeader = [ | |
'Content-type' => 'appliction/json' | |
]; | |
$signature = [ | |
"text" => $SignatureData | |
]; | |
try { | |
$contactData = json_decode(RequestHandlerController::sendRequest('http://128.199.149.246/closerbot', 'post', $signatureHeader, $signature)); | |
$mobile = null; | |
if (!empty($contactData->phone_numbers[0])) { | |
$mobile = $contactData->phone_numbers[0]; | |
} | |
return $mobile; | |
} catch (\Exception $e) { | |
Log::info('Cant extract mobile num: ' . $e); | |
} | |
} | |
/** | |
* @param $mailBody | |
* @return null|\Psr\Http\Message\StreamInterface|string | |
* @throws GuzzleException | |
*/ | |
public function mailBodyExtractorFromPythonEndpoint($mailBody) | |
{ | |
$headerForBodyExtraction = [ | |
'Content-type' => 'Application/json' | |
]; | |
$bodyToExtract = [ | |
'email' => $mailBody | |
//'email' => addslashes($mailBody) | |
]; | |
$bodyAndSignature = null; | |
try { | |
$bodyAndSignature = RequestHandlerController::sendRequest('http://128.199.149.246/email', 'post', $headerForBodyExtraction, $bodyToExtract); | |
} catch (\Exception $error) { | |
Log::info("Error : " . $error); | |
} | |
return $bodyAndSignature; | |
} | |
/** | |
* reply of mail in thread for both new mail and replay mail | |
* @param $mailInfo | |
* @throws GuzzleException | |
*/ | |
public function replyOfMail($mailInfo) | |
{ | |
//saving user info in crm | |
$this->saveUserInfoToCrm($mailInfo); | |
$mailToBeSent = $this->mailContentToBeSent($mailInfo); | |
if($this->answer === null){ | |
Log::info('null answer'); | |
exit(); | |
} | |
$mailFormat = $this->rfcMailFormat($mailToBeSent, $mailInfo); | |
$this->client->setAccessToken(Cache::get('accessToken_' . trim($mailInfo['receiverMail']))); | |
$objGMail = new \Google_Service_Gmail($this->client); | |
//sending mail | |
try { | |
$mime = rtrim(strtr(base64_encode($mailFormat), '+/', '-_'), '='); | |
$msg = new \Google_Service_Gmail_Message(); | |
$msg->setRaw($mime); | |
$msg->setThreadId($mailInfo['threadId']); | |
$sent = $objGMail->users_messages->send("me", $msg); | |
//Log::info($sent->labelIds[0]); | |
} catch (\Exception $error) { | |
Log::info("Can not send email (Error) : " . $error); | |
} | |
} | |
/** | |
* @param $mailInfo | |
*/ | |
public function saveUserInfoToCrm($mailInfo) | |
{ | |
try { | |
$crm = Contact::whereEmail(trim($mailInfo['senderMail']))->first(); | |
$botId = GmailBot::whereMailAddress(trim($mailInfo['receiverMail']))->first(); | |
if ($crm == null) { | |
$crmData = [ | |
"alias_id" => Uuid::generate()->string, | |
"name" => $mailInfo['senderName'], | |
"designation" => $mailInfo['signature'], | |
"email" => $mailInfo['senderMail'], | |
"contact" => $mailInfo['contact'], | |
"bot_id" => $botId['id'] | |
]; | |
Contact::create($crmData); | |
} | |
} catch (\Exception $e) { | |
Log::info($e); | |
} | |
} | |
/** | |
* @param $mailInfo | |
* @return string | |
* @throws GuzzleException | |
*/ | |
public function mailContentToBeSent($mailInfo) | |
{ | |
$gmailBot = GmailBot::whereMailAddress(trim($mailInfo['receiverMail']))->first(); | |
//If intent is set | |
if (Cache::has('intent_' . $mailInfo['senderMail'] . $mailInfo['threadId'])) { | |
$this->setStringToEventAns($mailInfo); | |
$this->setAttribute($mailInfo); | |
//setting up task for action if there is any | |
$action = Cache::get('action_' . $mailInfo['senderMail'] . $mailInfo['threadId']); | |
if (isset($action)) { | |
//calendar event action added | |
if (CalendarIntegration::whereBotKey(trim($mailInfo['receiverMail']))->first()) { | |
if ($action->name == "calendar_event") { | |
$createEvent = $this->sendDataToCalendarEnd($mailInfo); | |
$ans = $this->ansOnCreateEventStatus($createEvent, $action, $mailInfo); | |
return $ans; | |
} | |
} | |
} else { | |
$this->answer = "Thanks we've taken the information."; | |
} | |
$this->clearCache($mailInfo); | |
return $this->answer; | |
} // Getting intents from nlpHandler if intent_$mailAddress is not set | |
elseif (!Cache::has('intent_' . $mailInfo['senderMail'] . $mailInfo['threadId'])) { | |
//eliminating all the \n in the text | |
$mailInfo['mailBody'] = trim(str_replace("\n", " ", $mailInfo['mailBody'])); | |
//This part is only for calendar event. | |
//Intent is coming from mailbody object from python endpoint | |
//Integration check | |
if (CalendarIntegration::whereBotKey(trim($mailInfo['receiverMail']))->first()) { | |
if ($mailInfo['body_intent'] == 'appointment' && $intentFlow = IntentFlow::whereBotId($gmailBot['bot_key'])->whereIntent('appointment')->first()) { | |
$ans = $this->resultFromRequiredEntity($intentFlow, $mailInfo, $mailInfo['body_intent']); | |
return $ans; | |
} | |
} | |
//This part works in general case | |
//Looking for intent | |
$this->nlpData = new NLPHandler([$mailInfo['mailBody']]); | |
$this->intents = $this->nlpData->getIntents(); | |
//if found any intent | |
if (count($this->intents) > 0 && $intentFlow = IntentFlow::whereBotId($gmailBot['bot_key'])->whereIntent(trim($this->intents[0]))->first()) { | |
$ans = $this->resultFromRequiredEntity($intentFlow, $mailInfo, $this->intents[0]); | |
return $ans; | |
} //finding answer in answer table based on user messages if flag is true and didn't find any intent | |
elseif ($question = Question::whereBotId(trim($gmailBot['bot_key']))->whereMessage(trim($mailInfo['mailBody']))->with('answers')->first()) { | |
$ans = $this->resultFromFlow($question); | |
return $ans; | |
} else { | |
$ans = $this->resultFromNlu($mailInfo, $gmailBot); | |
return $ans; | |
} | |
} | |
} | |
/** | |
* mailbody to calendar event data formation | |
* @param $mailInfo | |
*/ | |
public function setStringToEventAns($mailInfo) | |
{ | |
$stringResult = $mailInfo['mailBody']; | |
$result = explode("\n", $stringResult); | |
foreach ($result as $key => $value) { | |
//filtering the event requirements only. must 1. format | |
if (preg_match("/[1-3]\./", $value)) { | |
$this->intentAnswer[$key] = trim(substr($value, 2)); | |
} | |
} | |
Log::info('re ans: ' . json_encode($this->intentAnswer)); | |
} | |
/** | |
* saving attributes | |
* @param $mailInfo | |
*/ | |
public function setAttribute($mailInfo) | |
{ | |
$requiredEntities = Cache::get('requiredEntity_' . $mailInfo['senderMail'] . $mailInfo['threadId']); | |
//saving attribute based on intent | |
foreach ($requiredEntities as $key => $requiredEntity) { | |
$psId = trim($mailInfo['senderMail']) . '_' . trim($mailInfo['receiverMail']); | |
$audience = Audiences::wherePsid($psId)->first(); | |
$attributeData = [ | |
"audiences_id" => $audience['id'], | |
"audiences_uid" => $audience['uid'], | |
"attribute_name" => $requiredEntity->attribute_name, | |
"attribute_value" => $this->intentAnswer[$key], | |
"attribute_slug" => $requiredEntity->attribute_slug | |
]; | |
try { | |
Attribute::create($attributeData); | |
} catch (\Exception $error) { | |
Log::info("Error: Attribute cant be saved. " . $error); | |
} | |
} | |
} | |
/** | |
* @param $mailInfo | |
* @return mixed | |
* @throws GuzzleException | |
*/ | |
public function sendDataToCalendarEnd($mailInfo) | |
{ | |
$header = [ | |
'Content-type' => 'application/json' | |
]; | |
//Log::info('time zone: '.$mailInfo['timeZone']); | |
$calendarEventData = [ | |
"title" => "Meeting with " . $mailInfo['senderName'], | |
"description" => '', | |
"location" => '', | |
"startTime" => $this->intentAnswer[0], | |
"endTime" => $this->intentAnswer[1], | |
"eventDate" => $this->intentAnswer[2], | |
"timeZone" => $mailInfo['timeZone'] | |
]; | |
Log::info('calendar data: ' . json_encode($calendarEventData)); | |
try { | |
//sending $calendarEventData to python end for error fixing if there is any | |
//$urlForDateFormation = "http://128.199.149.246/datetime"; | |
//$formattedCalendarEventData = RequestHandlerController::sendRequest($urlForDateFormation,'post', $header,$calendarEventData); | |
//event create | |
$eventUrl = 'https://platform.chatleads.io/api/calendar/createEvent/' . $mailInfo['receiverMail']; | |
$createEvent = json_decode(RequestHandlerController::sendRequest($eventUrl, 'post', $header, $calendarEventData)); | |
return $createEvent; | |
} catch (\Exception $e) { | |
Log::info($e); | |
} | |
return false; | |
} | |
/** | |
* @param $createEvent | |
* @param $action | |
* @param $mailInfo | |
* @return string | |
*/ | |
public function ansOnCreateEventStatus($createEvent, $action, $mailInfo) | |
{ | |
if ($createEvent->status === 'success') { | |
$this->clearCache($mailInfo); | |
return $this->answer = $action->response_message . PHP_EOL; | |
} elseif ($createEvent->status === 'busy') { | |
//checking if there is any free slot for next 7 days | |
if (count($createEvent->availableSlot->slotTimes) < 1) { | |
$this->clearCache($mailInfo); | |
$this->answer = $this->getBusyAns($mailInfo); | |
return $this->answer; | |
} | |
$this->answer = $this->getSlotAns($mailInfo); | |
$this->answer .= 'Date: ' . $createEvent->availableSlot->slotDate . PHP_EOL; | |
foreach ($createEvent->availableSlot->slotTimes as $slot) { | |
$this->answer .= 'Start: ' . $slot->start . ' ' . 'End: ' . $slot->end . PHP_EOL; | |
} | |
return $this->answer; | |
} elseif ($createEvent->status === 'failed') { | |
$this->clearCache($mailInfo); | |
return $createEvent->message; | |
} | |
} | |
/** | |
* @param $mailInfo | |
* @return string | |
*/ | |
public function getBusyAns($mailInfo) | |
{ | |
$busyAnswer = 'So I checked ' . $mailInfo['receiverName'] . '\'s calendar and it looks like they are busy for the entire week. Would you like me to follow up in a couple of days with some alternate slots?' . PHP_EOL . PHP_EOL; | |
$busyAnswer .= 'Looking forward to hearing from you!' . PHP_EOL . PHP_EOL; | |
return $busyAnswer; | |
} | |
/** | |
* @param $mailInfo | |
* @return string | |
*/ | |
public function getSlotAns($mailInfo) | |
{ | |
$slotAns = 'It looks like ' . $mailInfo['receiverName'] . ' is not available at that time. However, please have a look at these alternative schedules and let me know what works best for you.' . PHP_EOL . PHP_EOL; | |
$slotAns .= 'I am an A.I based assistant, so it would be best if you were to respond with the number besides the slot that works best for you, and I will set up the meeting.' . PHP_EOL . PHP_EOL; | |
$slotAns .= 'Hope you have a pleasant day.' . PHP_EOL . PHP_EOL; | |
return $slotAns; | |
} | |
/** | |
* @param $mailInfo | |
*/ | |
public function clearCache($mailInfo) | |
{ | |
Cache::forget('index_' . $mailInfo['senderMail'] . $mailInfo['threadId']); | |
Cache::forget('requiredEntity_' . $mailInfo['senderMail'] . $mailInfo['threadId']); | |
Cache::forget('intent_' . $mailInfo['senderMail'] . $mailInfo['threadId']); | |
Cache::forget('action_' . $mailInfo['senderMail'] . $mailInfo['threadId']); | |
} | |
/** | |
* @param $intentFlow | |
* @param $mailInfo | |
* @param $intent | |
* @return string | |
*/ | |
public function resultFromRequiredEntity($intentFlow, $mailInfo, $intent) | |
{ | |
$requiredEntities = json_decode($intentFlow->required_entity); | |
$action = json_decode($intentFlow->action); | |
Cache::put('index_' . $mailInfo['senderMail'] . $mailInfo['threadId'], 0, '60'); | |
Cache::put('requiredEntity_' . $mailInfo['senderMail'] . $mailInfo['threadId'], $requiredEntities, '60'); | |
Cache::put('action_' . $mailInfo['senderMail'] . $mailInfo['threadId'], $action, 20); | |
Cache::put('intent_' . $mailInfo['senderMail'] . $mailInfo['threadId'], $intent, 20); | |
$this->answer .= 'Pls answer accordingly to set a meet up. For example "1. Start Time" ' . PHP_EOL . PHP_EOL; | |
foreach ($requiredEntities as $key => $requiredEntity) { | |
$this->answer .= ($key + 1) . '. ' . $requiredEntity->text . PHP_EOL; | |
} | |
return $this->answer; | |
} | |
/** | |
* @param $question | |
* @return mixed | |
*/ | |
public function resultFromFlow($question) | |
{ | |
$answerObject = json_decode($question->answers); | |
foreach ($answerObject as $key => $answer) { | |
$val = json_decode($answer->value); | |
if ($answer->type == 'text') { | |
$this->answer ['text'][$key] = $val->text; | |
} else { | |
$this->answer ['url'][$key] = $val->attachment->payload->url; | |
} | |
} | |
return $this->answer; | |
} | |
/** | |
* @param $mailInfo | |
* @param $gmailBot | |
* @return string | |
* @throws GuzzleException | |
*/ | |
public function resultFromNlu($mailInfo, $gmailBot) | |
{ | |
try { | |
$confusedQuestions = new ConfusedQuestions(); | |
$sortedResponse = $confusedQuestions->getResponseList(trim($mailInfo['mailBody']), trim($gmailBot['bot_key'])); | |
if (count($sortedResponse) > 0 && $sortedResponse[0]['confidence'] > 0) { | |
$answerObject = $sortedResponse[0]['answers']; | |
foreach ($answerObject as $key => $answer) { | |
$val = json_decode($answer['value']); | |
if ($answer['type'] == 'text') { | |
$this->answer ['text'][$key] = $val->text; | |
} else { | |
$this->answer ['url'][$key] = $val->attachment->payload->url; | |
} | |
} | |
return $this->answer; | |
} else { | |
$this->answer = null; | |
return $this->answer; | |
} | |
} catch (\Exception $e) { | |
Log::info($e); | |
} | |
} | |
/** | |
* mail body construction | |
* @param $mailToBeSent | |
* @param $mailInfo | |
* @return string | |
*/ | |
public function rfcMailFormat($mailToBeSent, $mailInfo) | |
{ | |
$textAns = null; | |
if (gettype($mailToBeSent) == 'array') { | |
if (isset($mailToBeSent['text'])) { | |
foreach ($mailToBeSent['text'] as $textMail) { | |
$textAns .= $textMail . PHP_EOL; | |
} | |
} | |
} | |
$Body = 'Hello ' . $mailInfo['senderName'] . ',' . PHP_EOL . PHP_EOL; | |
$Body .= gettype($mailToBeSent) == 'string' ? $mailToBeSent : $textAns; | |
$Body .= PHP_EOL . "Thank you"; | |
$mailFormat = 'Content-Type: multipart/mixed; boundary = "separate"' . PHP_EOL; | |
//mail format | |
$mailFormat .= 'From: ' . $mailInfo['receiverNameMail'] . PHP_EOL; | |
$mailFormat .= 'To: ' . $mailInfo['senderMail'] . PHP_EOL; | |
//reference contains previous 1/2/multiple msg ids before the current msg im sending now | |
$mailFormat .= 'References: ' . $mailInfo['messageId'] . PHP_EOL; | |
// in-reply-to contains the message id im replying too | |
$mailFormat .= 'In-Reply-To: ' . $mailInfo['messageId'] . PHP_EOL; | |
$mailFormat .= 'Subject: ' . trim($mailInfo['subject']) . PHP_EOL; | |
$mailFormat .= 'Date: ' . $mailInfo['receivedAt'] . PHP_EOL; | |
$mailFormat .= 'Message-ID: ' . PHP_EOL; | |
$mailFormat .= '--separate' . PHP_EOL; | |
//-----------------text data---------------- | |
$mailFormat .= 'Content-Type: text/plain; charset = utf-8' . PHP_EOL; | |
$mailFormat .= 'Content-Transfer-Encoding: quoted-printable' . PHP_EOL; | |
$mailFormat .= $Body . PHP_EOL; | |
$mailFormat .= '--separate' . PHP_EOL; | |
//------------------attachment-------------- | |
if (gettype($mailToBeSent) == 'array') { | |
if (isset($mailToBeSent['url'])) { | |
foreach ($mailToBeSent['url'] as $urlMail) { | |
$path_info = pathinfo($urlMail); | |
$extention = $path_info['extension']; | |
$fileName = $path_info['filename']; | |
$mailFormat .= 'Content-Type: message/rfc822' . PHP_EOL; | |
$mailFormat .= 'Content-Transfer-Encoding: base64' . PHP_EOL; | |
$mailFormat .= 'Content-Disposition: attachment; filename="' . $fileName . '.' . $extention . '"' . PHP_EOL; | |
$mailFormat .= chunk_split(base64_encode(file_get_contents($urlMail)), 76, "\n") . PHP_EOL; | |
$mailFormat .= '--separate' . PHP_EOL; | |
} | |
} | |
} | |
//---------------end of attachment------------- | |
$mailFormat .= '--separate--' . PHP_EOL; | |
return $mailFormat; | |
} | |
/** | |
* Watch property needs to be activated in every 7 days [corn] | |
* @throws GuzzleException | |
*/ | |
public function activateWatchPropertyForAllGmailBot() | |
{ | |
$allBotInfos = GmailBot::get(); | |
if ($allBotInfos) { | |
foreach ($allBotInfos as $allBotInfo) { | |
//Checking if the user access_token expires or not | |
if (!Cache::has('accessToken_' . $allBotInfo->mail_address)) { | |
$this->tokenInfo = $this->client->fetchAccessTokenWithRefreshToken($allBotInfo->refresh_token); | |
Cache::put('accessToken_' . $allBotInfo->mail_address, $this->tokenInfo['access_token'], now()->addSeconds($this->tokenInfo['expires_in'])); | |
} | |
$header = [ | |
'Content-type' => 'application/json', | |
'Authorization' => 'Bearer ' . Cache::get('accessToken_' . $allBotInfo->mail_address) | |
]; | |
$data = [ | |
"topicName" => "projects/cl-gmail/topics/cl-mail-pusher", | |
"labelIds" => ["INBOX"] | |
]; | |
$watchUrl = "https://www.googleapis.com/gmail/v1/users/" . $allBotInfo->mail_address . "/watch"; | |
RequestHandlerController::sendRequest($watchUrl, 'post', $header, $data); | |
} | |
} | |
} | |
/** | |
* @param $mailInfo | |
* @throws \Exception | |
*/ | |
public function createAudienceForGmailBot($mailInfo) | |
{ | |
try { | |
// Checking if the audience exists in db | |
$psId = trim($mailInfo['senderMail']) . '_' . trim($mailInfo['receiverMail']); | |
$audience = Audiences::wherePageId(trim($mailInfo['receiverMail']))->wherePsid($psId)->first(); | |
if ($audience == null) { | |
//If not create a new audience | |
$audienceDetails = [ | |
"uid" => Uuid::generate()->string, | |
"page_id" => $mailInfo['receiverMail'], | |
"name" => $mailInfo['senderName'], | |
"psid" => $psId, | |
"first_name" => '', | |
"last_name" => '', | |
"profile_pic" => '', | |
"locale" => '', | |
"timezone" => $mailInfo['timeZone'], | |
"gender" => '', | |
"device" => null, | |
"device_os" => null | |
]; | |
$status = Audiences::create($audienceDetails); | |
} | |
} catch (\Exception $e) { | |
Log::info($e); | |
} | |
} | |
/** | |
* @param $mailAddress | |
* @return JsonResponse | |
* @throws GuzzleException | |
*/ | |
public function delete($mailAddress) | |
{ | |
$this->client->revokeToken(); | |
$botInfo = GmailBot::whereMailAddress($mailAddress)->first(); | |
if (!Cache::has('accessToken_' . $botInfo['mail_address'])) { | |
$this->tokenInfo = $this->client->fetchAccessTokenWithRefreshToken($botInfo->refresh_token); | |
Cache::put('accessToken_' . $botInfo['mail_address'], $this->tokenInfo['access_token'], now()->addSeconds($this->tokenInfo['expires_in'])); | |
} | |
$header = [ | |
'Content-type' => 'application/json', | |
'Authorization' => 'Bearer ' . Cache::get('accessToken_' . $botInfo['mail_address']) | |
]; | |
//revoking application access | |
$revokeUrl = "https://accounts.google.com/o/oauth2/revoke?token=" . $botInfo['refresh_token']; | |
RequestHandlerController::sendRequest($revokeUrl, 'get', $header); | |
$botInfo->delete(); | |
return response()->json('Deleted',200); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment