Last active
December 11, 2020 01:11
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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