Merge the two different JSON using node JS - json

I have two requests that return their data as JSON using NodeJS Seriate.
The first response is:
{
"status": true,
"message": "Data Found",
"data": [
{
"statusCode": 200,
"body": {
"expand": "renderedFields,names,schem,operations,editmeta,changelog,versionedRepresentations",
"id": "64672",
"self": "https://computenext.atlassian.net/rest/api/2/issue/64672",
"key": "CKS-2016",
"fields": {
"parent": {
"id": "64670",
"key": "CKS-2014"
}
}
}
}
]
}
The second response is:
{
"statusCode": 200,
"body": {
"errors": [],
"detail": [
{
"repositories": [
{
"name": "registry",
"avatar": "http://stash.computenext.com/projects/SERVICES/avatar.png?s=32",
"avatarDescription": "services"
}
]
}
]
}
}
I want to merge the two responses, that would have the following structure:
{
"status": true,
"message": "Data Found",
"data": [
{
"statusCode": 200,
"body": {
"expand": "renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations",
"id": "64672",
"self": "https://computenext.atlassian.net/rest/api/2/issue/64672",
"key": "CKS-2016",
"fields": {
"parent": {
"id": "64670",
"key": "CKS-2014",
"detail": [
{
"repositories": [
{
"name": "registry",
"avatar": "http://stash.computenext.com/projects/SERVICES/avatar.png?s=32",
"avatarDescription": "services"
}
]
}
]
}
}
}
}
]
}
I searched and found several methods of joining or extending two JSON objects but nothing similar to that.
How can I achieve this?
My Actual Code is,
exports.getIssues = function(req, res) {
console.log(filename + '>>get Issues>>');
var response = {
status : Boolean,
message : String,
data : String
};
var request = require('request');
var username = const.username ;
var password = const.password ;
var options = {
url : 'https://computenext.atlassian.net/rest/api/2/search?jql=status+%3D+Resolved+ORDER+BY+updated',
auth : {
username : username,
password : password
}
};
request( options, function(error, obj) {
if (error) {
response.message = appmsg.DATA_NT_FOUND;
response.status = false;
response.data = obj;
res.send(response);
} else {
response.message = appmsg.DATA_FOUND;
response.status = true;
response.data = JSON.parse(obj.body);
//res.send(response);
var issueKey = response.data.issues;
// var keyData = issueKey[0].key;
// console.log(response.data.issues);
// console.log(keyData);
var output = [];
for(var i = 0; i < issueKey.length; i++) {
var issue = issueKey[i].key;
//var key = [];
//key.push(issue);
console.log(issue);
var respon = {
status : Boolean,
message : String,
data : String
};
var request = require('request'),
username = const.username ,
password = const.username ,
url = "https://computenext.atlassian.net/rest/api/2/issue/" + issue,
auth = "Basic " + new Buffer(username + ":" + password).toString("base64");
//console.log(url);
request({url : url,headers : {"Authorization" : auth}}, function(err, object){
if (object) {
var info = object;
output.push(info); // this is not working as ouput is undefined at this point
//var pout = JSON.parse(output);
//console.log(info);
console.log("==============================================================================");
//console.log(output);
console.log("******************************************************************************");
if(issueKey.length === output.length){
respon.message = appmsg.DATA_FOUND;
respon.status = true;
respon.data = output;
//console.log(output);
//res.send(respon);
var id = issueKey[0].id;
console.log(id);
var commitout = [];
for(var i = 0; i < issueKey.length; i++) {
var commits = issueKey[i].id;
console.log(commits);
var request = require('request'),
username = const.username ,
password = const.password ,
url = "https://computenext.atlassian.net/rest/dev-status/1.0/issue/detail?issueId=" + commits + "&applicationType=stash&dataType=repository",
auth = "Basic " + new Buffer(username + ":" + password).toString("base64");
//console.log(url);
var test = [];
request({url : url,headers : {"Authorization" : auth}}, function(err, obj1){
if (obj1) {
var info1 = obj1.body;
commitout.push(info1);
if(issueKey.length === commitout.length){
respon.message = appmsg.DATA_FOUND;
respon.status = true;
respon.data = commitout;
// console.log(commitout);
//var test = merge(output, commitout);
var text = output.body;
var resultdone = output;
resultdone.data = resultdone + commitout.body;
console.log(resultdone.data);
res.send(resultdone.data);
}
}
});
}
}
}
});
}
}
});
};
How can i merge the two arrays? in one response. That is my question..

