Skip to content

Instantly share code, notes, and snippets.

@craigsdennis
Last active December 11, 2020 01:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save craigsdennis/e6113052dcdaa98f143c2a7707b65937 to your computer and use it in GitHub Desktop.
Save craigsdennis/e6113052dcdaa98f143c2a7707b65937 to your computer and use it in GitHub Desktop.
Save Twilio Studio Flow Execution Context to Airtable if Widget name and field names match
// Create an Airtable with fields that match the widget names that you want to record
// Make your primary key ExecutionSid and add a ContactChannelAddress field
// Set your environment variables AIRTABLE_*
// Run Function in Studio and pass the following params:
// Flow: {{flow | to_json }}
// Widgets: {{widgets | to_json}}
// Contact: {{contact | to_json}}
require("dotenv").config();
const Airtable = require("airtable");
const axios = require("axios");
const airtable = new Airtable({ apiKey: process.env.AIRTABLE_API_KEY });
const base = airtable.base(process.env.AIRTABLE_BASE_ID);
async function getFieldNames(tableName) {
// https://airtable.com/api/meta
const url = `https://api.airtable.com/v0/meta/bases/${process.env.AIRTABLE_BASE_ID}/tables`;
const config = {
headers: { Authorization: `Bearer ${process.env.AIRTABLE_API_KEY}` },
};
const { data } = await axios.get(url, config);
const table = data.tables.find((table) => table.name === tableName);
return table.fields.map((field) => field.name);
}
const fieldNamesPromise = getFieldNames(process.env.AIRTABLE_TABLE_NAME);
exports.handler = async (context, event, callback) => {
try {
const fieldNames = await getFieldNames(process.env.AIRTABLE_TABLE_NAME);
const widgetContext = JSON.parse(event.Widgets);
const flowContext = JSON.parse(event.Flow);
const contactContext = JSON.parse(event.Contact);
const widgets = Object.keys(widgetContext)
.filter((widgetName) => fieldNames.includes(widgetName))
.reduce(
(prev, widgetName) => {
const inbound = widgetContext[widgetName].inbound;
if (inbound !== undefined) {
// Is there more places where a value could hide?
prev[widgetName] = inbound.Body;
}
return prev;
},
{
ExecutionSid: flowContext.sid,
ContactChannelAddress: contactContext.channel.address,
}
);
const variables = Object.keys(flowContext.variables)
.filter((variableName) => fieldNames.includes(variableName))
.reduce((prev, variableName) => {
prev[variableName] = flowContext.variables[variableName];
return prev;
}, {});
const values = {...widgets, ...variables};
const records = await base(process.env.AIRTABLE_TABLE_NAME).create([
{
fields: values,
},
]);
callback(null, {
created: records.length,
fieldNames,
});
} catch (err) {
console.error(`Uh oh: ${err}`);
callback(err);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment