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

Slack应用调用Confluence API搜索无响应问题求助

Slack应用无法获取Confluence搜索结果的排查与修复

核心问题分析

  • Confluence API授权方式错误:Confluence Cloud API不支持Bearer令牌,必须使用Basic认证(邮箱+API Token做Base64编码)。
  • Slack令牌验证逻辑错误:Slack交互式请求的验证令牌不是APP Token,应使用对应命令/交互组件的Verification Token(或启用更安全的请求签名验证)。
  • 缺少响应状态检查:未处理Confluence API返回的非200状态(如401未授权),导致无法定位授权失败问题。
  • 冗余的Slack Response URL授权:Slack的response_url本身已包含授权信息,额外添加Authorization头反而可能导致请求失败。
  • 日志信息不足:未打印Confluence API的响应状态和原始返回内容,难以排查请求失败原因。

修复步骤与代码修改

1. 修正Confluence API认证方式

将Bearer授权改为Basic认证:

  • 把你的Confluence邮箱和API Token用冒号拼接(格式:你的邮箱:你的API Token)
  • 对拼接后的字符串进行Base64编码
  • 将Authorization头替换为Basic <base64编码字符串>

2. 修正Slack令牌验证

在Slack控制台中找到对应命令的Verification Token,替换代码中的验证逻辑(若需更高安全性,可改用Slack请求签名验证)。

3. 添加响应状态检查与详细日志

在Confluence请求回调中增加状态码判断,并打印关键调试信息。

4. 移除Slack Response URL的Authorization头

直接使用response_url发送消息,无需额外授权头。

修改后的完整代码

const express = require("express");
const bodyParser = require("body-parser");
const request = require("request");
const { SLACK_VERIFICATION_TOKEN, CONFLUENCE_EMAIL, CONFLUENCE_API_TOKEN } = process.env;

const app = express();
app.use(bodyParser.json());

// 生成Confluence Basic认证头
const confluenceAuth = Buffer.from(`${CONFLUENCE_EMAIL}:${CONFLUENCE_API_TOKEN}`).toString('base64');

app.post("/slack/interactive-endpoint", (req, res) => {
  // 验证Slack请求合法性
  if (!req.body.token || req.body.token !== SLACK_VERIFICATION_TOKEN) {
    console.log("未授权的Slack请求");
    res.status(401).send("Unauthorized");
    return;
  }

  try {
    // 获取用户查询内容(若为其他交互类型,需调整字段路径)
    const question = req.body.text?.trim();
    if (!question) {
      request.post({
        url: req.body.response_url,
        json: { text: "请输入要搜索的内容" }
      }, () => res.status(200).end());
      return;
    }

    const options = {
      url: "https://cardknox.atlassian.net/wiki/rest/api/content/search",
      headers: {
        Authorization: `Basic ${confluenceAuth}`,
        "Content-Type": "application/json",
      },
      qs: {
        spaceKey: "TST",
        expand: "body.storage",
        query: question,
      },
    };

    request.get(options, (error, response, body) => {
      if (error) {
        console.error("Confluence请求错误:", error);
        request.post({
          url: req.body.response_url,
          json: { text: "搜索服务暂时不可用,请稍后重试" }
        }, () => res.status(500).end());
        return;
      }

      // 打印调试信息,便于排查问题
      console.log("Confluence响应状态码:", response.statusCode);
      console.log("Confluence原始响应内容:", body);

      if (response.statusCode !== 200) {
        console.error("Confluence API请求失败,状态码:", response.statusCode);
        request.post({
          url: req.body.response_url,
          json: { text: `搜索失败,错误码: ${response.statusCode}` }
        }, () => res.status(500).end());
        return;
      }

      let data;
      try {
        data = JSON.parse(body);
      } catch (parseErr) {
        console.error("Confluence响应解析错误:", parseErr);
        request.post({
          url: req.body.response_url,
          json: { text: "搜索结果解析失败,请稍后重试" }
        }, () => res.status(500).end());
        return;
      }

      if (data.results.length > 0) {
        // 移除HTML标签,提取纯文本内容
        const answers = data.results.map(result => 
          result.body.storage.value.replace(/<[^>]+>/g, '')
        );
        request.post({
          url: req.body.response_url,
          json: { text: answers.join("\n\n---\n\n") }
        }, () => res.status(200).end());
      } else {
        request.post({
          url: req.body.response_url,
          json: { text: "未找到匹配的内容,可尝试调整搜索关键词或联系管理员" }
        }, () => res.status(200).end());
      }
    });
  } catch (err) {
    console.error("服务器内部错误:", err);
    request.post({
      url: req.body.response_url,
      json: { text: "服务器内部错误,请稍后重试" }
    }, () => res.status(500).end());
  }
});

app.listen(3000, () => {
  console.log("Server listening on port 3000!");
});

额外排查建议

  1. 验证环境变量:确认Glitch中已正确设置SLACK_VERIFICATION_TOKEN、CONFLUENCE_EMAIL、CONFLUENCE_API_TOKEN,无拼写错误。
  2. 单独测试Confluence API:用Postman等工具直接调用Confluence搜索接口,验证认证和搜索功能是否正常。
  3. 检查Slack请求结构:打印req.body完整内容,确认text字段是否正确获取用户输入(若为其他交互类型,输入字段路径可能不同)。
  4. 查看Glitch日志:在Glitch控制台查看服务器日志,确认请求是否到达、是否有错误信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:50:39