I ended up solving it after some toil. Posting below for anyone that wants a function to resume triggers after pausing their clusters.
exports = async function(username, apiKey, groupId, appId) {
//Get a bearer token
const arg1 = {
url: 'https://realm.mongodb.com/api/admin/v3.0/auth/providers/mongodb-cloud/login',
headers: {"Content-Type": ["application/json"]},
body: '{"username": "' + username + '", "apiKey": "' + apiKey + '"}'
};
var response1 = await context.http.post(arg1);
if(response1.statusCode != "200")
return 'Auth failed with response: ' + response1.status;
// The response body is a BSON.Binary object. Parse it and get bearer token.
var bearerToken = EJSON.parse(response1.body.text()).access_token;
//First, get a list of triggers. We are going to assume that if they are erroring, we need to resume them as this function will be run directly after the cluster is resumed.
const arg2 = {
url: 'https://realm.mongodb.com/api/admin/v3.0/groups/' + groupId + '/apps/' + appId + '/triggers',
headers: {"Authorization": ["Bearer " + bearerToken + ""]},
digestAuth: false
};
var response2 = await context.http.get(arg2);
if(response2.statusCode != "200")
return 'Failed to get list of triggers with response: ' + response2.status;
var jsonResponse2 = EJSON.parse(response2.body.text());
//var arr = EJSON.stringify(response2.body.text());
//Loop the triggers looking for a specific error which occurs when the cluster is paused
for (var i = 0; i < jsonResponse2.length; i++){
if (jsonResponse2[i].hasOwnProperty("error") && jsonResponse2[i].error == "cannot open a changestream against a paused cluster")
{
var arg3 = {
url: 'https://realm.mongodb.com/api/admin/v3.0/groups/' + groupId + '/apps/' + appId + '/triggers/' + jsonResponse2[i]._id + '/resume',
headers: {"Content-Type": ["application/json"], "Authorization": ["Bearer " + bearerToken + ""]},
body: '{ "disable_token": false }'
};
var response3 = await context.http.put(arg3);
if(response3.statusCode != "204")
return 'Failed to resume trigger ' + jsonResponse2[i].name + ': ' + response3.status;
else
console.log('Trigger resume request for ' + jsonResponse2[i].name + ' sent successfully!') //Does not mean it resumed though if no resume token was available!
}
}
//Now check again for any that could not be resumed as it can't get a resume token
var response4 = await context.http.get(arg2);
if(response4.statusCode != "200")
return 'Failed to get list of triggers with response: ' + response4.status;
var jsonResponse4 = EJSON.parse(response4.body.text());
for (var j = 0; j < jsonResponse4.length; j++){
if (jsonResponse4[j].hasOwnProperty("error") && jsonResponse4[j].error == "(ChangeStreamHistoryLost) PlanExecutor error during aggregation :: caused by :: Resume of change stream was not possible, as the resume point may no longer be in the oplog.")
{
var arg4 = {
url: 'https://realm.mongodb.com/api/admin/v3.0/groups/' + groupId + '/apps/' + appId + '/triggers/' + jsonResponse4[j]._id + '/resume',
headers: {"Content-Type": ["application/json"], "Authorization": ["Bearer " + bearerToken + ""]},
body: '{ "disable_token": true }'
};
var response5 = await context.http.put(arg4);
if(response5.statusCode != "204")
return 'Failed to resume trigger ' + jsonResponse4[j].name + ': ' + response5.status;
else
console.log('Trigger resume request for ' + jsonResponse4[j].name + ' sent successfully! (without resume token)');
}
}
return true;
};