Рекомендация песни дня
Locke и Key Soundtrack это 🔥. У меня было это повторить несколько недель после завершения шоу. Эта песня из Билтей Эйлиш является одной из основных моментов.
План
На моей последней сессии я настроил подписку на развертывание осьминога для развертывания, нуждающихся в одобрении. Подписка отправляет полезную нагрузку в функцию облака FireBase. Эта облачная функция использует API Twilio, чтобы написать мне о одобрении развертывания.
На этом сеансе я добавил еще несколько деталей для SMS, отправленных через Twilio. Я настроил ответы на сообщение для утверждения или отклонения развертывания с API Octopus. Я также реорганизовал код тоже.
Подробнее в исходном тексте
Полезная нагрузка подписки имеет свойство сообщения на мероприятии с таким текстом:
Deploy to Production requires manual intervention for blog.rousseau.dev release 0.0.8 to Production
Я добавил ссылку на экран развертывания и инструкции для того, как ответить.
// approvalRaised.js
function convertPayloadToMessage(payload) {
let message = payload.Event.Message;
let deploymentId = payload.Event.RelatedDocumentIds.find((id) => id.startsWith("Deployments-"));
let url = `${payload.ServerUri}/app#/deployments/${deploymentId}`;
return `${message}\n\nYou can view the deployment at ${url}\n\nReply with either 'Approve' or 'Reject' followed by notes.`;
}
exports.approvalRaised = functions.https.onRequest((req, res) => {
return octopus.authorizeRequest(req, res)
.then(octopus.getSubscriptionPayload)
.then(octwilio.saveApproval)
.then(convertPayloadToMessage)
.then(octwilio.sendTwilioMessage)
.then(() => { return res.status(200).send(); });
});
С помощью текста сообщения отсортирован, я обратил свое внимание на обработку ответов на оповещение.
Ах, да… Состояние
Облачные функции и SMS по своей природе нестандартны. Когда я отвечаю на это текстовое сообщение, Twilio не подключается к сообщению, которое было отправлено ранее.
Я должен отслеживать государство сам. FireBase имеет несколько вариантов базы данных, с которыми довольно легко начать. Я создал новую базу данных FireStore и обновил код для хранения полезной нагрузки.
// octwilio.js
exports.saveApproval = function (payload) {
return db.collection('approvals').doc(config.twilio.approval.to_number).set(payload)
.then(() => {
return payload;
});
};
// approvalRaised.js
exports.approvalRaised = functions.https.onRequest((req, res) => {
return octopus.authorizeRequest(req, res)
.then(octopus.getSubscriptionPayload)
.then(octwilio.saveApproval)
.then(convertPayloadToMessage)
.then(octwilio.sendTwilioMessage)
.then(() => { return res.status(200).send(); });
});
Когда появится сообщение, я получу полезную нагрузку от FireStore на основе номера, на котором есть сообщение.
// octwilio.js
exports.getApprovalRecord = function (from) {
return db.collection('approvals').doc(from).get().then((doc) => {
if (!doc.exists) {
console.log("Cannot find document for " + from);
} else {
approval = doc.data();
console.log(approval);
}
return approval;
})
};
У этого подхода есть недостаток. Он только хранит одну полезную нагрузку за номер. Таким образом, пользователь может ответить только на самое последнее одобрение. Это звучит как справедливое компромисс, чтобы иметь возможность одобрить или отклонить, отвечая на текст.
Отвечая на сообщения, отправленные в номер Twilio
Вы можете настроить номера Twilio для отправки полезной нагрузки данных в веб -ook, когда получает сообщение. Полезная нагрузка включает номер телефона отправителя и тело сообщения.
Я создал новую функцию имени ПроцессMessage Для обработки полезных нагрузок Twilio.
Если сообщение начинается с «Одобрения» или «Отклонить», «I обрабатываю одобрение. В противном случае я попрошу пользователя попробовать еще раз.
// processMessage.js
exports.processMessage = functions.https.onRequest((req, res) => {
let from = req.body.From;
let message = req.body.Body;
let action = null;
if (message.startsWith("Approve")) {
action = processApproval(from, "Proceed", message, "Deployment approved.");
} else if (message.startsWith("Reject")) {
action = processApproval(from, "Abort", message, "Deployment rejected.");
}
else {
action = octwilio.sendTwilioMessage("Sorry, I didn't understand that. Please try again.");
}
return action.then(() => { return res.status(200).send(); });
});
Процессобразование начинается, получая одобрение. Затем мы используем API Octopus, чтобы найти одобрение, взять на себя ответственность и отправить его. Наконец, мы удаляем одобрение из базы данных и отвечайте пользователю.
// processMessage.js
function processApproval(from, result, message, response) {
return octwilio.getApprovalRecord(from)
.then((approval) => { return createApprovalOptions(approval, result, message); })
.then(octopus.findInterruption)
.then(octopus.takeResponsibility)
.then(octopus.submitInterruption)
.then(() => { return octwilio.deleteApproval(from); })
.then(() => { return octwilio.sendTwilioMessage(response); });
}
Вызов Octopus развертывает API
Полезная нагрузка подписки имеет информацию, необходимую для создания целевых URL-адресов API. Мне нужен API ключ разрешить запросы. Я сохранил этот ключ в конфиге Firebase.
firebase functions:config:set octwilio.octopus.apikey="API-MYSECRETISSAFE"
Я использовал Запрос-обещание Чтобы сделать запросы API, но теперь он устарел. Мне придется найти замену для этого.
Радиоприпечатка Вызывает конечную точку API для поиска прерываний (в ожидании утверждений в этом случае) связано с задачей. Можно иметь более одного оказывающихся разрешений для каждого развертывания. Я в порядке с принятием одного одобрения за один раз для этого проекта.
// octopus.js
const rp = require('request-promise');
const octwilio = require('./octwilio');
let config = octwilio.config;
let headers = {
'X-Octopus-ApiKey': config.octopus.apikey
};
exports.findInterruption = function (options) {
let octopusUri = `${options.serverUri}\\api\\${options.spaceId}\\interruptions?regarding=${options.serverTaskId}`;
const requestOptions = {
method: 'GET',
uri: octopusUri,
json: true,
headers: headers
}
return rp(requestOptions).then((results) => {
console.log(results);
let interruption = results.Items[0];
options.interruption = interruption;
return options;
});
};
Тазаксимость Устанавливает пользователь, ответственный за одобрение владельцу токен API.
// octopus.js
exports.takeResponsibility = function (options) {
let interruption = options.interruption;
let octopusUri = `${options.serverUri}/api/${options.spaceId}/interruptions/${interruption.Id}/responsible`;
const requestOptions = {
method: 'PUT',
uri: octopusUri,
json: true,
headers: headers
}
return rp(requestOptions).then(() => {
return options;
});
};
Отправка одобряет или отклоняет развертывание и добавляет сообщение от пользователя в качестве примечаний для одобрения.
// octopus.js
exports.submitInterruption = function (options) {
let interruption = options.interruption;
let octopusUri = `${options.serverUri}/api/${options.spaceId}/interruptions/${interruption.Id}/submit`;
const requestOptions = {
method: 'POST',
uri: octopusUri,
json: true,
headers: headers,
body: {
Notes: options.message,
Result: options.result
}
}
return rp(requestOptions).then(() => {
return true;
});
};
Тестирование это
Теперь, когда у меня были все эти причудливые новые функции, пришло время дать ему правильный тестовый прогон. Я поставил в очередь новое развертывание в осьминоге.
Я получил текстовое сообщение с новыми деталями включенными.
Я ответил на Одобрить - выглядит хорошо для меня . Octwilio отправил подтверждение подтверждения, что развертывание было одобрено.
Я проверил страницу развертывания осьминога. Развертывание было одобрено, и я вижу мои комментарии в истории аудита.
В следующий раз
Я доволен Octwilio в своем нынешнем состоянии. Мне нужно заполнить readme и добавить некоторые инструкции для настройки его. Я покинул какую-то комнату в ПроцессMessage Принять другие команды через текст. Вероятно, это будет чище использовать отдельный номер телефона для этого. Я не думаю, что было бы слишком плохо для размещения нескольких команд с этим номером.
Обложка фото К. Митч Ходж на Бессмысленно .
Оригинал: «https://dev.to/octopus/reacting-to-messages-sent-to-twilio-1ppb»