Используйте пакет @slack/interactive-message с firebase-functions для прослушивания сообщений и диалогов Slack и ответа на них.
Я не уверен, как использовать слушателя @slack/interactive-message с firebase.
1) Могу ли я использовать functions.https.onRequest() Firebase, а как-то передать req из Slack в slackInteractions.action()?
ИЛИ
2) Использовать ли app.use("/app", slackInteractions.expressMiddleware()); Если да, то где же slackInteractions.action()s идти?
ИЛИ
3) Что-то еще?
// Express
import express = require("express");
const app = express();
const cors = require("cors")({
origin: "*"
});
app.use("*", cors);
// Firebase Functions SDK
import functions = require("firebase-functions");
const slackbotConfig = functions.config().slackbot;
const { createMessageAdapter } = require("@slack/interactive-messages");
const slackInteractions = createMessageAdapter(slackbotConfig.signing_secret);
app.use("/app", slackInteractions.expressMiddleware());
// Express route
app.post("/go", (req, res) => {
console.info("Hello from Express!");
res
.status(200)
.send("Hello from Express!")
.end();
});
exports.app = functions.https.onRequest(app);
exports.helloWorld = functions.https.onRequest((_req, res) => {
console.info("Hello from Firebase!");
res
.status(200)
.send("Hello from Firebase!")
.end();
});
Я новичок в деталях Express и использовании промежуточного программного обеспечения. Примеры шоу @slack/interactive-message ...
slackInteractions.start(port).then(() => {
console.info(`server listening on port ${port}`);
});
... а с функциями Firebase Cloud этот бит не имеет значения. Я не уверен, как слушатели, запросы и ответы интегрированы между Firebase и @ slack / interactive-message.

создатель @slack/interactive-messages здесь ?
Короче, ваше решение номер 2 мне кажется правильным. Хотя у меня нет опыта работы с функциями Firebase, я довольно хорошо разбираюсь в выражении, и я предоставлю некоторые дополнительные сведения.
Что такое промежуточное ПО Express?
Промежуточное ПО Express - это название функции, которая обрабатывает входящий HTTP-запрос. Все функции промежуточного программного обеспечения могут, на основе запроса за запросом, выбрать предварительную обработку запроса (обычно путем добавления свойства к аргументу req), ответ на запрос или постобработку запроса (например, вычисление времени между запрос и ответ). Он может выполнять одно или несколько из этих действий, в зависимости от того, чего он пытается достичь. Экспресс-приложение управляет стеком промежуточного программного обеспечения. Вы можете думать об этом как о списке шагов, которые может выполнить запрос, прежде чем будет готов ответ. Каждый шаг в этом списке может решить предложить ответ, так что следующий шаг даже не достигнут для этого запроса.
Значение cors в вашем примере кода является функцией промежуточного программного обеспечения. Он применяет некоторые правила о том, от каких источников ваша функция Firebase должна принимать запросы. Он применяет эти правила к входящим запросам, и если источник не разрешен, он сразу же ответит с ошибкой. В противном случае он позволяет обработать запрос следующему промежуточному программному обеспечению в стеке.
В вашем примере есть еще одно промежуточное программное обеспечение, и это маршрутизатор. Маршрутизатор - это просто своего рода промежуточное программное обеспечение, которое знает, как разделить приложение на отдельные обработчики на основе пути (части URL-адреса) во входящем запросе. Каждый экспресс app поставляется со встроенным маршрутизатором, и вы прикрепили к нему обработчик, используя строку кода app.post("/go", () => {}); в вашем примере. Маршрутизаторы обычно последнее промежуточное ПО в стеке. У них действительно есть особенность, которую люди часто не осознают. Что это за обработчики для маршрутов? Они просто больше функций промежуточного программного обеспечения. Таким образом, вы можете думать о маршрутизаторах как о промежуточном программном обеспечении, которое помогает разделить поведение приложения в зависимости от пути запроса.
Что это значит для slackInteractions?
Вы можете думать об объекте slackInteractions в своем коде как о маршрутизаторе, который всегда обрабатывает запрос - он никогда не передает запрос следующему промежуточному программному обеспечению в стеке. Ключевое отличие состоит в том, что вместо того, чтобы разделять поведение приложения по пути запроса, оно разделяет поведение с использованием различных свойств взаимодействия со Slack. Вы опишите, какие именно свойства вас интересуют, передав ограничения к методу .action(). Единственное существенное различие между типичным маршрутизатором и slackInteractions заключается в том, что само значение не является промежуточным программным обеспечением экспресс-обработки, вы создаете промежуточное программное обеспечение экспресс-обработки, вызывая метод .expressMiddleware(). Он разделен таким образом, чтобы он также мог работать вне экспресс-приложения (в этом случае вы можете использовать метод .start()).
Собираем все вместе
Как я уже сказал, у меня нет особого опыта работы с функциями Firebase, но вот с чего, я считаю, вам следует начать как минимум для функции, которая обрабатывает только взаимодействия со Slack.
// Firebase Functions SDK
import functions = require("firebase-functions");
const slackbotConfig = functions.config().slackbot;
// Slack Interactive Messages Adapter
const { createMessageAdapter } = require("@slack/interactive-messages");
const slackInteractions = createMessageAdapter(slackbotConfig.signing_secret);
// Action handlers
slackInteractions.action('welcome_agree_button', (payload, respond) => {
// `payload` is an object that describes the interaction
console.info(`The user ${payload.user.name} in team ${payload.team.domain} pressed a button`);
// Your app does some asynchronous work using information in the payload
setTimeout(() => {
respond({ text: 'Thanks for accepting the code of conduct for our workspace' });
}, 0)
// Before the work completes, return a message object that is the same as the original but with
// the interactive elements removed.
const reply = payload.original_message;
delete reply.attachments[0].actions;
return reply;
});
// Express
import express = require("express");
const app = express();
app.use("/", slackInteractions.expressMiddleware());
exports.slackActions = functions.https.onRequest(app);
@Chadd, не могли бы вы закомментировать некоторые строки, чтобы мы могли исключить некоторые возможности? Я бы начал с комментария к setTimeout(...) (чтобы respond() никогда не вызывали). если он работает без этих строк, значит, мы знаем, что ошибка клиента заключается в попытке отправить запрос к response_url, и можем продолжить отладку.
Привет, @Chadd, у тебя это когда-нибудь срабатывало? Думаю, мне стоит пойти в том же направлении.
Я не нашел хорошего способа использовать для этого функции Firebase. Самой большой проблемой был быстрый тайм-аут Slack, а время разогрева функций firebase не очень хорошо сочетается друг с другом.
Этот пример развертывается в Firebase, и Slack достигает конечной точки. Однако в приложении Slack и в журналах Firebase я все еще получаю
404_client_error. Есть догадки, что еще нужно Slack для аутентификации ответа от Firebase?