The Why?
I'm playing around with the GMAIL api, for a minor project at work
The Wanted Result
What I'm trying to get from the Gmail API, is all message threads modfied after a certain timestamp/date.
What do i have so far
So far i manage to get all threads created after a certain date - by using the standart gmail search queries see - https://support.google.com/mail/answer/7190.
The Problem
It's great i can get all the Message Threads after a certain date, but the problem is when i have my queried set as:
after:[todays date - 7 days)
This will show me all Message Threads, up to 7 days ago - but what when i have a Message Thread, created 8 days ago and still getting updated?. What is my best option to get all message threads, modified from now to 7 days ago?
Checking all message threads, all the time is not an option :)
The code
$client = getClient();
$oService = new Google_Service_Gmail($client);
$sUser = 'me';
$tsMailsAfter = '1554280000';
$sIn = 'INBOX';
//before;, after:, in:(inbox, sent)
$aThreads = getlistThread($oService, $sUser, 'after:'.$tsMailsAfter.' in:'.$sIn);
function getlistThread($service, $userId, $aQuery = '')
{
$threads = array();
$pageToken = NULL;
do
{
try
{
$opt_param = array();
if ($pageToken)
{
$opt_param['pageToken'] = $pageToken;
}
$opt_param['q'] = $aQuery;
$threadsResponse = $service->users_threads->listUsersThreads($userId, $opt_param);
if($threadsResponse->getThreads())
{
$threads = array_merge($threads, $threadsResponse->getThreads());
$pageToken = $threadsResponse->getNextPageToken();
}
}
catch (Exception $e)
{
print 'An error occurred: ' . $e->getMessage();
$pageToken = NULL;
}
}
while ($pageToken);
return $threads;
}
i solved my issue by just using a search query (with :after) on ->listUsersMessages() and then collecting the ID's in an array(). Its not the most optimal solution, having a search query :modified_after would be the best solution - this solution defiantly works for my purpose:)
function listThreadsToUpdate($service, $userId, $sQuery = '')
{
$pageToken = NULL;
$messages = array();
$opt_param = array();
do
{
try
{
if ($pageToken)
{
$opt_param['pageToken'] = $pageToken;
}
$opt_param['q'] = $sQuery;
$messagesResponse = $service->users_messages->listUsersMessages($userId, $opt_param);
if ($messagesResponse->getMessages())
{
$aMessages = array_merge($messages, $messagesResponse->getMessages());
$pageToken = $messagesResponse->getNextPageToken();
}
}
catch (Exception $e)
{
print 'An error occurred: ' . $e->getMessage();
}
} while ($pageToken);
$aThreadsToUpdate = array();
if(isset($aMessages) && !empty($aMessages))
{
foreach ($aMessages as $oMessage)
{
$aThreadsToUpdate[] = $oMessage->getThreadId();
}
}
return array_unique($aThreadsToUpdate);
}
Related
There are 3 queues in redis.
If I insert a data at a same time with different browsers, both requests are accepted.
I get 2 duplicated records. Any helps?
For example, the first request is on the 1st queue.
At the second request, 2nd queue is searched for finding the data.
But the data doesn't exist in the queue.
The second request is inserted on the queue.
Is it understandable?
public function save($evt_no, $type = "redis") {
$name = '';
$res = true;
try{
$headers = getallheaders();
$bodys = $_REQUEST;
$session = $_SESSION;
foreach ($_FILES as $fileKey=>$fileVal) {
if ($fileVal['error'] == 0) {
try {
$uploaded_row = $this->fileL->upload('queueEventParticipant', $fileKey, array() ,'queue');
} catch (\Exception $ex) {
throw $ex;
}
$bodys['file'][_return_numeric($fileKey)] = $uploaded_row;
}
}
$data = array(
'header' => $headers,
'body' => $bodys,
'session' => $session
);
$data['body']['evt_no'] = $evt_no;
$data = json_encode($data);
if($type == "redis"){
$name = $this->attendQueueRedisService->setNewRsvp($data);
} else {
throw new \Exception("No exist");
}
} catch (\Exception $ex){
log_message("error", $ex->getMessage());
throw $ex;
}
if($res){
return $name;
} else {
return "Error";
}
}
class AttendQueueRedisService extends CI_Model {
private $redisClient;
private $redisConfig;
const PREFIX_DONE = 'done_';
const PREFIX_ERROR = 'error_';
public function __construct() {
parent::__construct();
if ($this->load->config('redis', true, true)) {
$this->redisConfig = $this->config->config['redis'];
}
$this->redisClient = new Redis();
$this->redisClient->connect($this->redisConfig['hostname'], $this->redisConfig['port']);
$this->redisClient->auth($this->redisConfig['auth']);
$this->redisClient->select($this->redisConfig['queue']);
}
public function setNewRsvp($data) {
$key = uniqid('rsvp_'.gethostname().'_',true).':redis';
$this->redisClient->set($key, $data, 60 * 30);
return $key;
}
}
I am trying to get only last 100 threads from Gmail. I am using this function to gather threads but I don't know why It always fetches all threads and not only last 100. Also, I want to fetch them only from the inbox. Maybe there is a small mistake but I can't see what is wrong. Hope someone sees what is wrong.
function listThreads($service, $userId) {
$threads = array();
$pageToken = NULL;
do {
try {
$opt_param = array(
'maxResults' => 100,
'labelIds' => 'INBOX'
);
if ($pageToken) {
$opt_param['pageToken'] = $pageToken;
}
$threadsResponse = $service->users_threads->listUsersThreads($userId, $opt_param);
if ($threadsResponse->getThreads()) {
$threads = array_merge($threads, $threadsResponse->getThreads());
$pageToken = $threadsResponse->getNextPageToken();
}
} catch (Exception $e) {
print 'An error occurred: ' . $e->getMessage();
$pageToken = NULL;
}
} while ($pageToken);
foreach ($threads as $thread) {
print 'Thread with ID: ' . $thread->getId() . '<br/>';
}
return $threads;
}
I found a solution. If you set maxResults=>100 It will gather 100 threads from one token and then go ahead to gather another token to grab next 100. So the only thing I had to do was to break out once threads were fetched. Hope this helps someone.
Working code:
function listThreads($service, $userId) {
$threads = array();
$pageToken = NULL;
$opt_param = array(
'maxResults' => 100,
'labelIds' => 'INBOX'
);
do {
try {
if ($pageToken) {
$opt_param['pageToken'] = $pageToken;
}
$threadsResponse = $service->users_threads->listUsersThreads($userId, $opt_param);
if ($threadsResponse->getThreads()) {
$threads = array_merge($threads, $threadsResponse->getThreads());
//$pageToken = $threadsResponse->getNextPageToken();
break;
}
} catch (Exception $e) {
print 'An error occurred: ' . $e->getMessage();
$pageToken = NULL;
$x++;
}
} while ($pageToken);
foreach ($threads as $thread) {
print 'Thread with ID: ' . $thread->getId() . '<br/>';
}
return $threads;
}
I am working on getting the Gmail List API setup, but for some reason, it returns all 5,000 messages in my inbox even though I have set maxResults to 100. Here is my current code:
$pageToken = NULL;
$messages = array();
$opt_param = array();
do {
try {
if ($pageToken) {
$opt_param['pageToken'] = $pageToken;
$opt_param['maxResults'] = 100;
$opt_param['labelIds'] = 'INBOX';
}
$messagesResponse = $service->users_messages->listUsersMessages($userId, $opt_param);
if ($messagesResponse->getMessages()) {
$messages = array_merge($messages, $messagesResponse->getMessages());
$pageToken = $messagesResponse->getNextPageToken();
}
} catch (Exception $e) {
print 'An error occurred: ' . $e->getMessage();
}
} while ($pageToken);
foreach ($messages as $message) {
print 'Message with ID: ' . $message->getId() . '<br/>';
}
return $messages;
I'm not sure where I am going wrong, but I need to be able to filter down my inbox to the last 100 messages sent.
So I just realized, you are getting all messages because even though you are getting them by slices of 100, you are, in the end, doing that in a loop until you get all messages in your inbox...
If you only want the first 100, try this instead:
$messages = array();
try {
$opt_param = array(
'maxResults' => 100,
'labelIds' => 'INBOX'
);
$messagesResponse = $service->users_messages->listUsersMessages($userId, $opt_param);
$messages = $messagesResponse->getMessages();
} catch (Exception $e) {
print 'An error occurred: ' . $e->getMessage();
}
if(!empty($messages)) {
foreach ($messages as $message) {
print 'Message with ID: ' . $message->getId() . '<br/>';
}
}
return $messages;
So I removed the do/while loop, basically...
Hope this helps!
I'm using the following code to process a payment with MercadoPago and credit card:
$mp = new MP($access_token);
$payment = array();
$payment["transaction_amount"] = 100.00;
$payment["token"] = $token;
$result = $mp->post("/v1/payments", $payment);
echo "<pre>";
print_r($result);
echo "</pre>";
I already have the credit card token, but still I get this error:
Fatal error: Uncaught exception 'Exception' with message 'Params Error - 1: Params Error'
Any help will be appreciated.
Thanks.
This is a very old post, but it can help someone ....
Try to catch the exception so you can handle it and debug it more easily.
I´ve been able to catch it adding:
// import
use \MP;
use \MercadoPagoException;
// try payment
try {
$payment = $this->mp->post("/v1/payments", $this->paymentData);
}
catch (MercadoPagoException $e) {
$paymentError = new \stdClass();
$paymentError->parsed = $this->parseException($e->getMessage());
$paymentError->data = $e->getMessage();
$paymentError->code = $e->getCode();
}
// parse the excepetion "message" to get the code and detail, if exists
private function parseException($message) {
$error = new \stdClass();
$error->code = 0;
$error->detail = '';
$posA = strpos($message, '-');
$posB = strpos($message, ':');
if($posA && $posB) {
$posA+=2;
$length = $posB - $posA;
// get code
$error->code = substr($message, $posA, $length);
// get message
$error->detail = substr($message, $posB+2);
}
return $error;
}
I'm doing a little page that lists all files that are in google drive. In the first time I do the authentication and save the refresh token + user id and email and then I list all the files. To get the information I do this:
$result = array();
$pageToken = NULL;
do {
try {
$parameters = array();
if ($pageToken) {
$parameters['pageToken'] = $pageToken;
}
$files = $service->files->listFiles($parameters);
$list=$files->getItems();
$result = array_merge($result,$list);
$pageToken = $files->getNextPageToken();
} catch (Exception $e) {
echo "An error occurred: " . $e->getMessage();
$pageToken = NULL;
}
} while ($pageToken);
And it works, but if the user refresh the page, I have do refresh the access token (getting the refresh token from db) and then proceed to do the same as above. In this case that code gives me an error because this time I get an associative array when I do:
$files = $service->files->listFiles($parameters);
To make it work I need to change the code to:
$result = array();
$pageToken = NULL;
do {
try {
$parameters = array();
if ($pageToken) {
$parameters['pageToken'] = $pageToken;
}
$files = $service->files->listFiles($parameters);
$list=$files['items'];
$result = array_merge($result,$list);
$pageToken = $files['nextPageToken'];
} catch (Exception $e) {
echo "An error occurred: " . $e->getMessage();
$pageToken = NULL;
}
} while ($pageToken);
This shouldn't happen but I have no idea what's wrong.
From the relevant php source of the class, I guess I found what makes you trouble.
Look at Google_DriveService.php:
// ~Line 119
public function listFiles($optParams = array()) {
$params = array();
$params = array_merge($params, $optParams);
$data = $this->__call('list', array($params));
if ($this->useObjects()) { // THIS CALL HERE
return new Google_FileList($data);
} else {
return $data;
}
}
It checks if you want to work with objects, or not: $this->useObjects().
This method is defined in the super class, Google_ServiceResource.php:
// ~Line 180
public function useObjects() {
global $apiConfig;
return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']);
}
This tells me, that when you configure your service, you will have to set 'use_object' to true.