You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

迁移Firebase至Secret Manager后Slack/Bolt初始化报错的解决方法

问题

我们通过Firebase结合Slack/bolt开发机器人,此前用functions.config()管理Slack令牌和密钥,现在计划迁移至Secret Manager。改写后的代码如下:

// boltapp.js
const functions = require("firebase-functions");
const { App, ExpressReceiver, subtype } = require("@slack/bolt");
const config = functions.config();
const expressReceiver = new ExpressReceiver({
    signingSecret: process.env.SLACK_SECRET,
    endpoints: "/events",
    processBeforeResponse: true,
});

const app = new App({
    receiver: expressReceiver,
    token: process.env.SLACK_TOKEN
});
app.error(error => { console.error(error) });

app.use(async ({ client, payload, context, next }) => {
    console.info('It\'s payload', JSON.stringify(payload))
    if (!context?.retryNum) {
        await next();
    } else {
        console.debug('app.use.context', context);
    }
});

//**bot processing**//

// https://{your domain}.cloudfunctions.net/slack/events
module.exports = functions
    .runWith({ secrets: ["SLACK_TOKEN","SLACK_SECRET"] })
    .https.onRequest(expressReceiver.app);

迁移后出现以下报错:

Failed to load function definition from source: FirebaseError: Failed to load function definition from source: Failed to generate manifest from function source: Error: Apps used in a single workspace can be initialized with a token. Apps used in many workspaces should be initialized with oauth installer options or authorize.

Since you have not provided a token or authorize, you might be missing one or more required oauth installer options. See https://slack.dev/bolt-js/concepts#authenticating-oauth for these required fields.

请问如何修改代码以避免该错误?

解决方案

错误核心是函数初始化阶段,process.env.SLACK_TOKEN还未被Secret Manager注入,导致Bolt检测到令牌为undefined,误判你要构建多工作区应用。以下两种方法可修复:

方法一:延迟初始化Bolt App

将App的初始化逻辑放到请求处理流程中,确保环境变量已加载完成:

// boltapp.js
const functions = require("firebase-functions");
const { App, ExpressReceiver } = require("@slack/bolt");

const expressReceiver = new ExpressReceiver({
    signingSecret: process.env.SLACK_SECRET,
    endpoints: "/events",
    processBeforeResponse: true,
});

// 动态初始化Bolt App
expressReceiver.router.use(async (req, res, next) => {
    if (!req.app.locals.boltApp) {
        req.app.locals.boltApp = new App({
            receiver: expressReceiver,
            token: process.env.SLACK_TOKEN
        });

        // 挂载中间件与错误处理
        req.app.locals.boltApp.error(error => { console.error(error) });
        req.app.locals.boltApp.use(async ({ payload, context, next }) => {
            console.info('It\'s payload', JSON.stringify(payload))
            if (!context?.retryNum) {
                await next();
            } else {
                console.debug('app.use.context', context);
            }
        });

        // 在这里添加你的bot业务处理逻辑
        // req.app.locals.boltApp.command('/your-command', async ({ command, ack }) => { ... });
    }
    next();
});

module.exports = functions
    .runWith({ secrets: ["SLACK_TOKEN","SLACK_SECRET"] })
    .https.onRequest(expressReceiver.app);

方法二:提前验证环境变量

在初始化App前主动检查令牌和密钥是否存在,避免Bolt误判:

// boltapp.js
const functions = require("firebase-functions");
const { App, ExpressReceiver } = require("@slack/bolt");

// 提前校验环境变量
const slackToken = process.env.SLACK_TOKEN;
const slackSecret = process.env.SLACK_SECRET;

if (!slackToken || !slackSecret) {
    throw new Error("SLACK_TOKEN或SLACK_SECRET未从Secret Manager正确加载");
}

const expressReceiver = new ExpressReceiver({
    signingSecret: slackSecret,
    endpoints: "/events",
    processBeforeResponse: true,
});

const app = new App({
    receiver: expressReceiver,
    token: slackToken
});

app.error(error => { console.error(error) });
app.use(async ({ payload, context, next }) => {
    console.info('It\'s payload', JSON.stringify(payload))
    if (!context?.retryNum) {
        await next();
    } else {
        console.debug('app.use.context', context);
    }
});

// 添加你的bot业务处理逻辑

module.exports = functions
    .runWith({ secrets: ["SLACK_TOKEN","SLACK_SECRET"] })
    .https.onRequest(expressReceiver.app);

额外注意:需确保Firebase控制台的Secret Manager中已正确创建SLACK_TOKEN和SLACK_SECRET密钥,且函数拥有访问这些密钥的权限。

内容的提问来源于stack exchange,提问作者go600

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 02:55:16