使用来自 Firebase Cloud Functions 的 Slack 的 API dialog_open
Using Slack's API dialog_open from Firebase Cloud Functions
目标
一个 Slack 事件订阅事件正在命中我的 Firebase 端点,然后 Firebase 云函数正在使用 dialog_open
端点在 Slack 中打开一个对话框,其中包含来自 Firebase 的一些值。
问题
当 Firebase Cloud 函数访问 Slack 的 dialog_open
端点时,我在控制台日志中收到错误。
我得到 body: { ok: false, error: 'trigger_expired' }
但是,Firebase 中的日志显示往返时间少于 500 毫秒。但是,我没有看到将从第一个请求记录到 trigger_id 的触发器 ID(请参见下面的代码)。
4:57:12.443 PM | info | helloWorld | body: { ok: false, error: 'trigger_expired' }
4:57:04.163 PM | outlined_flag | helloWorld | Function execution took 254 ms, finished with status code: 200
4:57:03.910 PM | outlined_flag | helloWorld | Function execution started
当我在新部署后第二次、第三次或第四次触发 Slack 事件时,我得到 body: { ok: false, error: 'invalid_trigger' }
5:31:29.757 PM helloWorld body: { ok: false, error: 'invalid_trigger' }
5:31:28.744 PM helloWorld Function execution took 9 ms, finished with status code: 200
5:31:28.740 PM helloWorld json.trigger_id: "405615464868.7467239747.e706f2732257c541c445ad3938a29fd3"
5:31:28.735 PM helloWorld Function execution started
这也发生得足够快(9 毫秒),但触发错误不同,这次我确实 从 Slack 事件订阅事件中看到了 json.trigger_id
。
最后一件事,我试过了 JSON.stringify:
trigger_id: JSON.stringify(json.trigger_id),
现在日志和错误不同了:
5:33:24.512 PM | info | helloWorld | body: { ok: false, error: 'internal_error' }
5:33:23.565 PM | outlined_flag | helloWorld | Function execution took 13 ms, finished with status code: 200
5:33:23.559 PM | info | helloWorld | json.trigger_id: "406895248231.7467239747.7490e460213b3d65a44eef9f2e30c168"
5:33:23.553 PM | outlined_flag | helloWorld | Function execution started
问题
我一定是在做蠢事。猜猜我的 trigger_id
有什么问题?
代码
这是 Firebase 云函数:
import * as rp from "request-promise";
import * as functions from "firebase-functions";
export const helloWorld = functions.https.onRequest((request, response) => {
return new Promise((_resolve, _reject) => {
let json = JSON.parse(request.body.payload);
console.log("json.trigger_id:", json.trigger_id);
const options = {
method: "POST",
uri: "https://slack.com/api/dialog.open",
body: {
trigger_id: json.trigger_id,
dialog: {
callback_id: json.callback_id,
title: "Request a Ride",
submit_label: "Request",
elements: [
{ type: "text", label: "Pickup Location", name: "loc_origin" },
{ type: "text", label: "Dropoff Location", name: "loc_destination" }
]
}
},
json: true,
headers: {
"Content-type": "application/json; charset=utf-8",
Authorization:
"Bearer xoxp-secret"
}
};
rp(options)
.then(function(body) {
console.log("body:", body);
})
.catch(function(err) {
console.log("err:", err);
});
return response.status(200).json({ message: "Hello from Firebase" });
}).catch(err => response.status(500).send(err));
});
回答
违背承诺:在我的示例中,承诺是错误的。
消息与对话框:对话框不需要也不适合此目标。
Code Smell:web.chat.postMessage
不需要 发回消息。可以使用 Firebase Cloud Function 的 res
.
将消息发送回 Slack
这是一个改进的例子。
...
exports.eventsSlackBot = functions.https.onRequest((req, res) => {
return new Promise((resolve, reject) => {
// asyc things happening
})
.then(() => {
resolve.status(200).send({
"text": "I am a test message http://slack.com",
"attachments": [{
"text": "And here’s an attachment!"
}]
});
})
.catch(console.error);
});
...
目标
一个 Slack 事件订阅事件正在命中我的 Firebase 端点,然后 Firebase 云函数正在使用 dialog_open
端点在 Slack 中打开一个对话框,其中包含来自 Firebase 的一些值。
问题
当 Firebase Cloud 函数访问 Slack 的 dialog_open
端点时,我在控制台日志中收到错误。
我得到 body: { ok: false, error: 'trigger_expired' }
但是,Firebase 中的日志显示往返时间少于 500 毫秒。但是,我没有看到将从第一个请求记录到 trigger_id 的触发器 ID(请参见下面的代码)。
4:57:12.443 PM | info | helloWorld | body: { ok: false, error: 'trigger_expired' }
4:57:04.163 PM | outlined_flag | helloWorld | Function execution took 254 ms, finished with status code: 200
4:57:03.910 PM | outlined_flag | helloWorld | Function execution started
当我在新部署后第二次、第三次或第四次触发 Slack 事件时,我得到 body: { ok: false, error: 'invalid_trigger' }
5:31:29.757 PM helloWorld body: { ok: false, error: 'invalid_trigger' }
5:31:28.744 PM helloWorld Function execution took 9 ms, finished with status code: 200
5:31:28.740 PM helloWorld json.trigger_id: "405615464868.7467239747.e706f2732257c541c445ad3938a29fd3"
5:31:28.735 PM helloWorld Function execution started
这也发生得足够快(9 毫秒),但触发错误不同,这次我确实 从 Slack 事件订阅事件中看到了 json.trigger_id
。
最后一件事,我试过了 JSON.stringify:
trigger_id: JSON.stringify(json.trigger_id),
现在日志和错误不同了:
5:33:24.512 PM | info | helloWorld | body: { ok: false, error: 'internal_error' }
5:33:23.565 PM | outlined_flag | helloWorld | Function execution took 13 ms, finished with status code: 200
5:33:23.559 PM | info | helloWorld | json.trigger_id: "406895248231.7467239747.7490e460213b3d65a44eef9f2e30c168"
5:33:23.553 PM | outlined_flag | helloWorld | Function execution started
问题
我一定是在做蠢事。猜猜我的 trigger_id
有什么问题?
代码
这是 Firebase 云函数:
import * as rp from "request-promise";
import * as functions from "firebase-functions";
export const helloWorld = functions.https.onRequest((request, response) => {
return new Promise((_resolve, _reject) => {
let json = JSON.parse(request.body.payload);
console.log("json.trigger_id:", json.trigger_id);
const options = {
method: "POST",
uri: "https://slack.com/api/dialog.open",
body: {
trigger_id: json.trigger_id,
dialog: {
callback_id: json.callback_id,
title: "Request a Ride",
submit_label: "Request",
elements: [
{ type: "text", label: "Pickup Location", name: "loc_origin" },
{ type: "text", label: "Dropoff Location", name: "loc_destination" }
]
}
},
json: true,
headers: {
"Content-type": "application/json; charset=utf-8",
Authorization:
"Bearer xoxp-secret"
}
};
rp(options)
.then(function(body) {
console.log("body:", body);
})
.catch(function(err) {
console.log("err:", err);
});
return response.status(200).json({ message: "Hello from Firebase" });
}).catch(err => response.status(500).send(err));
});
回答
违背承诺:在我的示例中,承诺是错误的。
消息与对话框:对话框不需要也不适合此目标。
Code Smell:web.chat.postMessage
不需要 发回消息。可以使用 Firebase Cloud Function 的 res
.
这是一个改进的例子。
...
exports.eventsSlackBot = functions.https.onRequest((req, res) => {
return new Promise((resolve, reject) => {
// asyc things happening
})
.then(() => {
resolve.status(200).send({
"text": "I am a test message http://slack.com",
"attachments": [{
"text": "And here’s an attachment!"
}]
});
})
.catch(console.error);
});
...