Never mainpulate the string of JSON directly. Parse it first.
const firstRes = JSON.parse(firstResJson);
const secondRes = JSON.prase(secondResJson);
Now, it's a bit unclear what you want to do, and why you want to do it, but try this:
firstRes.data.body.fields.parent.detail = secondRes.body.detail;
Then, you'll find your combined data in firstRes. To get it back to JSON:
JSON.stringify(firstRes);

var obj1 = {
"status": true,
"message": "Data Found",
"data": [
{
"statusCode": 200,
"body": {
"expand": "renderedFields,names,schem,operations,editmeta,changelog,versionedRepresentations",
"id": "64672",
"self": "https://computenext.atlassian.net/rest/api/2/issue/64672",
"key": "CKS-2016",
"fields": {
"parent": {
"id": "64670",
"key": "CKS-2014"
}
}
}
}
]};
var obj2 = {
"statusCode": 200,
"body": {
"errors": [],
"detail": [
{
"repositories": [
{
"name": "registry",
"avatar": "http://stash.computenext.com/projects/SERVICES/avatar.png?s=32",
"avatarDescription": "services"
}
]
}
]}
}
obj1.data.forEach(function(item, index){
item.body.fields.parent.detail = r.body.detail[index];
});
console.log(obj1);

var result1 =
{
"status": true,
"message": "Data Found",
"data": [
{
"statusCode": 200,
"body": {
"expand": "renderedFields,names,schem,operations,editmeta,changelog,versionedRepresentations",
"id": "64672",
"self": "https://computenext.atlassian.net/rest/api/2/issue/64672",
"key": "CKS-2016",
"fields": {
"parent": {
"id": "64670",
"key": "CKS-2014"
}
}
}
}
]
}
var text = result1.data[0].body;
var result2 =
{
"statusCode": 200,
"body": {
"errors": [],
"detail": [
{
"repositories": [
{
"name": "registry",
"avatar": "http://stash.computenext.com/projects/SERVICES/avatar.png?s=32",
"avatarDescription": "services"
}
]
}
]
}
};
var resultdone = result1;
resultdone.data[0].body.fields.parent= result2.body.detail;

Related

App script once a week asking for authorization

