Sending a canned response with Gmail Apps Script - javascript

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

Related

Apps Script - Gmail addon - Get selected text in Gmail message

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.

using third party api on watson assistant

i'm using the open weather map api in order to get information on the current weather and then integrate it with watson assistant (i used this as a reference for the watson assistant code) before deploying on the terminal. here's my code:
var city = "Seattle";
weather.setCity(city);
function processResponse(err, response){
if(err){
console.log(err);
return;
}
var endConversation = false;
if(response.intents[0]){
if(response.intents[0].intent=="CurrentWeather"){
weather.getDescription(function(err, desc){
weather.getTemperature(function(err, temp){
console.log("It is " + desc + " today with a temperature of " + temp + " degrees Celsius.");
)};
)};
}
else if(response.intents[0].intent=="end_conversation"){
console.log(response.output.text);
endConversation = true;
}
}
if(!endConversation){
var newMessageFromUser = prompt(">> ");
service.message({
workspace_id: workspace_id,
input: {
text: newMessageFromUser
},
context: response.context
},processResponse);
}
}
it works, but then the response looks like this:
>> what is the weather today in seattle
>>
It is few clouds today with a temperature of 29 degrees Celsius.
>> bye
['See ya!']
whenever i use any third party apis, instead of responding right after i enter the trigger keywords, the terminal asks me to input another entry (in the scenario above, i entered nothing) before responding. however, when i try to enter keywords related to intents whose responses are just retrieved right away from the watson assistant (as is with end_conversation), the terminal responds right away.
Is there a way for me to force the terminal to only ask once?
There are different ways to get around entering something before the actual response.
Take a look at client-based dialog actions. The key is to use the skip_user_input flag and check it within your application. Basically, it would indicate to your application that you need to process some data. The app would it send back to Watson Assistant to respond. There is also the server-based dialog action. In that case Watson Assistant is invoking an IBM Cloud Functions action. A tutorial using that approach is here, interfacing with a Db2 database.
Another technique is what I call replaced markers. You would have Watson Assistant returns an answer with placeholders. Your app would replace those markers.
Third, you are using JavaScript with asynchronous processing. It seems that your empty prompt is processed while you fetch the weather data. The IF for the weather is independent of the empty prompt. Try fixing that.
following Michal Bida's advice, I tried implementing the third party API in cloud function and it worked. simply created a php function using the php implementation of the openweather map api and followed the steps on how to create an action in php through this tutorial. for the implementation, i followed this tutorial on how to implement actions in watson assistant. it now works even when directly invoked from the chat bot at the side of the watson assistant.
an example of a response it returns will be:
{"weather":"It is raining today in Seattle with a temperature of 15 degrees Celsius"}

Facebook messenger bot (webhook)

I am trying to integrate facebook bot for my business page and followed this
Copied js code given to setup webhook and created a .js file... but when i tried to verify and save the message it showed was "The URL couldn't be validated. Response does not match challenge, expected value = '1227072936', received=' app.get('/webho...'".
I am .net developer and have no idea of javascript coding.
Can anyone suggest me where i am going wrong?
This is my code while verify web hook in java
i just create a serlvet with dopost method and then git the request parameters like below .. sure you have something like that in .net
String token = req.getParameter("hub.verify_token");
if (token != null && !token.equals("")) {
resp.setContentType("text/html");
if (token.equals("{verified_token}")) {
String challenge = req.getParameter("hub.challenge");
System.out.println("I am WebHock Verification --------> ");
}
}
{verified_token} is the token i added while verify my webhook url
the webhook url in the image below replaced by my serlvet URL :
I hope that help you

Google Execution API with Simple Access API key to access AUTHORS spreadsheet?

From what I understand, deploying a Google Script as a Google Execution API allows me to call each function from my script separately as and when I need it.
I have a webpage with some buttons and forms that I want to run the functions within my script on.
I have a Google Script with some (example) functionality:
function addPlayer(name,email,group) {
//name email group
var ss = SpreadsheetApp.openById(SHEET_ID); //Sheet belonging to me, script author.
var sheet = ss.getSheetByName("Players");
sheet.appendRow(new Date(),name,email,group);
}
function updatePlayer() {
//update player row with new data
//name email group
}
function anotherFunction() {
//store some data in another sheet within spreadsheet.
}
function listPlayers()
{
//return data from sheet
}
And a sample webpage which wants to run functions from that script:
function OnLoadCallback() { //on gapi load
gapi.client.setApiKey(API_KEY); //developer dashboard generated browser API key
// Create execution request.
var request = {
'function': 'addPlayer',
'parameters': [name,email,group],
'devMode': true
};
// Make the request.
var op = gapi.client.request({
'root': 'https://script.googleapis.com',
'path': 'v1/scripts/' + scriptId + ':run',
'method': 'POST',
'body': request
});
}
I get a 401 UNAUTHENTICATED error at the moment saying I do not have valid auth credentials.
Is it possible for this webpage to use the API without requiring each webpage visitor to oAuth (which doesn't make sense to me as it's not THEIR data/sheet I am trying to access but my own? I know if I deploy as web app I can set it to execute AS me, but is there any similar equivalent for the Execution API?
I chose to use execution script as I need to be able to run several different functions, and as a webapp my only option would be the doPost() which wouldn't let me differentiate adding to sheets/updating sheets/reading from sheets easily?
Am I missing something completely here? If this is entirely the wrong approach I would be super grateful if someone could point me in the right direction.
Thanks!
Based on this SO question, by adding SpreadsheetApp calls, you've modified the authentication scope required for your script. You need to update your scope to include Spreadsheets.
To use the API, you must supply a valid OAuth token that covers all the scopes used by the script. To find the correct scopes to include in the authentication token, open the project in the script editor, then select File > Project properties and click the Scopes tab.
Here is the link for the list of OAuth scope.
Check also this SO question for more information.

How to retrieve the ID of the sent e-mail via GmailApp?

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)

Categories

Resources