Skip to main content

I want to send emails via SendGrid. this is to be done through an automation baed on a trigger of when a record enters a view, like this:

The email text contains many personalisations, pulled from the database. Some of these fields are lookup fields from other databases. Below are all the personalised fields:

 

And here is the script:

// Get your SendGrid API key (store securely)
const SENDGRID_API_KEY = "-KEYisHERE-";

// Get the record that triggered the automation
let record = input.config();

// Extract values from arrays BEFORE building email
let firstName = Array.isArray(record.firstName) ? record.firstName[0] : record.firstName;
let projectLeadName = Array.isArray(record.projectLeadName) ? record.projectLeadName[0] : record.projectLeadName;
let task = Array.isArray(record.task) ? record.task[0] : record.task;

// Debug - verify values
// console.log("Project Lead Name:", projectLeadName);
// console.log("Task:", task);
// FOR TESTING
// console.log("All record data:", record);
// console.log("Type:", typeof record.projectLeadName[0]);
// console.log("Type:", typeof record.task);
// console.log(record.projectLeadName[0])

// Prepare the email
let emailData = {
personalizations: [{
to: [{ email: Array.isArray(record.email) ? record.email[0] : record.email}],
subject: `[ID: ${record.applicationID}] Future Impact Group: Invite to Submit Project Assessment`
}],
from: {
email: "luke@futureimpact.group",
name: "Luke from FIG"
},
reply_to: {
email: "info@futureimpact.group",
name: "Future Impact Group"
},
content: [{
type: "text/html",
value:
`<p>Hi ${record.firstName}!</p>

<p>Thanks for your interest in the Winter 2025 FIG Fellowship. Now it's time to answer a specific question about the project you applied for!</p>

<p>In this email you'll find:</p>
<ul>
<li>project description</li>
<li>a description of the task you should complete</li>
<li>your application ID, <strong>specific to this project</strong></li>
<li>a link to a form where you can submit your answer.</li>
</ul>

<p>If you registered interest to participate in more than one project you'll receive a separate email for each project, <strong>each with a different task and application ID.</strong></p>

<p>❗️ Please <strong>submit all your answers by midnight on Oct 19, Anywhere on Earth</strong> to allow the FIG team and the project lead enough time to evaluate it.</p>

<br>

<h3>DESCRIPTION</h3>
<p>As a reminder, here's the description of project you applied for: ${record.projectTitle} with ${record.projectLeadName}.</p>

<br>

<h3>TASK</h3>
<p>The task we have for you is below.</p>

<p>${record.task}</p>

<p>Answering should take you ~30 minutes. You can do so directly in the form, or write elsewhere and copy-paste into the form.</p>

<br>

<h3>APPLICATION ID</h3>
<p>Lastly—and <strong>very importantly</strong>!—your application ID for this project is below. You'll be asked to write it in the submission form.</p>

<h2>${record.applicationID}</h2>

<h3>Submit your answer ➡️ <a href="https://airtable.com/appvWAOurdQ3Y6kFm/pagqERyUofyUmvcbt/form">here</a>!</h3>

<p>Thanks again for taking the time to apply and best of luck!</p>

<p>Luke Dawes<br>
`
}]
};

// Send via SendGrid API
let response = await fetch("https://api.sendgrid.com/v3/mail/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${SENDGRID_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify(emailData)
});

if (response.status === 202) {
console.log("✅ Email sent successfully!");
} else {
console.log("❌ Error:", response.status, await response.text());
}

When I test the email in the SG scripting window it works well. By this I mean:

  • the email is delivered, AND
  • the text shows all the personalised values.

However, when the automation is turned on it changes. The emails get delivered, but not all the personalised values appear in the email text. Namely `projectLeadName` and `task` do not appear.

Claude tells me that Airtable automatically flattens some values in testing, a process that’s not repeated in deployment. If true, this is frustrating. 

I’d appreciate suggestions on:

  1. how this script can be changed such that al values appear in the email;
  2. what can/should I be checking to look for the cause of this error (assume we can’t rely on test outputs of running this script)

If you have any questions that would help you answer the above, let me know.

 

Hm that’s strange.  In emaildata.content, we’re using ${record.projectLeadName} and ${record.task} instead of ${projectLeadName} and ${task}, is that intended?  