I did a script (I'm not a programer) and I'm running to get a csv from metabase question. The only problem is because once a week as asking me to authorize again.
It shows:
"Authorisation required" "A script attached to this document needs your permission to run."
image step 02
image step 03
image step 04
What can I do to authorize forever?
I need to have the authorization forever. Not needed to authorize once a week because I'm running on time-base and automated. The code is below.
I have two files Code.gs and Code2.gs - on the first one I have another code.
function onInstall() {
onOpen();
}
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Import Question & Send Email')
.addItem('Import Question', 'importQuestion')
.addItem('Send Report by e-mail', 'sendReport')
.addToUi();
}
function importQuestion() {
var status = getQuestionAsCSV(metabaseQuestionNum, true);
var scriptProp = PropertiesService.getScriptProperties();
var metabaseQuestionNum = scriptProp.getProperty('QUESTION_ID');
var log = {
'user': Session.getActiveUser().getEmail(),
'function': 'importQuestion',
'questionNumber': metabaseQuestionNum,
'status': status
};
if (log.status === true) {
console.log(log);
} else {
console.error(log);
}
}
function getSheetNumbers() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var questionNumbers = [];
for (var i in sheets) {
var sheetName = sheets[i].getName();
if (sheetName.indexOf('(metabase/') > -1) {
var questionMatch = sheetName.match('\(metabase\/[0-9]+\)');
if (questionMatch !== null) {
var questionNumber = questionMatch[0].match('[0-9]+')[0];
if (!isNaN(questionNumber) && questionNumber !== '') {
questionNumbers.push({
'questionNumber': questionNumber,
'sheetName': sheetName
});
}
}
}
}
return questionNumbers;
}
function getToken(baseUrl, username, password) {
var sessionUrl = baseUrl + "api/session";
var options = {
"method": "post",
"headers": {
"Content-Type": "application/json"
},
"payload": JSON.stringify({
username: username,
password: password
})
};
var response;
try {
response = UrlFetchApp.fetch(sessionUrl, options);
} catch (e) {
throw (e);
}
var token = JSON.parse(response).id;
return token;
}
function getQuestionAndFillSheet(baseUrl, token, metabaseQuestionNum, sheetName) {
var questionUrl = baseUrl + "api/card/" + metabaseQuestionNum + "/query/csv";
var options = {
"method": "post",
"headers": {
"Content-Type": "application/json",
"X-Metabase-Session": token
},
"muteHttpExceptions": true
};
var response;
try {
response = UrlFetchApp.fetch(questionUrl, options);
} catch (e) {
return {
'success': false,
'error': e
};
}
var statusCode = response.getResponseCode();
if (statusCode == 200 || statusCode == 202) {
var values = Utilities.parseCsv(response.getContentText());
try {
fillSheet(values, sheetName);
return {
'success': true
};
} catch (e) {
return {
'success': false,
'error': e
};
}
} else if (statusCode == 401) {
var scriptProp = PropertiesService.getScriptProperties();
var username = scriptProp.getProperty('USERNAME');
var password = scriptProp.getProperty('PASSWORD');
var token = getToken(baseUrl, username, password);
scriptProp.setProperty('TOKEN', token);
var e = "Error: Could not retrieve question. Metabase says: '" + response.getContentText() + "'. Please try again in a few minutes.";
return {
'success': false,
'error': e
};
} else {
var e = "Error: Could not retrieve question. Metabase says: '" + response.getContentText() + "'. Please try again later.";
return {
'success': false,
'error': e
};
}
}
function fillSheet(values, sheetName) {
var colLetters = ["N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO", "AP", "AQ", "AR", "AS", "AT", "AU", "AV", "AW", "AX", "AY", "AZ", "BA", "BB", "BC", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BK", "BL", "BM", "BN", "BO", "BP", "BQ", "BR", "BS", "BT", "BU", "BV", "BW", "BX", "BY", "BZ", "CA", "CB", "CC", "CD", "CE", "CF", "CG", "CH", "CI", "CJ", "CK", "CL", "CM", "CN", "CO", "CP", "CQ", "CR", "CS", "CT", "CU", "CV", "CW", "CX", "CY", "CZ", "DA", "DB", "DC", "DD", "DE", "DF", "DG", "DH", "DI", "DJ", "DK", "DL", "DM", "DN", "DO", "DP", "DQ", "DR", "DS", "DT", "DU", "DV", "DW", "DX", "DY", "DZ", "EA", "EB", "EC", "ED", "EE", "EF", "EG", "EH", "EI", "EJ", "EK", "EL", "EM", "EN", "EO", "EP", "EQ", "ER", "ES", "ET", "EU", "EV", "EW", "EX", "EY", "EZ", "FA", "FB", "FC", "FD", "FE", "FF", "FG", "FH", "FI", "FJ", "FK", "FL", "FM", "FN", "FO", "FP", "FQ", "FR", "FS", "FT", "FU", "FV", "FW", "FX", "FY", "FZ", "GA", "GB", "GC", "GD", "GE", "GF", "GG", "GH", "GI", "GJ", "GK", "GL", "GM", "GN", "GO", "GP", "GQ", "GR", "GS", "GT", "GU", "GV", "GW", "GX", "GY", "GZ", "HA", "HB", "HC", "HD", "HE", "HF", "HG", "HH", "HI", "HJ", "HK", "HL", "HM", "HN", "HO", "HP", "HQ", "HR", "HS", "HT", "HU", "HV", "HW", "HX", "HY", "HZ", "IA", "IB", "IC", "ID", "IE", "IF", "IG", "IH", "II", "IJ", "IK", "IL", "IM", "IN", "IO", "IP", "IQ", "IR", "IS", "IT", "IU", "IV", "IW", "IX", "IY", "IZ", "JA", "JB", "JC", "JD", "JE", "JF", "JG", "JH", "JI", "JJ", "JK", "JL", "JM", "JN", "JO", "JP", "JQ", "JR", "JS", "JT", "JU", "JV", "JW", "JX", "JY", "JZ"];
var sheet;
if (sheetName == false) {
sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
} else {
sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('AUTO-productivity');
}
var range = sheet.getRange(1,14,1000,4);
range.clear({contentsOnly: true});
var rows = values;
var header = rows[0];
var minCol = colLetters[0];
var maxCol = colLetters[header.length - 1];
var minRow = 1;
var maxRow = rows.length;
var range = sheet.getRange(minCol + minRow + ":" + maxCol + maxRow);
range.setValues(rows);
}
function getQuestionAsCSV(metabaseQuestionNum, sheetName) {
var scriptProp = PropertiesService.getScriptProperties();
var baseUrl = scriptProp.getProperty('BASE_URL');
var username = scriptProp.getProperty('USERNAME');
var password = scriptProp.getProperty('PASSWORD');
var token = scriptProp.getProperty('TOKEN');
var metabaseQuestionNum = scriptProp.getProperty('QUESTION_ID');
if (!token) {
token = getToken(baseUrl, username, password);
scriptProp.setProperty('TOKEN', token);
}
status = getQuestionAndFillSheet(baseUrl, token, metabaseQuestionNum, sheetName);
return status;
}
Maybe you could try to add scopes in manifest file
In project file, open Setup, and check display manifest file "appsscript.json", and then open it.
Add:
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/script.send_mail",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/gmail.modify",
]
Reference :
Scopes
List of scopes

