GMail API - Getting certain message headers or fields - php

I have successfully connected GMail API via G Suite account and service account. I can get a message list and I can retrieve messages by IDs. I'm working with PHP.
What I'm having problems with is to get for example the FROM or TO headers, SUBJECT or the snippet field.
$optParam = array('format' => 'metadata', 'metadataHeaders'=>['subject','from'], 'fields'=>['snippet','labelIds']);
$fullMessage = $service->users_messages->get($user, $id, $optParam);
This will return the snippet, but not the subject or from or the labelIds.
If I use the GMail "Try this API" and use the id of the message and use "snippet" in the "fields" entry, I just get the snippet back as:
{
"snippet": "Short snippet of the message"
}
If I use:
$optParam = array('format' => 'metadata', 'metadataHeaders'=>['subject','from','to']);
I do get the 3 headers, but I also get a lot more information, including the labels and snippet - about 3K for each message.
I just can't seem to be able to specify a small subset of the data. All I need is to show messages as a list with the subject, date/time, from/to.
I don't care so much about the amount of data, but it takes on average about 3.5 seconds to retrieve the data for just 14 message!
Is there a way to restrict this so I don't get all the "extra" data or speed the retrieval up somehow?

Sending the request would involve specifying the metadata keys as well as the parameter names of the fields you want to obtain. You can use an HTTP GET request with the URI to get the ‘to’, ‘from’, ‘subject’ and ‘snippet’ with https://www.googleapis.com/gmail/v1/users/me/messages/<MESSAGE_ID>?format=metadata&metadataHeaders=to&metadataHeaders=from&metadataHeaders=subject&fields=snippet%2C+payload%2Fheaders, which will also limit the headers you obtain.
In PHP you can use this:
$optParam = array('format' => 'metadata', 'metadataHeaders'=>['subject', 'from', 'to'], 'fields'=>'payload/headers,snippet');
Note that the fields parameter needs to be sent as a string and not an array.
Also be aware there is a known issue with the Gmail API where using the https://www.googleapis.com/auth/gmail.metadata scope will not return the snippet.
You’ll need to use https://www.googleapis.com/auth/gmail.readonly instead.
You can also make a batch of requests in one network call which will help speed up overall execution time as documented here.

Related

Docusign rate limit to receive documents in 1 envelope

