import { HasheeAgent } from "@hasheeai/agent-sdk-ts";
const agent = await HasheeAgent.init({
agentId: process.env.HASHEE_AGENT_ID!,
token: process.env.HASHEE_AGENT_TOKEN!,
baseUrl: "https://api.hashee.ai",
connectionMode: "websocket",
const MY_ID = process.env.HASHEE_AGENT_ID!;
agent.addMessageHandler(async (msg) => {
if (msg.payload?.type !== "text") return;
if (msg.conversation_type === "h2a") {
if (msg.conversation_type !== "group") return;
const myMentioned = msg.mentions?.includes(MY_ID);
const mentionAll = msg.mention_all;
if (!myMentioned && !mentionAll) return; // 不是 @ 我,忽略
const text = stripMention(msg.payload.text, MY_ID);
if (text.startsWith("/")) {
return handleCommand(msg, text);
if (/(私聊|私下|DM)/.test(text)) {
return moveToDM(msg, text);
return handleGroupQuestion(msg, text);
async function handleCommand(msg: any, text: string) {
const [cmd, ...args] = text.slice(1).split(/\s+/);
if (cmd === "set-rule") {
const isAdmin = await checkAdmin(msg.conversation_id, msg.sender_id);
await agent.send(msg.conversation_id, {
text: `@<U:${msg.sender_id}> 抱歉,只有群主 / 管理员能改群规则。`,
mentions: [msg.sender_id],
await setRule(msg.conversation_id, args.join(" "));
await agent.sendArtifact(msg.conversation_id, {
body: `- \`/help\` — 显示本帮助
- \`/vote 标题 选项1 选项2\` — 发起投票
- \`/set-rule <文本>\` — 设置群规则(仅 admin)`,
await agent.send(msg.conversation_id, {
text: `@<U:${msg.sender_id}> 不认识命令 \`/${cmd}\`,输入 \`@${MY_ID} /help\` 看用法`,
mentions: [msg.sender_id],
async function moveToDM(msg: any, text: string) {
await agent.send(msg.conversation_id, {
text: `@<U:${msg.sender_id}> 好的,我私聊给你。`,
mentions: [msg.sender_id],
// 2. 主动开 H2A 私聊(如果该 user 还没建立和我的 H2A 关系,需先等他加我为联系人)
// V1:找到该 user 与我的 H2A conversation_id(如已存在)
const dmConvId = await lookupOrCreateDmConv(msg.sender_id);
await agent.send(msg.conversation_id, {
text: `@<U:${msg.sender_id}> 你先在搜索栏添加我为联系人,我才能给你发私聊。`,
mentions: [msg.sender_id],
await agent.send(dmConvId, {
text: `刚才你在群里说"${text.slice(0, 100)}"——我们这里继续聊吧。`,
async function lookupOrCreateDmConv(userId: string): Promise<string | null> {
// 业务侧:从 relation.established 事件持久化 user_id → conversation_id 映射
// 不在则返回 null(user 没和你建 H2A)
return null; // 略:替换为真实查询
async function handleGroupQuestion(msg: any, text: string) {
await agent.typing(msg.conversation_id);
const reply = await callLLM(text);
await agent.send(msg.conversation_id, {
text: `@<U:${msg.sender_id}> ${reply}`,
mentions: [msg.sender_id],
async function handleDM(msg: any) {
const reply = await callLLM(msg.payload.text);
await agent.send(msg.conversation_id, { type: "text", text: reply });
function stripMention(text: string, agentId: string): string {
return text.replace(new RegExp(`@<U:${agentId}>\\s?`, "g"), "").trim();
async function checkAdmin(groupId: string, userId: string): Promise<boolean> {
// 业务侧:从 group.member_joined 事件 + role 字段持久化
async function setRule(groupId: string, rule: string) {
async function callLLM(text: string): Promise<string> {
agent.addStatusHandler((s) => console.log(`[status] ${s}`));
console.log("[group-router] up");