Google chat app is not responding for image attachment

I am trying to save attachment uploaded by google chat app.
I am handling two cases if user messages anything to google chat app, it will pop up a card with widgets which is perfectly fine but I am handling if user uploads attachment it will save into google drive but the code is not working. Can someone please help?
I am new in coding.
function getByteStream(dataRef) {
var blob = "";
var driveFileName = "";
var url = "https://chat.googleapis.com/v1/media/"+ dataRef +"?alt=media"
var service = getOAuth2Service();
var response = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + service.getAccessToken(),
},
'muteHttpExceptions': true,
});
if(response.getResponseCode() != 200){
return "Failed to get file content with error code: " + response.getResponseCode();
}
blob = response.getBlob();
driveFileName = DriveApp.createFile(blob);
return "The uploaded contents have been saved in a Google Drive file: "+ driveFileName;
}
function onMessage(event) {
if (event.message.attachment) {
var attachmentName = event.message.attachment[0].name;
var attachment = getByteStream(attachmentName);
console.log(attachment);
} else {
return {
"cards_v2": [{
"card_id": "addContact",
"card": {
"header": {
"title": "Hello" +" " + event.user.displayName + "!",
"subtitle": "Log your feedback!",
"imageUrl": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
"imageType": "CIRCLE"
},
"sections": [
{
"widgets": [
{
"buttonList": {
"buttons": [
{
"text": "Start here",
"onClick": {
"action": {
"function": "openDialog",
"interaction": "OPEN_DIALOG"
}
}
}
]
},
"horizontalAlignment": "CENTER"
}
]
}
]
}
}]
};
}
}

