Gmail API - How do I see a email opening date? - google-api

I need to use the Google API in order to retrieve the first time an email was marked as view (Specifically, when an email was opened).
I'm using GET https://gmail.googleapis.com/gmail/v1/users/{userId}/messages/{id} requesting only the metadata to get the messages but the response looks like this:
{
"id": "17a05bd8db1609b9",
"threadId": "17a05bd8db1609b9",
"labelIds": [
"CATEGORY_PROMOTIONS",
"UNREAD",
"INBOX"
],
"payload": {
"partId": "",
"headers": [
{
"name": "Delivered-To",
"value": "{EMAIL ADDRESS}"
},
{
"name": "Received",
"value": "by 2002:a55:c51e:0:b029:e9:12c1:65a9 with SMTP id b30csp1876084egk; Sun, 13 Jun 2021 07:19:06 -0700 (PDT)"
},
{
"name": "X-Google-Smtp-Source",
"value": "ABdhPJzPcWJR1zsvAH654luf+agnL6i6CGj8S/jO1MDZVz3yPHcqE7y37chZ7euL02n40t6idUB/"
},
{
"name": "X-Received",
"value": "by 2002:a9d:62ce:: with SMTP id z14mr10328566otk.255.1623593946243; Sun, 13 Jun 2021 07:19:06 -0700 (PDT)"
},
{
"name": "ARC-Seal",
"value": "i=1; a=rsa-sha256; t=1623593946; cv=none; d=google.com; s=arc-20160816; b=L8L+Vz979TjsIDtXAyhnPBQUmW8Njjz+DiyScOHFvyHbmOC9sIyaH5AFOafzFou45N nTtpzyq9pSlZ8VWd6N9N+NYcdldf67A7/FarG9iIs6EvddVYcpbEqdTPOyMt6/mluVQO utRoX3ma1TFAIyXoQLvxfPZ5QZLZNQFpPwYWGIkB+/8r45OKkqhuWtX8d93InKgpoVIf NQjaI4Tnr2AJWWJjiALL8bLoCe1QvA3mV+I1sTbGRPZAIPcKfm+nB3smYgkH7f9C+1+8 iXR/45AWh+9Sxd1IFrHHokfTEOQvHEWDXm8BBagCFaRFJv45V+FIyWGJKKpL4UCI0oab 7ZRg=="
},
{
"name": "ARC-Message-Signature",
"value": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe-post:list-unsubscribe:mime-version:subject :message-id:to:reply-to:from:date:dkim-signature:dkim-signature; bh=3CtcdJdIFbH5c/+55q2hcIqL8foXcatroOK85FVqTxk=; b=0/F/Qn1AmdXlp7t9Or1qvUB+6xmvr2Ewxm33BtMBo956QCvgQQ5qilxt3ZI1Kqx+YB zuQZLKRcG7T1kRqvsq3ERdrAqAr6P8+I6j9yWw6XaI7uuU8crVbnEjbkUAheFjmNeXOP ZcuwtlUPlgDiyOmE6ND2HWLrpUcCKxx/TY17fYkR/H08yr44BqtTXSJVUG12n5Sjb8iA nnFyJHYBRg2Elw7vMnUl+wiO0k1EH9C7ltwTJCjVsDPe0LcvcjtDcr0R4i24sYbNTDgN fyOsKMfJnPAE/oLk6iZhd0NvWVkUUvop6b8kdZtLfVH1jLMIYPBOlNjeSct+yfmtrHWt Vrwg=="
},
{
"name": "ARC-Authentication-Results",
"value": "i=1; mx.google.com; dkim=pass header.i=#emails.waves-audio.com header.s=gears header.b=AAcEguTx; dkim=pass header.i=#d.messagegears.io header.s=gears header.b=jvFNHriZ; spf=pass (google.com: domain of 346064636000c23595702-b21164-83d6be2bdc4542f7a574924245020c5e#emails.waves-audio.com designates 135.84.217.27 as permitted sender) smtp.mailfrom=346064636000c23595702-b21164-83d6be2bdc4542f7a574924245020c5e#emails.waves-audio.com"
},
{
"name": "Return-Path",
"value": "\u003c346064636000c23595702-b21164-83d6be2bdc4542f7a574924245020c5e#emails.waves-audio.com\u003e"
},
{
"name": "Received",
"value": "from mta0201-27.emails.waves-audio.com (mta0201-27.emails.waves-audio.com. [135.84.217.27]) by mx.google.com with ESMTPS id t22si9652818otl.163.2021.06.13.07.19.06 for \u003c{EMAIL ADDRESS}\u003e (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Jun 2021 07:19:06 -0700 (PDT)"
},
{
"name": "Received-SPF",
"value": "pass (google.com: domain of 346064636000c23595702-b21164-83d6be2bdc4542f7a574924245020c5e#emails.waves-audio.com designates 135.84.217.27 as permitted sender) client-ip=135.84.217.27;"
},
{
"name": "Authentication-Results",
"value": "mx.google.com; dkim=pass header.i=#emails.waves-audio.com header.s=gears header.b=AAcEguTx; dkim=pass header.i=#d.messagegears.io header.s=gears header.b=jvFNHriZ; spf=pass (google.com: domain of 346064636000c23595702-b21164-83d6be2bdc4542f7a574924245020c5e#emails.waves-audio.com designates 135.84.217.27 as permitted sender) smtp.mailfrom=346064636000c23595702-b21164-83d6be2bdc4542f7a574924245020c5e#emails.waves-audio.com"
},
{
"name": "DKIM-Signature",
"value": "v=1; a=rsa-sha256; c=relaxed/relaxed; s=gears; d=emails.waves-audio.com; h=Date:From:Reply-To:To:Message-ID:Subject:MIME-Version:Content-Type: List-Unsubscribe:List-Unsubscribe-Post; i=news#emails.waves-audio.com; bh=3CtcdJdIFbH5c/+55q2hcIqL8foXcatroOK85FVqTxk=; b=AAcEguTxQVhKb8tKVqR1lfLjeU7RxkHAe91vfNVg5UdOTOvGfi+oPi4wnn3dR/XUuFYxu47u9Cfo g+jeKSONECg68D/xEtQCnf0MfO71lKSLXDghlYhhaAh5Jjd2IH88b+2hM5fBFN7Fz7lDUp1+Bw/0 U9IH4Ei+w7E8RXs/D6E="
},
{
"name": "DKIM-Signature",
"value": "v=1; a=rsa-sha256; c=relaxed/relaxed; s=gears; d=d.messagegears.io; h=Date:From:Reply-To:To:Message-ID:Subject:MIME-Version:Content-Type: List-Unsubscribe:List-Unsubscribe-Post; bh=3CtcdJdIFbH5c/+55q2hcIqL8foXcatroOK85FVqTxk=; b=jvFNHriZksLExFsp7Br0sf598nLFywhbNS7N+70VY0zeKKLxvm0G4EKNUJ3Fe+3a5oWYWa7HBcJS vq8hAERdI6vQjNNZHYJifHodm4+B04CXCDev9Il3Sx3qB+CYDYymKyeiEycsHWejCdJilo8HN+GE Cxv+AtCFwq2s68gY/r0="
},
{
"name": "Date",
"value": "Sun, 13 Jun 2021 10:04:23 -0400 (EDT)"
},
{
"name": "From",
"value": "Waves Audio \u003cnews#emails.waves-audio.com\u003e"
},
{
"name": "Reply-To",
"value": "Waves Audio \u003cnews#emails.waves-audio.com\u003e"
},
{
"name": "To",
"value": "{EMAIL ADDRESS}"
},
{
"name": "Message-ID",
"value": "\u003c618286522.102678350.1623593063602.JavaMail.cloud#mta0201.messagegears.net\u003e"
},
{
"name": "Subject",
"value": "ENDS TODAY ⏰ ALL Compressors $29.99"
},
{
"name": "MIME-Version",
"value": "1.0"
},
{
"name": "Content-Type",
"value": "multipart/mixed; boundary=\"----=_Part_102678347_1640882403.1623593063602\""
},
{
"name": "X-Original-To",
"value": "{EMAIL ADDRESS}"
},
{
"name": "List-Unsubscribe",
"value": "\u003chttp://track.waves-audio.com/list-unsub/uc/2/1cla%3ANDYwNjQ2MzY%3AMDItYjIxMTY0LTgzZDZiZTJiZGM0NTQyZjdhNTc0OTI0MjQ1MDIwYzVl%3AYXJzZXJlZ0BnbWFpbC5jb20%3AMTY1NjkwNQ%3An%3An%3A_8LcuFe86CJ4F5wm08TiWA\u003e, \u003cmailto:unsub-346064636000c23595702-b21164-83d6be2bdc4542f7a574924245020c5e#emails.waves-audio.com\u003e"
},
{
"name": "List-Unsubscribe-Post",
"value": "List-Unsubscribe=One-Click"
}
]
},
"sizeEstimate": 51137,
"historyId": "6952408",
"internalDate": "1623593063000"
}
And this doesn't show any field like First opened, nor anything similar.
The other approach I was thinking about was checking the history of Labels of the message, if I'm able to retrieve the date at which the UNREAD labelId was added, I would be able to determine the time the email was viewed.

