Help

The Community will be temporarily unavailable starting on Friday February 28. We’ll be back as soon as we can! To learn more, check out our Announcements blog post.

Embed Calendar View in Automation Email?

Topic Labels: Automations
Solved
Jump to Solution
958 1
cancel
Showing results for 
Search instead for 
Did you mean: 
Kiersten_Kollin
6 - Interface Innovator
6 - Interface Innovator

Is it possible to embed a calendar view in an automated email?

1 Solution

Accepted Solutions
Sho
11 - Venus
11 - Venus

I don't know if this will match your use case, but you can use this script in automation to output calendar HTML.

Spoiler

Code:

const { month, year, recordIds } = input.config();

// Please specify the table name
const tableName = "table name"; 

// Caption format for year and month
const caption = `${year} / ${month}`; 

// Whether to link to records true or false
const recordLink = true; 

// URL up to tbl~ or viw~
const linkURL = "https://airtable.com/app~/tbl~/viw~"; 

// Common style
const style = "border:1px solid #ddd; padding:4px; width: 14.2857%; min-height:100px;";

function generateCalendar(year, month, records) {
  const firstDay = new Date(year, month - 1, 1);
  const lastDay = new Date(year, month, 0);
  const daysInMonth = lastDay.getDate();

  let calendarHTML = `<h3 style="text-align:center;">${caption}</h3><table>`;
  calendarHTML += '<tr><th style="width: 14.2857%">Sun</th><th style="width: 14.2857%">Mon</th><th style="width: 14.2857%">Tue</th><th style="width: 14.2857%">Wed</th><th style="width: 14.2857%">thu</th><th style="width: 14.2857%">Fri</th><th style="width: 14.2857%">Sat</th></tr>';
  calendarHTML += '';

  let dayCounter = 1;
  for (let i = 0; i < 6; i++) {
    calendarHTML += '<tr>';
    let bgColor = "#ffffff";
    for (let j = 0; j < 7; j++) {
      if (j === 0 || j === 6) {
        bgColor = "#efefef";
      } else {
        bgColor = "#ffffff";
      }
      if (i === 0 && j < firstDay.getDay()) {
        // Empty cells before the first day of the month
        calendarHTML += `<td style="${style} background-color:${bgColor};"></td>`;
      } else if (dayCounter <= daysInMonth) {
        const cellDate = new Date(year, month - 1, dayCounter);
        const matchingRecords = records.filter(record => {
          const recordDate = new Date(record.date);
          return cellDate.toISOString().split('T')[0] === recordDate.toISOString().split('T')[0];
        });

        const cellContent = matchingRecords.map(record => {
          let content = '<span style="display: inline-block; height: 100%; overflow: hidden; text-overflow: clip; border:1px solid #ddd;">';
          if(recordLink === true){
            content += `<a href="${linkURL}/${record.id}?blocks=hide&date=${record.date}&mode=month">${record.name}</a></span><br>`;
          } else {
            content += `${record.name}</span><br>`;
          }
          return content;
        });
        calendarHTML += `<td style="${style} background-color:${bgColor};">${dayCounter}<br>`;
        calendarHTML += cellContent.join(``);
        calendarHTML += "</td>";
        dayCounter++;
      } else {
        calendarHTML += `<td style="${style} background-color:${bgColor};"></td>`; // Empty cells after the last day of the month
      }
    }
    calendarHTML += '</tr>';
  }

  calendarHTML += '</table>';
  return calendarHTML;
}

const genYear = parseInt(year, 10);
const genMonth = parseInt(month, 10);

// Filtering by specified year and month
const queryRecords = await base.getTable(tableName).selectRecordsAsync({
  recordIds: recordIds
});
let records = queryRecords.records.map(record => {
  let name = record.getCellValueAsString("Name");
  let date = record.getCellValue("Date");
  return {name: name, date: date, id:record.id};
})
const calendarHTML = generateCalendar(genYear, genMonth, records);

