为 Slack API 使用 Firebase onRequest() 或 Express app.use()
Use Firebase onRequest() or Express app.use() for the Slack API
目标
使用 @slack/interactive-message
包和 firebase-functions
来收听和响应 Slack 消息和对话。
问题
我不确定如何将 @slack/interactive-message
侦听器与 firebase 一起使用。
1) 我是否使用 Firebase 的 functions.https.onRequest()
,并且 以某种方式 将 req
从 Slack 传递到 slackInteractions.action()
?
或
2) 我是否使用 app.use("/app", slackInteractions.expressMiddleware());
如果是,slackInteractions.action()
s go 去哪里?
或
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.log("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.log("Hello from Firebase!");
res
.status(200)
.send("Hello from Firebase!")
.end();
});
tl;博士
我不熟悉 Express 的细节和使用中间件。 @slack/interactive-message
的示例显示...
slackInteractions.start(port).then(() => {
console.log(`server listening on port ${port}`);
});
...对于 Firebase Cloud Functions,此位不相关。我不确定 Firebase 和 @slack/interactive-message
之间的侦听器、请求和响应是如何集成的
@slack/interactive-messages
的创建者
简而言之,您的解决方案 2 对我来说似乎是正确的。虽然我没有使用 Firebase 函数的经验,但我对 express 有很好的理解,我会提供更多细节。
什么是快速中间件?
Express 中间件是一种处理传入 HTTP 请求的函数的名称。所有中间件功能都可以在逐个请求的基础上,选择预处理请求(通常通过在 req
参数中添加 属性),响应请求,或 post-处理一个请求(比如计算请求和响应之间的时间)。它可以做任何一件事情或这些事情的组合,这取决于它试图完成的事情。 Express 应用程序管理一堆中间件。您可以将其视为请求在响应准备好之前可能完成的步骤列表。该列表中的每个步骤都可以决定提供响应,以便该请求甚至不会到达下一步。
您的代码示例中的 cors
值是一个中间件函数。它应用了一些关于您的 Firebase 函数应该接受来自哪些来源的请求的规则。它将这些规则应用于传入请求,并且当不允许来源时,它将立即响应错误。否则,它允许请求由堆栈中的下一个中间件处理。
您的示例中还有另一个中间件,那就是路由器。路由器只是一种中间件,它知道如何根据传入请求中的路径(URL 的一部分)将应用程序拆分为单独的处理程序。每个 express app
都带有一个内置路由器,您在示例中使用 app.post("/go", () => {});
代码行将处理程序附加到它。路由器通常是堆栈中的最后一个中间件。它们确实具有人们通常没有意识到的特殊功能。这些路由处理程序是什么?它们只是更多的中间件功能。所以总的来说,您可以将路由器视为一种中间件,它可以帮助您根据请求的路径划分应用程序行为。
这对 slackInteractions
意味着什么?
您可以将代码中的 slackInteractions
对象视为 始终 处理请求的路由器 - 它从不将请求传递到堆栈中的下一个中间件.关键区别在于,它不是通过请求路径来划分应用程序行为,而是使用 Slack 交互的各种属性来划分行为。您 describe which properties exactly you care about by passing in constraints 到 .action()
方法。典型路由器与 slackInteractions
之间的唯一显着区别是值本身不是 express 中间件,您可以通过调用 .expressMiddleware()
方法生成一个 express 中间件。它像这样分开,因此它也可以在 express 应用程序之外工作(那时您可能会使用 .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.log(`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);
目标
使用 @slack/interactive-message
包和 firebase-functions
来收听和响应 Slack 消息和对话。
问题
我不确定如何将 @slack/interactive-message
侦听器与 firebase 一起使用。
1) 我是否使用 Firebase 的 functions.https.onRequest()
,并且 以某种方式 将 req
从 Slack 传递到 slackInteractions.action()
?
或
2) 我是否使用 app.use("/app", slackInteractions.expressMiddleware());
如果是,slackInteractions.action()
s go 去哪里?
或
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.log("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.log("Hello from Firebase!");
res
.status(200)
.send("Hello from Firebase!")
.end();
});
tl;博士
我不熟悉 Express 的细节和使用中间件。 @slack/interactive-message
的示例显示...
slackInteractions.start(port).then(() => {
console.log(`server listening on port ${port}`);
});
...对于 Firebase Cloud Functions,此位不相关。我不确定 Firebase 和 @slack/interactive-message
之间的侦听器、请求和响应是如何集成的@slack/interactive-messages
的创建者
简而言之,您的解决方案 2 对我来说似乎是正确的。虽然我没有使用 Firebase 函数的经验,但我对 express 有很好的理解,我会提供更多细节。
什么是快速中间件?
Express 中间件是一种处理传入 HTTP 请求的函数的名称。所有中间件功能都可以在逐个请求的基础上,选择预处理请求(通常通过在 req
参数中添加 属性),响应请求,或 post-处理一个请求(比如计算请求和响应之间的时间)。它可以做任何一件事情或这些事情的组合,这取决于它试图完成的事情。 Express 应用程序管理一堆中间件。您可以将其视为请求在响应准备好之前可能完成的步骤列表。该列表中的每个步骤都可以决定提供响应,以便该请求甚至不会到达下一步。
您的代码示例中的 cors
值是一个中间件函数。它应用了一些关于您的 Firebase 函数应该接受来自哪些来源的请求的规则。它将这些规则应用于传入请求,并且当不允许来源时,它将立即响应错误。否则,它允许请求由堆栈中的下一个中间件处理。
您的示例中还有另一个中间件,那就是路由器。路由器只是一种中间件,它知道如何根据传入请求中的路径(URL 的一部分)将应用程序拆分为单独的处理程序。每个 express app
都带有一个内置路由器,您在示例中使用 app.post("/go", () => {});
代码行将处理程序附加到它。路由器通常是堆栈中的最后一个中间件。它们确实具有人们通常没有意识到的特殊功能。这些路由处理程序是什么?它们只是更多的中间件功能。所以总的来说,您可以将路由器视为一种中间件,它可以帮助您根据请求的路径划分应用程序行为。
这对 slackInteractions
意味着什么?
您可以将代码中的 slackInteractions
对象视为 始终 处理请求的路由器 - 它从不将请求传递到堆栈中的下一个中间件.关键区别在于,它不是通过请求路径来划分应用程序行为,而是使用 Slack 交互的各种属性来划分行为。您 describe which properties exactly you care about by passing in constraints 到 .action()
方法。典型路由器与 slackInteractions
之间的唯一显着区别是值本身不是 express 中间件,您可以通过调用 .expressMiddleware()
方法生成一个 express 中间件。它像这样分开,因此它也可以在 express 应用程序之外工作(那时您可能会使用 .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.log(`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);