Could you provide a screenshot of the automation run history for one of the runs where it didn’t send out all the personalized values?  Specifically, the Run a Script action’s input data, as well as the console logs for that run?

Alternatively if you could private message me a link to your base I could take a look for you too!


test step 
execution triggered by submitting the form

Difference: ${record.projectLeadName} and ${record.task} vs ${projectLeadName} and ${task}.

I (strongly believe I have) tested both, can’t remember which version was on for the logs I attached above; we can assume the ${record.projectLeadName} and ${record.task}. I will test the other one again a few hrs to make sure this was also failing.


Hm in the screenshot ‘execution triggered by submitting the form’, the ‘task’ and ‘projectLeadName’ inputs are empty, which means the script isn’t getting values at all, and so it makes sense that the resulting email output doesn’t put anything for those values?

Can we add some conditions to the automation so that it only triggers when the fields for those two values aren’t empty?

 

That’s the crux of the matter, in the table this script is pulling from these values are not empty. They should be the same as on the first screenshot I shared. 

For some reason these inputs are not received (not parsed well? idk), and hence not added to the email. I don’t know where in the process they disappear.

Below is the same record in the DB where you can see that the values in the respective columns exist.

 


Oh, I just realized I made a mistake, so sorry, the screenshot you provided actually has the ‘>’ signs at the right, and so that part’s fine.  Hm let me run a test and get back to you real quick


Hm I tried to replicate the issue but wasn’t able to, and you can find my test base here

The one difference is that my script input shows the data immediately without the ‘>’ on the far right:

I experimented a bunch but wasn’t able to get that ‘>’ to show up and without access to a copy of the base it’s difficult to help I’m afraid.  Hopefully someone else has a better idea!


Hi ​@Marta_Krzeminsk,

Sorry, I don’t know Javascript, so I can’t help fix your Javascript coding problems above.

However, I just wanted to say that if you’d like a MUCH EASIER way of handling all of this — which doesn’t require writing any JavaScript code at all — you may want to consider doing all of this with Make’s SendGrid integrations combined with Make’s Airtable integrations.

I’ve got all of my Airtable consulting clients setup with Make for their advanced automations & integrations, because it is a no-code app that doesn’t require knowing any code at all. (Although they also support writing code, too.)

So Make is super easy to learn — yet it is also super powerful, super customizable, and super inexpensive.

Make has native, built-in support for 3,000+ apps, but you can even use it to communicate with non-native apps as well.

Even better, once you switch over to Make, it opens you up to a whole new world of easily connecting with ANY email sending app on the web.

For example, I have several of my clients using MailGun instead of SendGrid, because it turns out that MailGun is so much easier & so much better than SendGrid -- with better tech support too! But you can choose from any email sending app that you would like.

If you’ve never used Make before, I’ve assembled a bunch of Make training resources in this thread. For example, here is one of the ways that you could instantly trigger a Make automation from Airtable

I also give live demonstrations of how to use Make in many of my Airtable podcast appearances. For example, in this video, I show how to work with Airtable arrays in Make.

Hope this helps!

If you’d like to hire the best Airtable consultant to help you with anything Airtable-related, please feel free to contact me through my website: Airtable consultant — ScottWorld


Thanks for the suggestion ​@ScottWorld -- this looks a bit too complicated for us (too many elements).

@TheTimeSavingCo I really appreciate you taking the time to engage with my issue with this level of detail, it makes me feel valued!

Extra info I just found out: Looking at the structure of the DB. One of the lookup fields in the DB I’m using to compose this email links to a DB in which it’s already a lookup field. My guess was that by using record.projectLeadName[0] I was just retrieving an empty array (potentially an array of arrays).

However, when I test the type (typeof record.task[0], typeof record.projectLeadName[0])) they are both strings. And yet the email returns empty values in these places. idk what else to test.

Btw. I’m talking to Claude  to solve it too, so we’re not relying only on my mind here 😅


Hm, I just tried making the lookup of a lookup like you mentioned and it worked fine for me as well I’m afraid:

 

Data:


Automation run:


Hmm, could you PM me an invite to a duplicated copy of your base with a bit of test data in it please?  To do that, you’d just duplicate your base with no records, and then create a bit of test data in it

Sorry, I don’t think I can’t help much via screenshots for this matter and it’d be a lot faster if I could troubleshoot via the base itself!