I am developing a Gmail addon and need to get selected/highlighted text in a Gmail message via Google Apps Script. I can get whole message body via following code, but can't seem to find a way to get selected text.
function onGmailMessage(e) {
// Get the ID of the message the user has open.
var messageId = e.gmail.messageId;
// Get an access token scoped to the current message and use it for GmailApp
// calls.
var accessToken = e.gmail.accessToken;
GmailApp.setCurrentMessageAccessToken(accessToken);
// Get the subject of the email.
var message = GmailApp.getMessageById(messageId);
}
It is not possible to get client-side selected text of a Gmail message server-side - with the Gmail API / Apps Script
A Gmail Add-on can give you the following event objects when a trigger fires:
gmail.accessToken
gmail.bccRecipients[]
gmail.ccRecipients[]
gmail.messageId
gmail.threadId
gmail.toRecipients[]
A Gmail message resource contains the following information:
{
"id": string,
"threadId": string,
"labelIds": [
string
],
"snippet": string,
"historyId": string,
"internalDate": string,
"payload": {
object (MessagePart)
},
"sizeEstimate": integer,
"raw": string
}
Whereby this information is only available for saved sent / reveived messages or SAVED drafts.
Unfortunately, a Gmail Add-on (unlike a Docs Add-on) does not have any access to the text that is typed / selected client-side into the draft module.
If this feature is crucial for your application you would need to change direction and consider e.g. a Chrome extension where it might be possible to scrape client-side content with HTML / Javascript.
Related
I'm writing an auto-replying tool for gmail using Google Apps Script (http://script.google.com).
In the docs, I don't find any function to send a Gmail canned response. Is there no such feature?
If not, how would you handle this? I thought about sending an email to myself in gmail:
To:example#gmail.com
From:example#gmail.com
Subject:This is a canned response ID1847
Hi
This is a test
adding the label mycannedresponse to it, and then loading in Apps Script this mail from code:
var threads = GmailApp.search("label:mycannedresponse ID1847");
if (threads.length != 1) {
// error: the canned response ID... is not unique
} else {
threads[0].getBody(...)
threads[0].getPlainBody(...)
}
Is there a more-documented way to do it?
Have you seen the sendEmail method for GAS? You can create a trigger to fire off this email.
// The code below will send an email with the current date and time.
var now = new Date();
GmailApp.sendEmail("mike#example.com", "current time", "The time is: " + now.toString());
https://developers.google.com/apps-script/reference/gmail/gmail-app#sendemailrecipient-subject-body
I'm trying create a simple UI here on my iOS app to test a thing or two out but I'm having some issues here. My app is set up with a UITextField and UIButton. I'm trying to replace a string on my .js file which is saved on my virtual server. In my .js file I have below:
// Prepare a new notification
var notification = new apn.Notification();
// Display the following message (the actual notification text, supports emoji)
notification.alert = 'Hi James';
I basically would like to replace "Hi James" with whatever I typed in the UITextField in my Swift 3 project but not too sure where to start. This would be my first time sending data to .js file so anything would help. I'm thinking so far that it'd be something along the lines to below. Node.js would be similar to Javascript since it's cross platform.
func sendSomething(stringToSend : String) {
appController?.evaluateInJavaScriptContext({ (context) -> Void in
//Get a reference to the "myJSFunction" method that you've implemented in JavaScript
let myJSFunction = evaluation.objectForKeyedSubscript("myJSFunction")
//Call your JavaScript method with an array of arguments
myJSFunction.callWithArguments([stringToSend]) }, completion: { (evaluated) -> Void in
print("we have completed: \(evaluated)")
})
}
Found that on a relevant StackOverflow post so I feel like I'm getting close. Any assistant would be appreciated in advanced. Have a good one!
I recommend using the Node HTTP or ExpressJS server reading the POST fields and posting a document from your iOS app with the desired field
See
https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/
I have a one-pager campaign site which should collect PageView and LEAD event data for Facebook targeting with "advanced matching".
For PageView, I need to initialize the Pixel on page load. For advanced matching, I need to provide user data for initialization script — however, I only have user data available after user has submitted the data, which is when the LEAD event should be sent.
Is it possible to provide the initialization script with a "pointer" to a javascript variable that is used when sending the LEAD event? Help page hints at this, but all the examples have e.g. email parameter provided as plain text or sha256 hash; not as JS variable nor as a textual pointer to one.
From the "Advanced Matching with the Pixel" help page:
To enable this feature, modify the default FB pixel code to pass data
into the pixel init call.
fbq('init', '<FB_PIXEL_ID>', {
em: '{{_email_}}',
// Data will be hashed automatically via a dedicated function in FB pixel
ph: '{{_phone_number_}}',
fn: '{{_first_name_}}'
....
})
In the example above, you will need to replace email, phone_number,
first_name with the names of the variables on your website that
capture this data.
Let's say I have user_email variable in the same scope as fbq-init:
var user_email = '';
Later, after the form is submitted, this variable will be populated like
user_email = "john#example.com";
How should I reference the variable in fbq? (1) Like this?
fbq('init', 123456, { em: '{{_user_email_}}' });
(2) Or like this?
fbq('init', 123456, { em: 'user_email' });
(3) Or should I provide it simply with the variable:
fbq('init', 123456, { em: user_email }); // nb: user_email === false when this is run
(4) Or should I initialize the pixel without any matching data and later enrich it? (How?)
A reputable ad agency sent me with instructions to submit the name of the variable as in my example 2, but the help page hints at 1 without actually providing any real world examples.
I tried all the options 1–3, and it seems variables won't get re-evaluated in subsequent fbq('track', …); calls after the initialization. If user_email is blank to start with, none of the events will include hashed user data.
Moreover even if I start with a valid email user_email = "john#example.com"; (also tried real domains instead of example.com) only method 3 will work — but, as expected, this is not dynamic, ie. if user_email changes the hashes won't.
It is as if there is no string-variable replacement to begin with.
Would the more proper question be: how do I submit user data for advanced matching after the pixel initialization? Instead of trying to make the initialization lazy/dynamic.
As a workaround it is possible to generate a Lead event with email user data by loading the pixel (image) via javascript:
// here the user email is unknown, so PageView is generated without email
fbq('init', 123456, {});
fbq('track', 'PageView');
// Later the form is submitted via ajax, so the user email is known
$.ajax(…).done(function(data) {
// I decided to sha256 hash the email address in the backend and return it for the javascript handler
var pixel = document.createElement('img');
pixel.src = 'https://www.facebook.com/tr/?id=123456&ev=Lead&ud[em]=' + data;
document.body.appendChild(pixel);
// confirmed by the Pixel helper Chrome extension, this does generate a valid tracking event
// (ironically, we're loading the noscript version via javascript)
});
Of course, a pure fbq version would be more desirable. Also, I'm yet unaware of possible drawbacks, should there be any.
Here is a sample code
GmailApp.sendEmail("email#example.com", "mail subject", "mail body");
after the call I can see a sent message in my gmail account and that has a ID like this 147f7e77a4efed11 I want to retrieve this ID for the sent mail via the above code
sendEmail method returns an instance of GmailApp which is useful for chaining actions but no way to get the ID of the sent email.
what I am doing now is to perform a search and take the first message. But I am sure that is not a reliable way.
example
var message = GmailApp.search("to:email#example.com", 0, 1)[0].getMessages()[0];
now I can get the ID of the message and perform the desired actions.
Is it possible to retrieve the message or the ID of the message without an unreliable search?
After building your service, you can use the messages.list and then filter them like you would when searching in GMail, you can also use labels to get only sent mails etc.
messages = gmail_service.users().messages().list(userId='me', q="subject:mail subject deliveredto:email#example.com", maxResults=1).execute()
if messages['messages']:
for message in messages['messages']:
print 'message ID: %s' % (message['id'])
If you pass through the email you're searching for and other "unique" references as arguments in a Python function it makes it a lot more versatile too.
Edit: After talking with you I think that creating your own personal ID/reference for each email sent would be the most prudent method of retrieval. I recommend using faker, they have a javascript version and I use faker for all of my data needs. There's plenty of documentation for it and then you can filter your list according to how you set your ID.
you can use the new gmail api directly. you will need a manual oauth flow to get the token, then use urlFetch to make the call. https://developers.google.com/gmail/api/v1/reference/users/messages/send
it returns a message resource with its id. might also be possible to do this with advanced services but i havent tried. i have done it with urlfetch and worked ok.
Can you set the Message-Id header on the email? (Not sure if the apps scripts allows that or overwrites it or not.) If so, I'd generate a unique Id that way and you can look it up using a search "rfc822msgid:".
create a draft first, then send it
function sendEmail(opts) {
let draft = GmailApp.createDraft(recipient=opts.recipient, subject=opts.title, {
htmlBody: opts.msg,
});
draft.send()
let ret = {
id: draft.getId(),
messageId: draft.getMessageId(),
}
console.log('sendEmail results: ', ret )
return ret
}
2022 Update
GmailDraft.send() returns a GmailMessage you can use that to label the sent message.
Example:
const draft = GmailApp.createDraft('Foo <foo#bar.com>','Lorem Ipsum','Dolor Sit Amet');
const label = GmailApp.getUserLabelByName('Test');
const msg = draft.send();
const thrd = msg.getThread();
label.addToThread(thrd);
google-apps-script solution working for sent messages with methods: GmailApp, MailApp
enable Gmail service
use the code:
var messages = Gmail.Users.Messages.list(
"me", {q: "subject:Test Me", maxResults: 1}
).messages;
console.log(messages[0].id)
Recently was enabled Google + Domains API For Apps Script, I have explored some options and it seems is going to work, but in the specific case of PlusdDomains.Circles.list I don't know how to pass the second argument what is an object, I can not obtain several fields in the response, this is my code.
function getProfile() {
var userId = 'me';
var post = { maxResults: 2, fields:"title"};
var profile = PlusDomains.Circles.list(userId, post);
Logger.log('all: %s', JSON.stringify(profile));
}
this is the output,all: {"title":"Google+ List of Circles"}
if I try to get another field I don't know if this is correct, I put this:
var post = { maxResults: 2, fields:["title", "items"]};
but I get the same result:all: {"title":"Google+ List of Circles"}
If I try to get the result value for items, I get undefined. I don't how to pass the object correctly or if this is a bug in the Apps Script, somebody has idea??
I'm trying to get this working too. From the public google+ domain api docs it looks that the fields property expects a string with field names comma separated, i.e.
var post = { maxResults: 2, fields:"title,items"};
I don't seem to get the items populated (all the properties are undefined) in my google apps script. But when I use the API explorer "try it" console with OAuth2 enabled for scopes https://developers.google.com/+/domains/api/circles/list and https://developers.google.com/+/domains/api/circles/list I do see the items populated, so I'm thinking there may be an issue with my scripts authorization scopes or a bug in the google apps google+ domain service.