跳转到内容

从 Slack bot 迁移到 Hashee

如果你已经有 Slack bot,本教程帮你完整迁移到 Hashee:API 映射、UI 元素 对照、消息事件改造、配置项变更。

一句话差异

维度SlackHashee
消息内容平台可见✗(盲管道 E2EE)
Bot 身份App + Bot User TokenAgent (agent_id + agent_token)
连接Socket Mode / Events APIWebSocket / Webhook
富 UIBlock KitArtifact(subtype 列表)
命令Slash commands任意文本 + 业务侧解析(V2 会有 commands API)
@mention<@U12345>@<U:user_id> + mentions 数组
互动Block actions (button_click)artifact_response(含 action 字段)
工作区概念Workspace无(用户全局账号)
信任模型App owner 信任 SlackAgent 用户撤销关系即清理

API 字段映射

接收消息

Slack: app.message(async ({ message, say }) => { say(`hi <@${message.user}>`); });
Hashee: agent.addMessageHandler(async (msg) => {
if (msg.payload?.type !== "text") return;
await agent.send(msg.conversation_id, {
type: "text", text: `hi @<U:${msg.sender_id}>`, mentions: [msg.sender_id],
});
});

命令

Slack: app.command("/poll", async ({ command, ack, say }) => { ... });
Hashee: agent.addMessageHandler(async (msg) => {
if (msg.payload?.text?.startsWith("/poll")) { ... }
});

Block Kit → Artifact

Slack Block Kit:
{
blocks: [
{ type: "section", text: { type: "mrkdwn", text: "*Hello*" } },
{ type: "actions", elements: [
{ type: "button", text: { type: "plain_text", text: "Click" }, action_id: "click" }
]}
]
}
Hashee Artifact:
agent.sendArtifact(convId, {
artifact: {
subtype: "info",
title: "Hello",
payload: {
body: "**Hello**",
actions: [{ id: "click", label: "Click" }],
},
},
});

Button → artifact_response

Slack: app.action("click", async ({ ack, body }) => { ... });
Hashee: agent.addEventHandler(async (event) => {
if (event.type === "artifact_response" && event.payload.action === "click") {
// event.payload.payload 是用户的回流 data
}
});

Slack 文件 → Hashee 文件

Slack: files.upload({ channels, file, filename });
Hashee: agent.uploadFile(conversationId, {
filename, mime, data: fileBuffer,
});

完整迁移示例

把 Slack 的 /echo + button 改成 Hashee:

原 Slack 版本(Bolt SDK)

import { App } from "@slack/bolt";
const app = new App({ token, signingSecret, socketMode: true, appToken });
app.command("/echo", async ({ command, ack, say }) => {
await ack();
await say({
blocks: [
{ type: "section", text: { type: "mrkdwn", text: `Echo: ${command.text}` } },
{ type: "actions", elements: [{ type: "button", text: { type: "plain_text", text: "再说一次" }, action_id: "again", value: command.text }] },
],
});
});
app.action("again", async ({ ack, body, say }) => {
await ack();
await say(`再次 Echo: ${(body as any).actions[0].value}`);
});
await app.start();

Hashee 版本

import { HasheeAgent } from "@hasheeai/agent-sdk-ts";
import { ulid } from "ulid";
const agent = await HasheeAgent.init({
agentId: process.env.HASHEE_AGENT_ID!,
token: process.env.HASHEE_AGENT_TOKEN!,
baseUrl: "https://api.hashee.ai",
connectionMode: "websocket",
});
// 业务侧记录每个 artifact 关联的"原始 echo 文本"
const echoStore = new Map<string, string>();
agent.addMessageHandler(async (msg) => {
if (msg.payload?.type !== "text") return;
const m = msg.payload.text.match(/^\/echo\s+(.+)$/);
if (!m) return;
const text = m[1];
const artifactId = ulid();
echoStore.set(artifactId, text);
await agent.sendArtifact(msg.conversation_id, {
artifact: {
artifact_id: artifactId,
subtype: "info",
title: "Echo",
payload: {
body: `Echo: ${text}`,
actions: [{ id: "again", label: "再说一次", action: "again" }],
},
},
});
});
agent.addEventHandler(async (event) => {
if (event.type !== "artifact_response") return;
if (event.payload.action !== "again") return;
const original = echoStore.get(event.payload.ref_artifact);
if (!original) return;
await agent.send(event.payload.conversation_id, {
type: "text", text: `再次 Echo: ${original}`,
});
});
agent.addStatusHandler((s) => console.log(`[status] ${s}`));
console.log("[migrated-echo] up");

配置项迁移

SlackHashee
SLACK_BOT_TOKEN (xoxb-…)HASHEE_AGENT_TOKEN (hsk_…)
SLACK_SIGNING_SECRETHASHEE_WEBHOOK_SECRET(webhook 模式)
SLACK_APP_TOKEN (Socket Mode)n/a (WebSocket 自动处理)
OAuth scopes (chat:write / channels:history)Capability Manifest + Permission Scopes(notification:send 等)
events_url(HTTP Events Mode)webhook_url
Workspace 安装用户主动添加 Agent

部署对比

SlackHashee
Slack App + OAuth flowAgent 创建 + Token 一次性显示
Render / Heroku 跑 Bolt + Socket ModeVPS / 容器跑 WebSocket Agent
Vercel / Lambda + Events ModeCloudflare Workers / Vercel Edge + Webhook

详见 部署到 Cloudflare Workers / 自托管 VPS

你可能会怀念的(V1 暂无)

  • OAuth distribute:V2 marketplace 会有”安装到我的 workspace”流程;V1 是每个用户自己加 Agent
  • App Directory 上架:V2 marketplace
  • Slash commands 注册中心:V1 让 Agent 自己解析消息文本;V2 commands API
  • Modal:用 Artifact form 替代(功能更强)
  • Home tab:V1 无对等概念;用主动推送的 artifact 模拟

你会得到的(Slack 没有)

  • 端到端加密:消息平台看不到
  • Tool Call with sensitivity:3 级权限同意机制
  • 数据撤销 + cleanup 事件relation.revoked 自动通知 cleanup
  • 多设备同步:用户切手机 / 桌面 / 平板无缝
  • Grant Ledger:每次 Agent 读用户数据有 append-only 审计

相关页面