I am trying to switch to the production API of Docusign. When I submit the required 20 envelopes for approval they do not get approved. I recieved a log file that lists multiple GET requests. It violates the API rules, only one GET request per envelope per 15 minutes is allowed according to the documentation. (https://developers.docusign.com/esign-rest-api/guides/resource-limits)
When I list my envelope and loop through the envelope multiple times to get the documents out of it. I do multiple GET requests to the same envelope and that's why I think I get a rate limit error.
In the example below, you can see that when I retrieve the envelope, I immediately loop over the documents inside the envelope and get the documents with the getDucument method as described in the documentation. (https://developers.docusign.com/esign-rest-api/code-examples/get-an-envelope-document-list)
public function getEnvelopeDocument ($envelopeId)
{
$documents = $this->envelopeApi->listDocuments(config('docusign.id'), $envelopeId);
try {
foreach($documents->getEnvelopeDocuments() as $document)
{
$docs[] = $this->envelopeApi->getDocument((config('docusign.id')), $document->getDocumentId(), $envelopeId);
}
} catch (ApiException $e){
dd("Error connecting Docusign : " . $e->getResponseBody()->errorCode . " " . $e->getResponseBody()->message);
}
}
Am I violating the API rate limiter? If so, what would be the allowed way to retrieve documents inside an envelope.
My interpretation of the code is that you are performing the following calls in sequence:
GET /envelopes/{envelopeId}/documents - ListDocuments
GET /envelopes/{envelopeId}/documents/1 - get document 1
GET /envelopes/{envelopeId}/documents/2 - get document 2
and so on.
If this is the case, you are not in violation of the API limit. If you were to make two calls to the ListDocuments or to one of the individual documents within 15 minutes that would be a polling violation.
To confirm everything is acceptable, you might capture API logs to confirm you're hitting each unique endpoint only once. Info on API logs is available here: https://support.docusign.com/guides/ndse-user-guide-api-request-logging

When using twilio's php notify API, how do you set your callback URL?

I have the following code and it sends SMS notifications to my phone:
$notification = $twilio->notify->services($serviceSid)
->notifications->create([
'toBinding' => $batch,
'body' => $txt,
'statusCallback' => 'http://postb.in/b/jarblegarble' // <-- this doesn't work
]);
However, even though the sending works, I can't seem to figure out their callbacks.
I'm scouring through their docs and I can't find how to set the callback URL. I see some of their resources use "url" while others use "statusCallback" (heck, one seems to use "redirect"). That being said, I can't seem to post to postb.in using them -- there must be a way to check the status of my notification.
So it turns out I was wrong on two fronts.
1) The callback URL needs to be passed to your messaging service this way:
$notification = $twilio->notify->services($serviceSid)
->notifications->create([
'toBinding' => $bindings,
'body' => $txt,
'sms' => ['status_callback' => 'http://your_callback_url' ]
]);
2) postb.in wasn't working! I was testing the code above, after being assured by twilio support that it was valid, I decided to try and post to my own server and just capture the POSTed content. Sure enough, it was working as they suggested.
Edit: It wasn't clear to me at the time but the callback URL will be called for each SMS sent out for each status update. So that means queued, sent, and delivered. I initially thought that I'd just get a status update for the batch itself as I don't necessarily care for the status of up to 10,000 txt messages.
Your example passes the statusCallback parameter of the individual SMS service API to the universal notify API. This mixing won't work. The individual SMS service sets up a callback for that one particular message, which isn't efficient for batch sends. The universal notify API, in contrast, relies on web hooks, which are globally configured per service.
The simplest thing to do, in your case, is to use the individual SMS service API:
$message = $twilio->messages->create('+15551234567', [ 'body' => 'Hi',
'from' => '+15559876543',
'statusCallback' => 'http://postb.in/b/jarblegarble' ]);
To use the universal notify API, you'll need to set the PostWebhookUrl to the target URL when creating the notification service, and arrange for the code at that URL to handle onMessageSent messages. More at the "web hooks" URL above.
Caveat emptor: haven't tried any of this, and I haven't used Twilio in literally eight years, but the above is my theoretical understanding.

Push notification overrides previous notifications

