I found a pretty good project that examples that! And the best part is that really works very well!
Basically, you only need to set up the webhooks when a call is made and on this webhook you call the processRecordCall :D
The method is here:
async function processRecordCall(req){
let callSID = req.body.inboundResourceSid;
console.log(req.body.inboundResourceSid);
console.log(req.body.inboundResourceStatus);
console.log(req.body.outboundResourceStatus);
//The only Proxy callback we care about is the one that provides us context for the initiated outbound dial. We will ignore all other callbacks (including those with context for SMS). Alternatively and depending on the use case, we could use the Proxy "Intercept" callback, but this has additional requirements for handling error status.
if(req.body.outboundResourceStatus == "initiated")
{
//Get all recordings for a given call.
let recordings = await client.recordings.list({callSid: callSID});
console.log(recordings.length);
//We only want to start recording if there are no existing recordings for this callSid. *This may be overkill as I haven't hit this edge case. Consider it preventitive for now*
if(recordings.length == 0)
{
let recordingSet = false;
let callStatus = "";
//Self-invoking function to facilitate iterative attempts to start a recording on the given call. See example here: https://stackoverflow.com/a/3583740
(function tryRecord (i) {
setTimeout(async function () {
if(!recordingSet && i > 0)
{
console.log(`I is ${i}`);
//Fetch the call to see if still exists (this allows us to prevent unnecessary attempts to record)
//Prod code probably needs callback or async added to ensure downstream execution is as expected
let call = await client.calls(callSID).fetch();
callStatus = call.status;
//Only attempt to create the recording if the call has not yet completed
if(callStatus != "completed")
{
//Try to create the recording
try{
let result = await axios.post(`https://api.twilio.com/2010-04-01/Accounts/${accountSid}/Calls/${callSID}/Recordings.json`, {},
{
auth: {
username: accountSid,
password: authToken
}
});
//This code assumes an HTTP 201 *Created* status and thus sucessful creation of recording. Production code may need to explicitly ensure HTTP 201 (eg. handle any other possible status')
console.log(`statusCode: ${result.status}`);
recordingSet = true; //This isn't entirely necessary (eg. could just set i=1 to force stop iteration), but I'm making an assumption that most use cases will prefer having this for reporting purposes
} catch(err){
//TODO(?) - There may be specific errors that should be explicitly handeled in a production scenario (eg. 21220)
}
}
else //The call is completed, so there's no need to loop anymore
{
console.log("Force stop iteration");
i = 1; //Set i = 1 to force stop the iteration
}
}
if (--i || !recordingSet) tryRecord(i); // decrement i and call myLoop again if i > 0 or if recording is not set
}, 1000) //NOTE: 1 second time delay before retry (this can be whatever works best --responsibly-- for the customer)
})(15); //NOTE: 15 attempts to record by default (unless forced to stop or recording already started. This can be whatever works best --responsibly-- for the customer)
}
else
{
console.log("recording exists already");
}
}
else
{
console.log(`We ignored callback with outgoing status '${req.body.outboundResourceStatus}'`);
}
}
I'm linking the full project below
https://github.com/Cfee2000/twilio-proxy-admin-app