// Setting the generated HTML to the 'Calendar' field
output.set('Calendar', calendarHTML);

 

Automation is set up like this:

2023-12-03 173412.png

Preview:

2023-12-03 174355.png

See Solution in Thread

1 Reply 1
Sho
11 - Venus
11 - Venus

I don't know if this will match your use case, but you can use this script in automation to output calendar HTML.

Spoiler

Code:

const { month, year, recordIds } = input.config();

// Please specify the table name
const tableName = "table name"; 

// Caption format for year and month
const caption = `${year} / ${month}`; 

// Whether to link to records true or false
const recordLink = true; 

// URL up to tbl~ or viw~
const linkURL = "https://airtable.com/app~/tbl~/viw~"; 

// Common style
const style = "border:1px solid #ddd; padding:4px; width: 14.2857%; min-height:100px;";

function generateCalendar(year, month, records) {
  const firstDay = new Date(year, month - 1, 1);
  const lastDay = new Date(year, month, 0);
  const daysInMonth = lastDay.getDate();

  let calendarHTML = `<h3 style="text-align:center;">${caption}</h3><table>`;
  calendarHTML += '<tr><th style="width: 14.2857%">Sun</th><th style="width: 14.2857%">Mon</th><th style="width: 14.2857%">Tue</th><th style="width: 14.2857%">Wed</th><th style="width: 14.2857%">thu</th><th style="width: 14.2857%">Fri</th><th style="width: 14.2857%">Sat</th></tr>';
  calendarHTML += '';

  let dayCounter = 1;
  for (let i = 0; i < 6; i++) {
    calendarHTML += '<tr>';
    let bgColor = "#ffffff";
    for (let j = 0; j < 7; j++) {
      if (j === 0 || j === 6) {
        bgColor = "#efefef";
      } else {
        bgColor = "#ffffff";
      }
      if (i === 0 && j < firstDay.getDay()) {
        // Empty cells before the first day of the month
        calendarHTML += `<td style="${style} background-color:${bgColor};"></td>`;
      } else if (dayCounter <= daysInMonth) {
        const cellDate = new Date(year, month - 1, dayCounter);
        const matchingRecords = records.filter(record => {
          const recordDate = new Date(record.date);
          return cellDate.toISOString().split('T')[0] === recordDate.toISOString().split('T')[0];
        });

        const cellContent = matchingRecords.map(record => {
          let content = '<span style="display: inline-block; height: 100%; overflow: hidden; text-overflow: clip; border:1px solid #ddd;">';
          if(recordLink === true){
            content += `<a href="${linkURL}/${record.id}?blocks=hide&date=${record.date}&mode=month">${record.name}</a></span><br>`;
          } else {
            content += `${record.name}</span><br>`;
          }
          return content;
        });
        calendarHTML += `<td style="${style} background-color:${bgColor};">${dayCounter}<br>`;
        calendarHTML += cellContent.join(``);
        calendarHTML += "</td>";
        dayCounter++;
      } else {
        calendarHTML += `<td style="${style} background-color:${bgColor};"></td>`; // Empty cells after the last day of the month
      }
    }
    calendarHTML += '</tr>';
  }

  calendarHTML += '</table>';
  return calendarHTML;
}

const genYear = parseInt(year, 10);
const genMonth = parseInt(month, 10);

// Filtering by specified year and month
const queryRecords = await base.getTable(tableName).selectRecordsAsync({
  recordIds: recordIds
});
let records = queryRecords.records.map(record => {
  let name = record.getCellValueAsString("Name");
  let date = record.getCellValue("Date");
  return {name: name, date: date, id:record.id};
})
const calendarHTML = generateCalendar(genYear, genMonth, records);

// Setting the generated HTML to the 'Calendar' field
output.set('Calendar', calendarHTML);

 

Automation is set up like this:

2023-12-03 173412.png

Preview:

2023-12-03 174355.png