I'm using codeigniter-gcm library on top of codeigniter to send messages to Google Cloud Messaging service. It sends the message and the message is received at the mobile device, but if I send multiple messages, only the latest message appears on the device (as if it is overriding the previous messages).
I'm seeing that I might need to create a unique notification ID, but I'm not seeing how it's done anywhere on the codeigniter-gcm documentation or Google's documentation for downstream messages.
Any idea how this should be done?
Here's my code in the codeigniter controller. It is worth mentioning that Google's response contains a different message_id for each time I send a push...
public function index() {
$this->load->library("gcm");
$this->gcm->setMessage("Test message sent on " . date("d.m.Y H:i:s"));
$this->gcm->addRecepient("*****************");
$this->gcm->setData(array(
'title' => 'my title',
'some_key' => 'some_val'
));
$this->gcm->setTtl(false);
$this->gcm->setGroup(false);
if ($this->gcm->send())
echo 'Success for all messages';
else
echo 'Some messages have errors';
print_r($this->gcm->status);
print_r($this->gcm->messagesStatuses);
}
After three exhausting days I found the solution. I'm posting it here in hope of saving someone else's time...
I had to add a parameter to the data object inside the greater JSON object, named "notId" with a unique integer value (which I chose to use a random integer from a wide range). Now why Google didn't include this in their docs? Beats me...
Here's how my JSON looks now, when it creates separate notifications instead of overriding:
{
"data": {
"some_key":"some_val",
"title":"test title",
"message":"Test message from 30.09.2015 12:57:44",
"notId":14243
},
"registration_ids":["*******"]
}
Edit:
I'm now thinking that the notId parameter is not really determined by Google, but by a plugin I use on the mobile app side.
To extend further on my environment, my mobile app is developed using Phonegap, so to get push notification I use phonegap-plugin-push which I now see in its docs that parameter name.
I'm kinda' lost now as far as explaining the situation - but happy it is no longer a problem for me :-)
You need to pass a unique ID to each notification. Once you have clicked on the notification you use that ID to remove it.
...
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotificationManager.cancel(SIMPLE_NOTFICATION_ID_A);
...
But I'm sure you shouldn't have so much of notifications for user at once. You should show a single notification that consolidates info about group of events like for example Gmail client does. Use Notification.Builder for that purpose.
NotificationCompat.Builder b = new NotificationCompat.Builder(c);
b.setNumber(g_push.Counter)
.setLargeIcon(BitmapFactory.decodeResource(c.getResources(), R.drawable.list_avatar))
.setSmallIcon(R.drawable.ic_stat_example)
.setAutoCancel(true)
.setContentTitle(pushCount > 1 ? c.getString(R.string.stat_messages_title) + pushCount : title)
.setContentText(pushCount > 1 ? push.ProfileID : mess)
.setWhen(g_push.Timestamp)
.setContentIntent(PendingIntent.getActivity(c, 0, it, PendingIntent.FLAG_UPDATE_CURRENT))
.setDeleteIntent(PendingIntent.getBroadcast(c, 0, new Intent(ACTION_CLEAR_NOTIFICATION), PendingIntent.FLAG_CANCEL_CURRENT))
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE)
.setSound(Uri.parse(prefs.getString(
SharedPreferencesID.PREFERENCE_ID_PUSH_SOUND_URI,
"android.resource://ru.mail.mailapp/raw/new_message_bells")));

Gmail oauth received on date using PHP

How do I go about getting a count of emails received on a particular date across all gmail folders. Managed to get email inbox counting working ok but now need to figure out how to get number received for previous day using PHP and oauth. Can anyone help?
The messages#list method allows you to pass a q parameter which accepts the same query format from the Gmail search field.
Thus it's possible to do this:
// $gmail is an instance of Google_Service_Gmail
$messages = $gmail->users_messages->listUsersMessages('me', array(
'q' => "after:2014/10/20 before:2014/10/21"
));
// $count is the number of messages from 2014/10/20
$count = $messages->getResultSizeEstimate();
Beware that the result will be different from what you see in Gmail if you have the 'Conversation view' turned on.

SendGrid Web API bounced email header response

I am sending emails via SendGrid with this inside the x-smtpapi header
$json_string = array(
'unique_args' => array (
'email_id' => 1
)
);
It all seems to send okay, inside SendGrid I can view the "email_id" in the Email activity under Unique Args.
However when I try to use the API to look at this email, I cannot find a way to actually get these unique arguments from the API.
I am using this to try and get the headers returned with the bounced emails.
$request = 'https://api.sendgrid.com/api/bounces.get.json&api_user=username&api_key=password'
All I get is just the email addresses that have bounced, not the header information (the unique arguments)
I want to know, is it possible to get the unique arguments from the API. I have read it multiple times to no avail.
I hope this makes sense.
Thanks
At present there's no way request to lookup specific events by unique_arg with the Web API.
However, the SendGrid Event Webhook will give you granular data on each event, such as a bounce as it happens. The Event Webhook POSTs data to your server every time an action is taken upon an email (e.g. open, click, bounce).
Once you receive it, you're responsible for storing this, although it's not a typical API it gives very specific data on events which you can then compile and rehash however you like.
To get started using the webhook, you'll do something like the following, and have SendGrid POST to the following script:
<?php
$data = file_get_contents("php://input");
$events = json_decode($data, true);
foreach ($events as $event) {
// Here, you now have each event and can process them how you like
process_event($event);
}
[Taken from the SendGrid Webhook Code Example]

Categories