JSON Transformation to required format

We are working on a Middleware platform where we are required to respond to consumer with a JSON data in a particular format.
The Data we get from south bound API is a key value pair and this needs to be mapped to an understandable format for the consumer
We tried json-path, ObjectMapper but none of them is giving us the expected result for transforming
Respnse from backend API
{
"details": [
{
"name": "x.y.z.name","value": "TR-54695"
},
{
"name": "a.b.c.standards","value": "DOCSIS"
},
{
"name": "x.x.x.hversion","value": "10"
},
{
"name": "x.x.x.sversion","value": "9.1.116V"
},
{
"name": "x.x.x.uptime","value": "8000"
},
{
"name": "x.x.x.accessallowed","value": "true"
},
]
}
To be transformed to
{
"myData": {
"myInfo": {
"productClass": "TR-54695",
"supportedStandards": "DOCSIS",
"hardwareVersion": "10",
"softwareVersion": "9.1.116V",
"modemMacAddress": "",
"upTime": "8000",
"modemNetworkAccessAllowed": true
}
}
}
Do not like manual work, so here generated demo using 2 functions.
Mind ticking accept button under voting in case you like some answer.
function translate(src, mapping) {
var dst = { "myData": { "myInfo": { "modemMacAddress": "" } } }
//in case order matters:
dst = { "myData": { "myInfo": { "productClass": "", "supportedStandards": "", "hardwareVersion": "", "softwareVersion": "", "modemMacAddress": "", "upTime": "", "modemNetworkAccessAllowed": undefined } } }
var trueFalse = { "false": false, "true": true };
src = src.details;
for (var i = 0; i < src.length; i++) {
dst.myData.myInfo[mapping[src[i].name]] = trueFalse[src[i].value] || src[i].value;
}
return dst;
}
function generateMapping(src, dst) {
src = src.details;
var backLinks = {}, rename2 = {};
for (var i = 0; i < src.length; i++) {
backLinks[src[i].value] = src[i].name;
}
dst = dst.myData.myInfo;
for (var i in dst) {
rename2[backLinks[dst[i]]] = i;
}
return rename2;
}
var src = {
"details": [
{ "name": "x.y.z.name", "value": "TR-54695" },
{ "name": "a.b.c.standards", "value": "DOCSIS" },
{ "name": "x.x.x.hversion", "value": "10" },
{ "name": "x.x.x.sversion", "value": "9.1.116V" },
{ "name": "x.x.x.uptime", "value": "8000" },
{ "name": "x.x.x.accessallowed", "value": "true" },
]
}
var dst = {
"myData": {
"myInfo": {
"productClass": "TR-54695",
"supportedStandards": "DOCSIS",
"hardwareVersion": "10",
"softwareVersion": "9.1.116V",
"modemMacAddress": "",
"upTime": "8000",
"modemNetworkAccessAllowed": true
}
}
}
var mapping = generateMapping(src, dst);
// var mapping = {
// "x.y.z.name": "productClass",
// "a.b.c.standards": "supportedStandards",
// "x.x.x.hversion": "hardwareVersion",
// "x.x.x.sversion": "softwareVersion",
// "undefined": "modemMacAddress",
// "x.x.x.uptime": "upTime",
// "x.x.x.accessallowed": "modemNetworkAccessAllowed"
// }
var result = translate(src, mapping);
console.log(JSON.stringify(result, null, 2));
console.log(JSON.stringify(mapping, null, 2));
You can use below code and use codesandbox link (check console output ) for exact response and this link for key:value pair.
let response = {
details: [
{
name: "x.y.z.name",
value: "TR-54695"
},
{
name: "a.b.c.standards",
value: "DOCSIS"
},
{
name: "x.x.x.hversion",
value: "10"
},
{
name: "x.x.x.sversion",
value: "9.1.116V"
},
{
name: "x.x.x.uptime",
value: "8000"
},
{
name: "x.x.x.accessallowed",
value: "true"
}
]
};
// convert function for key value pair
function convertResponse(responseData) {
let output = { myData: { myInfo: {} } };
let outputRef = output.myData.myInfo;
responseData.forEach(element => {
outputRef[element.name] = element.value
});
return output;
}
// OR convert Function for getting exact same output
function convertResponse(responseData) {
let output = { myData: { myInfo: {} } };
let outputRef = output.myData.myInfo;
responseData.forEach(element => {
if (element.name === "x.y.z.name") {
outputRef.productClass = element.value;
} else if (element.name === "a.b.c.standards") {
outputRef.supportedStandards = element.value;
} else if (element.name === "x.x.x.hversion") {
outputRef.hardwareVersion = element.value;
} else if (element.name === "x.x.x.sversion") {
outputRef.softwareVersion = element.value;
} else if (element.name === "x.x.x.uptime") {
outputRef.upTime = element.value;
} else if (element.name === "x.x.x.accessallowed") {
outputRef.modemNetworkAccessAllowed = element.value;
}
});
return output;
}
//Function Call
console.log(convertResponse(response.details));