Issue:
In Gmail API, there's no direct way to retrieve the date a certain message was read.
In Gmail itself, there's the option of requesting a read receipt, but this doesn't automatically apply to all emails, and is not available to the API either (consider filing a feature request in Issue Tracker for this).
Using users.history you can track changes to labels (e.g. UNREAD), but the related History resource does not include information on the dates these label changes occurred, so it would not be useful for your situation either (apart from this, history records expire after a short time, typically around one week or a bit more - see Limitations).
Workaround:
Taking all this into account, I think currently the best approach would be to develop a Workspace Gmail add-on. With this, you can add a contextual trigger that fires a function every time a message is opened (as long as the add-on is being used).
The fired function could then be used to store the current date as well as the messageId (for example, using PropertiesService. This way, you could keep track of the dates each message was opened. In this case, the messageId (or the threadId, for that matter), could be retrieved in your function thanks to Gmail event object.
More specifically, you contextual function could be something along the following lines:
function onGmailContextual(e) {
const messageId = e.gmail.messageId;
const userProps = PropertiesService.getUserProperties();
let dateRead;
const messageProp = userProps.getProperty(messageId);
if (messageProp) { // If it exists, the message was read before
dateRead = new Date(JSON.parse(messageProp)); // Retrieve previously store read date
} else { // If it doesn't exist, the message was not read before (at least while the add-on was open)
dateRead = new Date(); // Get current date
userProps.setProperty(messageId, JSON.stringify(dateRead.getTime())); // Store current date as reading date for this message
}
// ...
}
Please note that this will only work for messages opened when the add-on is opened, so you cannot use this to retrieve reading dates for old messages.
Further reading:
Extending Gmail with Google Workspace add-ons
Build contextual message interfaces
Install an unpublished add-on

Related

Timezone shows UTC in Outlook when created by graph api

When creating an calendar event via MS Graph API the event looks different in the OWA and the Outlook Client.
In the Outlook client the event shows up ok in the overview, but when looking at the details it is shown in UTC instead of my timezone (Western Europe) and I cannot click/unclick the timezone button. If I open the same event in OWA it shows up in the correct timezone. Also if I send the event to another organisation it also shows up ok.
This leads me to believe it's something in our outlook client, but then I cannot see any difference in the graph API between events created from Outlook directly (looks ok) and the ones created via a rest call.
This is my payload
{
"subject": "tEST",
"organizer": {
"emailaddress": {
"address": "<email>"
}
},
"start": {
"dateTime": "2019-10-09T08:01:00.0000000",
"timeZone": "UTC"
},
"end": {
"dateTime": "2019-10-09T09:01:00.0000000",
"timeZone": "UTC"
},
"attendees": [
{
"emailAddress": {
"name": "Mattias Johansson",
"address": "<email>"
},
"type": "optional"
}
],
"reminderminutesbeforestart": 15
}
and this is a screenshot of the booking, the time is slightly different since it's another booking than the payload.

Problem with the interpretation of "Now" as #Sys.Time in Dialogflow

Currently i am creating a chatbot for skype using Dialogflow the main problem is when i use the command "Now" in a skype message it uses my current time +1 hour, but when i ask for the time "Now" from the IOS Application it use the current correct TimeZone, someone knows from "where" exactly dialogflow takes the current time zone for the word "Now" because from my app-IOS because from the IOS_Application it gets one value (Correct timezone value) and from skype it gets a another(timezone + 1 hour value)
Raw Interaction Log(Dialogflow - Skype):
{
"queryText": "what time is now?",
"parameters": {
"time": "StiDate [Thu Oct 18 12:38:16 CDT 2018]"
},
"fulfillmentText": "the time is 12:38:16",
"fulfillmentMessages": [
{
"text": {
"text": [
"[{\"type\":0,\"speech\":\"the time is 12:38:16\"}]"
]
}
}
],
"intent": {
"id": "37524c80-a15a-4c04-aa9b-38986ff38993",
"displayName": "A_Test_EventTime"
},
"languageCode": "en",
"sentimentAnalysisResult": {},
"id": "93ce9408-4b73-4f18-9ae0-b947a906afc8",
"sessionId": "6b69769b-1ce7-4359-9018-c88d017485bf",
"timestamp": "2018-10-18T17:38:16.164Z",
"source": "agent"
}
Raw Interaction Log(Dialogflow - AppIOS):
{
"queryText": "What time is now?",
"parameters": {
"time": "StiDate [Thu Oct 18 11:38:00 CST 2018]"
},
"fulfillmentText": "the time is 11:38:00",
"fulfillmentMessages": [
{
"text": {
"text": [
"[{\"type\":0,\"speech\":\"the time is 11:38:00\"}]"
]
}
}
],
"outputContexts": [
{
"name": "fa75fc39-7c68-47ac-bea5-12394f425855",
"lifespanCount": 4,
"parameters": {
"time.original": "now?",
"time": "StiDate [Thu Oct 18 11:38:00 CST 2018]"
}
}
],
"intent": {
"id": "37524c80-a15a-4c04-aa9b-38986ff38993",
"displayName": "A_Test_EventTime"
},
"languageCode": "en",
"sentimentAnalysisResult": {},
"id": "58ade82b-c842-44b6-b0a2-d6cced4d6648",
"sessionId": "dfe0efda53d11aa3d8d43e92a726f9e4",
"timestamp": "2018-10-18T17:38:00.695Z",
"source": "agent"
}
Dialogflow agents have a default time zone. You can change this time zone in your Dialogflow's agents settings in the console: https://dialogflow.com/docs/agents/create-manage#general

Multiple labels for some emails

When we trash a mail after sending it, the UI displays it with only the "Trash" label. However, the API shows both "Sent" and "Trash"
{
"id": "16169c0c3d212e74",
"threadId": "16169c0c3d212e74",
"labelIds": [
"TRASH",
"SENT"
],
"snippet": "#Testing ",
"historyId": "1893418",
"internalDate": "1517897696000",
"payload": {
"partId": "",
"mimeType": "multipart/alternative",
"filename": "",
"headers": [
{
"name": "MIME-Version",
"value": "1.0"
},
{
"name": "Received",
"value": "by xx.xx.xx.xx with HTTP; Mon, 5 Feb 2018 22:14:56 -0800 (PST)"
},
{
"name": "Date",
"value": "Tue, 6 Feb 2018 11:44:56 +0530"
},
{
"name": "Delivered-To",
"value": "xxx#xxx"
},
{
"name": "Message-ID",
"value": "xxx"
},
{
"name": "Subject",
"value": "TEST2"
},
{
"name": "From",
"value": "xxx"
},
{
"name": "To",
"value": "xxxx"
},
{
"name": "Content-Type",
"value": "multipart/alternative; boundary=\"f403045c3c98fab46e05648518a7\""
}
],
"body": {
"size": 0
},
"parts": [
{
"partId": "0",
"mimeType": "text/plain",
"filename": "",
"headers": [
{
"name": "Content-Type",
"value": "text/plain; charset=\"UTF-8\""
}
],
"body": {
"size": 423,
"data": "----"
}
}
]
},
"sizeEstimate": 1810
}
Some mails also have labels like [SENT, INBOX]. Is there any way to get the latest or most relevant label. I would like to categorize mails based on the labels and multiple labels create contradictions.
After you send an email it gets the SENT label. When you are trashing the email you are adding the TRASHED label. It does not remove any other labels that had been added.
I would suspect that the UI version of Gmail has a filter that does not display trashed mails in the sent mail box.
Solution: When you trash your email make sure to delete the SENT label or just filter out all other labels in your application if it has a trashed label.
The gmail api returns the data it has its up to you to either ensure that it has only the correct data by deleting other labels after you trash an email or filtering out the labels you are not interested in.

Can't get almost all information from event from service Hook

I am trying to use the Trello service hook with Team Foundation Server. I have followed this tutorial and the connection worked without problems but, I can't get the informations I need from the Event JSON:
The Description I Tried
This is the Event JSON:
{
"id": "03c164c2-8912-4d5e-8009-3707d5f83734",
"eventType": "git.push",
"publisherId": "tfs",
"scope": 0,
"message": {
"text": "Jamal Hartnett pushed updates to Fabrikam-Fiber-Git:master.",
"html": "Jamal Hartnett pushed updates to Fabrikam-Fiber-Git:master.",
"markdown": "Jamal Hartnett pushed updates to `Fabrikam-Fiber-Git`:`master`."
},
"detailedMessage": {
"text": "Jamal Hartnett pushed a commit to Fabrikam-Fiber-Git:master.\n - Fixed bug in web.config file 33b55f7c",
"html": "Jamal Hartnett pushed a commit to Fabrikam-Fiber-Git:master.\n<ul>\n<li>Fixed bug in web.config file 33b55f7c\n</ul>",
"markdown": "Jamal Hartnett pushed a commit to [Fabrikam-Fiber-Git](https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git/):[master](https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git/#version=GBmaster).\n* Fixed bug in web.config file [33b55f7c](https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git/commit/33b55f7cb7e7e245323987634f960cf4a6e6bc74)"
},
"resource": {
"commits": [
{
"commitId": "33b55f7cb7e7e245323987634f960cf4a6e6bc74",
"author": {
"name": "Jamal Hartnett",
"email": "fabrikamfiber4#hotmail.com",
"date": "2015-02-25T19:01:00Z"
},
"committer": {
"name": "Jamal Hartnett",
"email": "fabrikamfiber4#hotmail.com",
"date": "2015-02-25T19:01:00Z"
},
"comment": "Fixed bug in web.config file",
"url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git/commit/33b55f7cb7e7e245323987634f960cf4a6e6bc74"
}
],
"refUpdates": [
{
"name": "refs/heads/master",
"oldObjectId": "aad331d8d3b131fa9ae03cf5e53965b51942618a",
"newObjectId": "33b55f7cb7e7e245323987634f960cf4a6e6bc74"
}
],
"repository": {
"id": "278d5cd2-584d-4b63-824a-2ba458937249",
"name": "Fabrikam-Fiber-Git",
"url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249",
"project": {
"id": "6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
"name": "Fabrikam-Fiber-Git",
"url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
"state": "wellFormed",
"visibility": "unchanged"
},
"defaultBranch": "refs/heads/master",
"remoteUrl": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git"
},
"pushedBy": {
"id": "00067FFED5C7AF52#Live.com",
"displayName": "Jamal Hartnett",
"uniqueName": "Windows Live ID\\fabrikamfiber4#hotmail.com"
},
"pushId": 14,
"date": "2014-05-02T19:17:13.3309587Z",
"url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/pushes/14"
},
"resourceVersion": "1.0",
"resourceContainers": {
"collection": {
"id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2"
},
"account": {
"id": "f844ec47-a9db-4511-8281-8b63f4eaf94e"
},
"project": {
"id": "be9b3917-87e6-42a4-a549-2bc06a7a878f"
}
},
"createdDate": "2017-07-21T16:48:44.312Z"
}
This is the Request that was send to Trello:
Method: POST
URI: https://api.trello.com/1/cards?key=7d6630fd03ac2b6fc9fde2f2ef0c4096&token=********
HTTP Version: 1.1
Headers:
{
Content-Type: application/json; charset=utf-8
}
Content:
{
"name": "Test Nº ",
"desc": "Description: ",
"pos": "top",
"due": null,
"labels": "green",
"idList": "5935a0d45ff8e5a6c8f828b9"
}
The only field that I could get/read from the Event JSON was the "message".
What am I doing wrong?
If you want to get the push ID and comments, the description is:
{{push.pushId}}
{{push.commits[0].comment}}
Update
Eddie is right you should use push as the resource in this case. The docs are not so clear. In the end, it was something so simple. However the corresponding checkin is not work for Code checked in event.
The docs could definitely be more clear in how the resource are for each event which applied to help avoid this confusion.
The basic form of the placeholder is {{resource.field}} where
resource is the name of the resource raising the event (workitem, build, etc) and field is a field within the resource section of the
event, like id. So, if the subscription were for a completed build,
it might be something like:
Build {{build.id}} completed at {{build.finishTime}}
Seems the issue is you are using the wrong placeholder in this case. According to your send Request , resource.pushID & resource.commits.[0].comment is not replaced by values from the event that was raised.

Youtube Data Subscription API V3 not returning NextPage when submitted with mySubscribers

I am not getting "nextPageToken" in the response object when I tried to retrieve list of users who subscribed to our channels using YT Data API (v3) Subscription. For some reason YT not returning "nextPageToken" even though below channel has more than 100K subscribers so could you please advise me on how to be able to fetch next pages of subscribers. Same behavior happening when I tried with any of channels from our CMS account:
Request:
https://www.googleapis.com/youtube/v3/subscriptions?onBehalfOfContentOwner=xxxx&onBehalfOfContentOwnerChannel=xxxxxxxxxxx&fields=items(contentDetails,id,snippet(publishedAt,channelId),subscriberSnippet(title,description)),nextPageToken,pageInfo,tokenPagination&maxResults=50&mySubscribers=true&part=id,snippet,contentDetails,subscriberSnippet&key=xxxxxxxxxxxxxxxx
Here is sample response snippet (I trimmed out other 48 items from below list and intentionally masked out subscriber details)
{
"items": [
{
"snippet": {
"channelId": "UCUR8UieACc2QXl7waH821hQ",
"publishedAt": "2014-05-20T19:50:44.000Z"
},
"contentDetails": {
"newItemCount": 0,
"activityType": "all",
"totalItemCount": 51
},
"subscriberSnippet": {
"description": "",
"title": "Sebastian Brentsworth"
},
"id": "MVPSEm5kMooIHMvcBKqbtFJAp1dHw0GeHza2Iq5KXP"
},
{
"snippet": {
"channelId": "UCYs04YSyy1soNzyvsDljYVg",
"publishedAt": "2014-05-28T22:39:30.000Z"
},
"contentDetails": {
"newItemCount": 0,
"activityType": "all",
"totalItemCount": 51
},
"subscriberSnippet": {
"description": "",
"title": "Jason Chan"
},
"id": "Xd7_fS3FIA4rnSu6NXEfxF8trXzL8-LspvIuYtDMmc0"
}
],
"pageInfo": {
"resultsPerPage": 50,
"totalResults": 144403
}
}
"Known" (Hopefully also to Google) bug:
https://code.google.com/p/gdata-issues/issues/detail?id=7163 and youtube.subscriptions.list (api v3) - nextPageToken isn't available
For the time being, I've came up with a token generator as a workaround (see other SO post, or here: https://gist.github.com/pulsar256/f5621e85ef50711adc6f)

Resources