I am trying to automise sending of the Emails from my account using Gmail API in Google Apps Script.
Here is my code:
function email_checker() {
var yourEmailAddress = "####gmail.com";
var myEmailAddress = "support####.com";
var subject = "testing mail";
var forScope = GmailApp.getInboxUnreadCount();
var htmlBody = '<html><body>' + '<h1>HI</h1>' + '</body></html>';
var message = 'From: Me <' + myEmailAddress + '>\r\n' +
'To: Me <' + myEmailAddress + '>\r\n' +
'Subject: ' + subject + '\r\n' +
'Content-Type: text/html; charset=utf-8\r\n' +
'Content-Transfer-Encoding: quoted-printable\r\n\r\n' +
htmlBody;
var draftBody = Utilities.base64Encode(message);
draftBody = draftBody.replace(/\//g, '_').replace(/\+/g, '-');
var params = {
method: "post",
contentType: "application/json",
headers: {
"Authorization": "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true,
payload: JSON.stringify({
"message": {
"raw": draftBody
}
})
};
var resp = UrlFetchApp.fetch("https://gmail.googleapis.com/upload/gmail/v1/users/me/messages/send", params);
Logger.log(resp.getContentText());
}
I am getting the following error: Media type 'application/json' is not supported.
Can anyone please advise on what I am doing wrong?
Thank you.
I believe your goal and your current situation as follows.
You want to send an email using Gmail API with UrlFetchApp.
You have already done the settings for sending the email.
Gmail API is enabled.
The scopes for sending emails can be included.
Modification points:
From your endtpoint, it is found that the media upload request is used.
In this case,
the request body is required to create with multipart/alternative.
It is not required to use the base64 encode with the web safe.
The content type is required to use message/rfc822.
The created request body can be directly used for payload.
When above points are reflected to your script, it becomes as follows.
Modified script:
function email_checker() {
var yourEmailAddress = "####gmail.com";
var myEmailAddress = "support####.com";
var subject = "testing mail";
var forScope = GmailApp.getInboxUnreadCount();
var htmlBody = '<html><body>' + '<h1>HI</h1>' + '</body></html>';
var message = 'MIME-Version: 1.0\r\n' +
'From: Me <' + myEmailAddress + '>\r\n' +
'To: Me <' + myEmailAddress + '>\r\n' +
'Subject: ' + subject + '\r\n' +
'Content-type: multipart/alternative; boundary=boundaryboundary\r\n\r\n' +
'--boundaryboundary\r\n' +
'Content-type: text/html; charset=UTF-8\r\n' +
'Content-Transfer-Encoding: quoted-printable\r\n\r\n' +
htmlBody + "\r\n\r\n" +
'--boundaryboundary--';
var params = {
method: "post",
contentType: "message/rfc822",
headers: {
"Authorization": "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true,
payload: message
};
var resp = UrlFetchApp.fetch("https://gmail.googleapis.com/upload/gmail/v1/users/me/messages/send", params);
Logger.log(resp.getContentText());
}
Note:
If you want to use the endpoint of POST https://gmail.googleapis.com/gmail/v1/users/{userId}/messages/send, please modify your script as follows.
From
var params = {
method: "post",
contentType: "application/json",
headers: {
"Authorization": "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true,
payload: JSON.stringify({
"message": {
"raw": draftBody
}
})
};
var resp = UrlFetchApp.fetch("https://gmail.googleapis.com/upload/gmail/v1/users/me/messages/send", params);
Logger.log(resp.getContentText());
To
var params = {
method: "post",
contentType: "application/json",
headers: {
"Authorization": "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true,
payload: JSON.stringify({"raw": draftBody})
};
var resp = UrlFetchApp.fetch("https://gmail.googleapis.com/gmail/v1/users/me/messages/send", params);
Logger.log(resp.getContentText());
In this case, var draftBody = Utilities.base64Encode(message); draftBody = draftBody.replace(/\//g, '_').replace(/\+/g, '-'); can be also modified to var draftBody = Utilities.base64EncodeWebSafe(message);.
Reference:
Method: users.messages.send
Related
I am looking to mention a user in a discord channel based on information set in a google sheet.
I have the script already pushing content from the google sheet to the discord channel so know that is working.
I can also get it to use the #everyone tag to mention everyone.
I am now wanting to get it set so that it only will mention the user.
Below is my script so far:
function onEdit() {
var wsID = " "
var sheet = SpreadsheetApp.openById(wsID).getSheetByName('discord');
var firestaff = sheet.getRange("A1").getValue();
var firecourse = sheet.getRange("B1").getValue();
var policestaff = sheet.getRange("A4").getValue();
var policecourse = sheet.getRange("B4").getValue();
var rescuestaff = sheet.getRange("A14").getValue();
var rescuecourse = sheet.getRange("B14").getValue();
var discordUrl = "",
options;
var firepayload = JSON.stringify({
content: "Please can " + firestaff + " start the " + firecourse + " courses. "
});
var policepayload = JSON.stringify({
content: "Please can " + policestaff + " start the " + policecourse + " courses.",
});
var rescuepayload = JSON.stringify({
content: "Please can " + rescuestaff + " start the " + rescuecourse + " courses."
});
var policemention = JSON.stringify({
content: "#everyone ",
})
var ssurl = JSON.stringify({
content: " "
});
var fireparams = {
method: "POST",
payload: firepayload,
muteHttpExceptions: true,
contentType: "application/json"
};
var policeparams = {
method: "POST",
payload: policepayload,
muteHttpExceptions: true,
contentType: "application/json"
};
var rescueparams = {
method: "POST",
payload: rescuepayload,
muteHttpExceptions: true,
contentType: "application/json"
};
var urlperms = {
method: "POST",
payload: ssurl,
muteHttpExceptions: true,
contentType: "application/json"
};
var policemen = {
method: "POST",
payload: policemention,
muteHttpExceptions: true,
contentType: "application/json"
};
UrlFetchApp.fetch(discordUrl, policemen)
UrlFetchApp.fetch(discordUrl, fireparams);
UrlFetchApp.fetch(discordUrl, policeparams);
UrlFetchApp.fetch(discordUrl, rescueparams);
UrlFetchApp.fetch(discordUrl, urlperms);
}
The only method available will be to create and store a list of users and their IDs, tagging them with <#THEUSERID>.
You can get the user IDs by right-clicking on a user's avatar.
In the following script I have to manually insert the email addresses. I rather get the list from the sheet to be able to update it without editing the script.
How do I retrieve a list of email addresses from the sheet (Sheet!A2:A)?
function sendReport() {
EMAIL = 'email'
URL = 'url'
+ '/export?'
+ 'format=pdf'
+ '&size=A4'
+ '&gid=id'
+ '&scale=4'
+ '&portrait=true';
SpreadsheetApp.getActive();
var response = UrlFetchApp.fetch(URL, {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
});
var message = {
to: EMAIL,
subject: "subject",
body: "body",
attachments: [response.getBlob().setName('file.pdf')]
}
MailApp.sendEmail(message);
}
Is the script you expect as follows?
Modified script:
function sendReport() {
URL = 'url'
+ '/export?'
+ 'format=pdf'
+ '&size=A4'
+ '&gid=id'
+ '&scale=4'
+ '&portrait=true';
var response = UrlFetchApp.fetch(URL, {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
});
// Retrieve values from Spreadsheet.
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getRange("A2:A" + sheet.getLastRow()).getDisplayValues();
// Send the email using the email addresses.
values.forEach(([email]) => {
if (email) {
var message = {
to: email,
subject: "subject",
body: "body",
attachments: [response.getBlob().setName('file.pdf')]
}
MailApp.sendEmail(message);
}
});
}
If you want to set the specific sheet, please modify var sheet = SpreadsheetApp.getActiveSheet(); to var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");.
Reference:
forEach()
I intend to update my bound script (destination) with contents from another script (source). I am trying the following code. It does not give any error, but do not modify the destination script either.
function getScriptSourceCode() {
var srcProjectId = "id of source project"; // Source project ID
var destProjectId = "id of destination project"
var baseUrl = "https://script.googleapis.com/v1/projects";
var accessToken = ScriptApp.getOAuthToken()
var srcName = JSON.parse(UrlFetchApp.fetch(baseUrl + "/" + srcProjectId, {
method: "get",
headers: {"Authorization": "Bearer " + accessToken}
}).getContentText()).title;
var content = UrlFetchApp.fetch(baseUrl + "/" + srcProjectId + "/content", {
method: "get",
headers: {"Authorization": "Bearer " + accessToken}
}).getContentText();
var url = "https://script.googleapis.com/v1/projects/" + destProjectId
+ "/content";
var options = {
followRedirects: true,
"method" : "PUT",
"muteHttpExceptions": true,
"headers": {
'Authorization': 'Bearer ' + accessToken
},
"contentType": "application/json",
"payload": JSON.stringify(content)
}
var response = UrlFetchApp.fetch(url, options);
}
}
Am i missing something?
Excuse me for the erroneous script. I modified the script little bit and now its working as desired. However it seems I have to run the script twice to get the desired result. Below is the working script.
function UpdateScript()
{
var destProjectId = "Destination project ID"
var srcProjectId = "Source Project ID"; // Source project ID
var baseUrl = "https://script.googleapis.com/v1/projects";
var accessToken = ScriptApp.getOAuthToken()
var content = UrlFetchApp.fetch(baseUrl + "/" + srcProjectId + "/content", {
method: "get",
headers: {"Authorization": "Bearer " + accessToken}
}).getContentText();
// Upload a project to bound-script project.
var response = JSON.parse(UrlFetchApp.fetch(baseUrl + "/" + destProjectId + "/content", {
method: "put",
contentType: 'application/json',
headers: {"Authorization": "Bearer " + accessToken},
payload: content
}).getContentText());
}
I try to automatically attach a file from my Google Drive (so ideally with the file id) in my Gmail draft created with Google Apps Script and GMail API. I use the syntax below. Can I do that easily? Creating the draft works great by the way.
Thanks! Chris
function createDraft() {
var forScope = GmailApp.getInboxUnreadCount(); // needed for auth scope
var htmlBody = 'Howzit';
var raw =
'Subject: Howzit\n' +
'To: aa#bb.cc\n' +
'Content-Type: text/html; charset=UTF-8\r\n' +
'\r\n' + htmlBody;
var draftBody = Utilities.base64Encode(raw, Utilities.Charset.UTF_8).replace(/\//g,'_').replace(/\+/g,'-');
var params = {method:"post",
contentType: "application/json",
headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions:true,
payload:JSON.stringify({
"message": {
"raw": draftBody
}
})
};
var resp = UrlFetchApp.fetch("https://www.googleapis.com/gmail/v1/users/me/drafts", params);
}
How about following sample script? This is a very simple script for attaching a file to a draft. So please modify this to your environment.
In order to use this script, please enable Gmail API at API console. And please import file ID to fileId in the script.
Sample script :
function createDraft() {
var fileId = "### file id ###";
var file = DriveApp.getFileById(fileId);
var forScope = GmailApp.getInboxUnreadCount();
var htmlBody = 'Howzit';
var raw =
'Subject: Howzit\r\n' +
'To: aa#bb.cc\r\n' +
'Content-Type: multipart/mixed; boundary=##########\r\n\r\n' +
'--##########\r\n' +
'Content-Type: text/html; charset=UTF-8\r\n\r\n' + htmlBody + '\r\n' +
'--##########\r\n' +
'Content-Type: ' + file.getMimeType() + '; charset=UTF-8; name="' + file.getName() + '"\r\n' +
'Content-Disposition: attachment; filename="' + file.getName() + '"\r\n' +
'Content-Transfer-Encoding: base64\r\n\r\n' + Utilities.base64Encode(file.getBlob().getBytes()) +
'\r\n--##########\r\n';
var draftBody = Utilities.base64EncodeWebSafe(raw, Utilities.Charset.UTF_8);
var params = {
method:"post",
contentType: "application/json",
headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions: true,
payload: JSON.stringify({"message": {"raw": draftBody}})
};
var resp = UrlFetchApp.fetch("https://www.googleapis.com/gmail/v1/users/me/drafts", params);
Logger.log(resp)
}
Result :
{
"id": "#####",
"message": {
"id": "#####",
"threadId": "#####",
"labelIds": [
"DRAFT"
]
}
}
Image :
streak api: https://www.streak.com/api/
I tried to use this streak api with GAS UrlService and found the right syntax for get requests. But I don't find the rigth syntax for put and post:
(1) f.e. create box
var RequestArguments = {
"contentType": "application/json",
"headers":{
"User-Agent": "MY_APP_NAME",
"Authorization": "Basic " + Utilities.base64Encode(streakApiKey),
},
"validateHttpsCertificates" :false,
"method": "PUT",
"????": "????"
};
var result = UrlFetchApp.fetch(RequestUrl,RequestArguments);
(2) f.e. edit box
var RequestArguments = {
"contentType": "application/json",
"headers":{
"User-Agent": "MY_APP_NAME",
"Authorization": "Basic " + Utilities.base64Encode(streakApiKey),
},
"validateHttpsCertificates":false,
"method": "PUT",
"????": "????"
};
var result = UrlFetchApp.fetch(RequestUrl,RequestArguments);
I use such way in my Chrome extension, didn't try this code but should be similar in GAS:
"url": "https://www.streak.com/api/v1/boxes/"+boxKey+"/fields/"+fieldKey;
"type": 'POST',
"dataType": "json",
"contentType": 'application/json; charset=utf-8',
"data": {value: yourValue}
It took me some time to figure out the right combination of parameters (Streak API documentation is not friendly in this part), but what I see in your code looks alright to me. It should work.
Here's the function you can use to edit a field in an existing box. Creating a new box will follow the same format.
function editBox(boxKey, fieldKey, value) {
var url = 'https://www.streak.com/api/v1/boxes/' + boxKey + '/fields/' + fieldKey;
var params = {
headers: {Authorization: 'Basic ' + Utilities.base64Encode(STREAK_API_KEY + ":")},
method: "POST",
payload: JSON.stringify({
value: value
}),
contentType: 'application/json'
};
var field = UrlFetchApp.fetch(url,params );
return JSON.parse(field.getContentText());
}
This is working:
function editBox() {
var boxKey = "xxx";
var value = "{value:Test}";
var fieldKey = "1001";
//{name:"Deal Size", key:"1001", type:"TEXT_INPUT", lastUpdatedTimestamp:1457089319053}
var url = 'https://www.streak.com/api/v1/boxes/' + boxKey + '/fields/' + fieldKey;
var params = {
headers: {Authorization: 'Basic ' + Utilities.base64Encode(streakApiKey)},
method: "POST",
payload: value,
contentType: 'application/json'
};
var result = UrlFetchApp.fetch(url,params );
var string = result.getContentText();
var Object = JSON.parse(string);
return Object;
}
function createBox() {
var pipelineKey = "xxx";
var name = "sample box name";
var url = 'https://www.streak.com/api/v1/pipelines/' + pipelineKey + '/boxes';
var RequestArguments = {
headers: {"Authorization": "Basic " + Utilities.base64Encode(streakApiKey)},
method: "PUT",
payload: {
name: name
}
};
var box = UrlFetchApp.fetch(url,RequestArguments);
var result = JSON.parse(box.getContentText());
return result;
}