Angular Getting Value from Object Object

I would like to extract the value from the JSON below (resReturn.result.gamingdata.original.success)
Just wonder why I can get the value only if I do several times of stringify and parse.
Can someone tell me how to simplify my code?
JSON:
{
"status":"Success",
"message":"100",
"resReturn":
{
"result":{
"gamingdata":
{
"headers":{},
"original":{"success":"Gaming Data Excel - upload success"},
"exception":null
}
}
}
}
My Code:
let resReturnJSON = JSON.stringify(this.UploadstatusGamingDataExcel.resReturn);
let resultobj = JSON.parse(resReturnJSON || '{}').result;
let resultJSON = JSON.stringify(resultobj);
let gamingdataobj = JSON.parse(resultJSON || '{}').gamingdata;
let gamingdataJSON = JSON.stringify(gamingdataobj);
let originalObj = JSON.parse(gamingdataJSON || '{}').original;
let originalJSON = JSON.stringify(originalObj);
let successObj = JSON.parse(originalJSON || '{}').success;
console.log(successObj);
const value = {
"status": "Success",
"message": "100",
"resReturn":
{
"result": {
"gamingdata":
{
"headers": {},
"original": { "success": "Gaming Data Excel - upload success" },
"exception": null
}
}
}
}
const jsonValue = JSON.stringify(value);
const valueFromJson = JSON.parse(jsonValue);
const success = (((((valueFromJson || {}).resReturn || {}).result || {}).gamingdata || {}).original || {}).success;
Check for truthiness for every property until you hit success property and return if found or return empty string.
const data = {
"status": "Success",
"message": "100",
"resReturn": {
"result": {
"gamingdata": {
"headers": {},
"original": {
"success": "Gaming Data Excel - upload success"
},
"exception": null
}
}
}
};
const success = (data.resReturn &&
data.resReturn.result &&
data.resReturn.result.gamingdata &&
data.resReturn.result.gamingdata.original.success) ?
data.resReturn.result.gamingdata.original.success : '';
console.log(success);
If you want a generalised function for json having array and objects, you can use this,
const data = {
"status": "Success",
"message": "100",
"resReturn": {
"result": {
"gamingdata": {
"headers": {},
"original": {
"success": "Gaming Data Excel - upload success"
},
"exception": null
}
}
}
};
const get = (p, o) =>
p.reduce((xs, x) =>
(xs && xs[x]) ? xs[x] : null, o)
console.log(get(['resReturn', 'result', 'gamingdata', 'original', 'success'], data));
I have one more simplest solution:
let obj: any;
try {
if (data.resReturn.result.gamingdata.original.success) {
obj = data.resReturn.result.gamingdata.original.success
}
} catch(e) {
obj = null
}
console.log(obj);
For other different ways, you can also refer this answer

