I have developed a 2-way messaging flow in Twilio via Studio Flow and Messaging Service. At the end of the conversation, need to collect all the SMS (outbound/inbound) and send it to our system via REST API as json. I wrote a classic Twilio function and passed the "widgets" object to it. By iterating the same I can collect all the messages but they are not is sequence. Is there a way to get all the messages in sequence? Alternatively, is there a way to get the widgets collection in the sequence in which they got executed? This is how function is invoked from flow
Twilio function
exports.handler = function(context, event, callback) {
// const response = new Twilio.Response();
// response.appendHeader('Location', context.HTTP_REDIRECT_URL);
// callback(null, response);
//console.log('context', context.getTwilioClient());
console.log('event', event.all);
let allWidget = JSON.parse(event.all);
for (const key in allWidget) {
let currWidget = allWidget[key];
if (currWidget.outbound) {
console.log (key, '->', currWidget.outbound.To, currWidget.outbound.DateCreated, currWidget.outbound.Body, currWidget.outbound.Status);
}
//if (currWidget.incoming) {
// console.log (key, ':', currWidget.incoming.From, currWidget.incoming.DateCreated, currWidget.incoming.Body);
//}
if (currWidget.inbound) {
console.log (key, '<-', currWidget.inbound.From, currWidget.inbound.DateCreated, currWidget.inbound.Body);
}
}
};
You can get all messages sent on the Flow execution using the following function example
import { TwilioInstance } from './util/twilio-instance.mjs'
;(async () => {
const twilio = TwilioInstance()
const FLOW_SID = 'FWXXXX'
// getting an execution by id
const execution = await twilio.studio.v2
.flows(FLOW_SID)
// you can get it by the flow execution
.executions('FN819b8f8de2cc900898b9975874caa0a0')
.fetch()
// getting all steps from execution (with this api you can get all steps in sequence that were executed)
const steps = await twilio.studio.v2
.flows(FLOW_SID)
.executions(execution.sid)
.steps.list()
// getting step context from the last step of execution (with it we can get all widgets information)
const stepContext = await twilio.studio.v2
.flows(FLOW_SID)
.executions(execution.sid)
.steps(steps[0].sid)
.stepContext()
.fetch()
// filtering widgets to get just messages widgets and filtering by outbound date create
const filteringJustMessagesWidgets = Object.entries(
stepContext.context.widgets,
)
.filter(entry => {
const [_, value] = entry
if (value.inbound || value.outbound) return entry
})
.sort((a, b) =>
a[1].outbound.DateCreated > b[1].outbound.DateCreated ? 1 : -1,
)
filteringJustMessagesWidgets.map(entry => {
const [_, value] = entry
if (value.outbound) {
console.log(
'outbound',
new Date(value.outbound.DateCreated).toLocaleString(),
value.outbound.Body,
)
}
if (value.inbound) {
console.log(
'inbound',
value.inbound.From,
new Date(value.inbound.DateCreated).toLocaleString(),
value.inbound.Body,
)
}
})
})()
Remember that if you have some logic in your Studio Flow that the user can pass in the same message Widget (for example, to correct some information), using the example function will return just the last state of context because we're getting based on the last step executed.
I hope that it can help you!