Send emails using Sendgrid with google appscript

I am creating a googlesheet addon to send mails.And for sending mails I am using sendgrid.
I cannot find any documentation or example code for sending mails with Google Appscript. This is the code I am using, but it is no good.
var data = {
"api_user":"username",
"api_key":"ioioi",
"to":[],
"tonnage":[],
"cc":[],
"ccname":[],
"bcc":[],
"subject":sub,
"from":from,
"html":htmlBody
}
var headers = { "Accept":"application/json",
"Content-Type":"application/json"
};
data = JSON.stringify(data);
var options = {
"method": "POST",
"payload": data,
"headers": headers,
"muteHttpExceptions": true
};
var res = UrlFetchApp.fetch("https://api.sendgrid.com/api/mail.send.json", options);
Does anyone have any idea or code to send emails with sendgrid using googl appscript?
Try the below code. It worked for me
var SENDGRID_KEY ='Your API KEY';
var headers = {
"Authorization" : "Bearer "+SENDGRID_KEY,
"Content-Type": "application/json"
}
var body =
{
"personalizations": [
{
"to": [
{
"email": "email id of the sender"
}
],
"subject": "Hello, World!"
}
],
"from": {
"email": "From email id"
},
"content": [
{
"type": "text",
"value": "Hello, World!"
}
]
}
var options = {
'method':'post',
'headers':headers,
'payload':JSON.stringify(body)
}
var response = UrlFetchApp.fetch("https://api.sendgrid.com/v3/mail/send",options);
Logger.log(response);
Also ensure that the API key you created in SendGrid has the all the credentials it needs to send the email
For anyone who has this issue in the future with Transactional Email Template:
https://sendgrid.com/docs/ui/sending-email/how-to-send-an-email-with-dynamic-transactional-templates/
This is the function to send (similar to the answer of Nikil Mathew, but for transactional email template with dynamic data):
export const sendBySendGrid = (toEmail, templateId, dynamicTemplateData) => {
const headers = {
Authorization: `Bearer ${process.env.SENDGRID_API_KEY}`,
'Content-Type': 'application/json',
}
const body = {
from: {
email: process.env.SENDGRID_FROM_EMAIL,
name: process.env.SENDGRID_FROM_NAME,
},
personalizations: [
{
to: [
{
email: toEmail,
},
],
dynamic_template_data: dynamicTemplateData,
},
],
template_id: templateId,
}
const options = {
method: 'POST',
headers,
payload: JSON.stringify(body),
}
const response = UrlFetchApp.fetch('https://api.sendgrid.com/v3/mail/send', options)
Logger.log(response)
}
You can update process.env.SENDGRID_API_KEY, process.env.SENDGRID_FROM_EMAIL, process.env.SENDGRID_FROM_NAME with your SendGrid credentials
Here's what's working for me right now in Google Apps Script, including using a dynamic template and insertion of dynamic data for the "handlebars" in my SendGrid template:
var SENDGRID_KEY ='API_KEY';
var headers = {
"Authorization" : "Bearer "+SENDGRID_KEY,
"Content-Type": "application/json"
}
function sendEmail_1() {
var body = {
"personalizations": [
{
"to": [
{
"email": "test#test.com",
"name": "Test Name"
}
],
"bcc": [
{
"email": "test#test.com"
}
],
"dynamic_template_data":
{
"firstName": "Marco Polo"
}
}
],
"from":
{
"email": "test#test.com",
"name": "Test Name"
},
"reply_to": {
"email": "test#test.com"
},
"template_id":"TEMPLATE_ID"
}
var options = {
'method':'post',
'headers':headers,
'payload':JSON.stringify(body)
}
var response = UrlFetchApp.fetch("https://api.sendgrid.com/v3/mail/send",options);
}