亚洲中文字幕乱码亚洲-蜜桃成熟视频在线观看-免费中文字幕视频在线-中国五十路熟妇洗澡视频-亚洲av伊人啪啪c-国产精品成人一区二区-国产自拍视频一区在线观看-成人一区不卡二区三区四区-亚洲情精品中文字幕99在线

網(wǎng)易首頁(yè) > 網(wǎng)易號(hào) > 正文 申請(qǐng)入駐

扒了下微信接 OpenClaw 的源碼,我做出了自己的機(jī)器人~

0
分享至


?前言

就在前天,微信官方終于推出了小龍蝦接入微信的插件「微信 ClawBot」:


那作為一個(gè)程序員,我就想了,微信能把小龍蝦接進(jìn)來(lái),那不就能把滿足協(xié)議要求的任何機(jī)器人接進(jìn)來(lái)了么?二開(kāi)一個(gè)官方支持的微信機(jī)器人不再是夢(mèng)想!


這篇文章就來(lái)講一下怎么根據(jù)微信官方支持的渠道,實(shí)現(xiàn)一個(gè)自己高度自定義的機(jī)器人,而不是局限于小龍蝦這個(gè)框架。

背景

根據(jù)官方的插件接入指南可以看到,微信機(jī)器人主要是靠一個(gè)叫@tencent-weixin/openclaw-weixin-cli的 npm 包:


那我們來(lái)到這個(gè)包在 npm 上的對(duì)應(yīng)頁(yè)面 https://www.npmjs.com/package/@tencent-weixin/openclaw-weixin-cli,可以看到有非常清晰的說(shuō)明:

從介紹里我們也能看到,這個(gè)包只是一個(gè)安裝程序,并沒(méi)有程序的實(shí)際內(nèi)容,實(shí)際的邏輯都在@tencent/openclaw-weixin里:


所以我們需要找到這個(gè)包對(duì)應(yīng)的 npm 頁(yè)面 https://www.npmjs.com/package/@tencent-weixin/openclaw-weixin,核心的內(nèi)容就是下圖中的這段話:


就是說(shuō),想把自己的程序接入到微信機(jī)器人里,只需要實(shí)現(xiàn)這5個(gè) Http 接口就好了。

接口

路徑

作用

getUpdates

ilink/bot/getupdates

長(zhǎng)輪詢拉取新消息

sendMessage

ilink/bot/sendmessage

發(fā)送消息給用戶

getUploadUrl

ilink/bot/getuploadurl

獲取媒體文件上傳地址

getConfig

ilink/bot/getconfig

獲取賬號(hào)配置

sendTyping

ilink/bot/sendtyping

發(fā)送「正在輸入」?fàn)顟B(tài)

文檔的旁邊還有源碼,這也是我們二開(kāi)的重要參考:


? 整體架構(gòu)

理清楚上面的背景之后,我們要做的這個(gè)項(xiàng)目的數(shù)據(jù)流向就非常清晰了:收消息 → 問(wèn) AI → 發(fā)回復(fù)。


核心實(shí)現(xiàn) 一、掃碼登錄

掃碼登錄是整個(gè)流程的第一步。微信的登錄協(xié)議是一個(gè)典型的「生成二維碼 → 輪詢狀態(tài) → 獲取 Token」流程:


首先通過(guò)get_bot_qrcode接口拿到二維碼:

async function fetchQRCode(): Promise {
const url = `${BASE_URL}/ilink/bot/get_bot_qrcode?bot_type=${BOT_TYPE}`;
const res = await fetch(url);
if (!res.ok) throw new Error(`獲取二維碼失敗: ${res.status}`);
return (await res.json()) as QRCodeResponse;
}

這里參考的是插件源碼中的src/auth/login-qr.ts文件:


然后用qrcode-terminal把二維碼渲染到終端里,用微信掃碼即可:


掃碼后,通過(guò)長(zhǎng)輪詢get_qrcode_status接口來(lái)追蹤狀態(tài)變化。這里的狀態(tài)機(jī)有四種狀態(tài):

  • wait—— 等待掃碼,繼續(xù)輪詢

  • scaned—— 用戶已掃碼,等待手機(jī)確認(rèn)

  • expired—— 二維碼過(guò)期,自動(dòng)刷新(最多 3 次)

  • confirmed—— 用戶確認(rèn),返回bot_tokenilink_bot_id

case "confirmed": {
if (!status.bot_token || !status.ilink_bot_id) {
thrownewError("登錄確認(rèn)但未返回 token 或 bot_id");
}
const creds: LoginCredentials = {
token: status.bot_token,
baseUrl: status.baseurl || BASE_URL,
accountId: status.ilink_bot_id,
userId: status.ilink_user_id,
};
saveCredentials(creds);
console.log(`[auth] ? 登錄成功! accountId=${creds.accountId}`);
return creds;
}

拿到憑證后保存到data/credentials.json,文件權(quán)限設(shè)為0o600(僅當(dāng)前用戶可讀寫(xiě))。下次啟動(dòng)時(shí)如果憑證還在,就跳過(guò)掃碼直接復(fù)用。

我們只需要點(diǎn)擊連接,就登錄成功可以對(duì)話啦:


二、微信 API 層

和微信通信的核心就是 HTTP POST,但有幾個(gè)協(xié)議細(xì)節(jié)需要注意。

1)每個(gè)請(qǐng)求都需要攜帶特定的 Header:

function buildHeaders(token?: string): Record {
const headers: Record = {
"Content-Type": "application/json",
AuthorizationType: "ilink_bot_token",
"X-WECHAT-UIN": randomWechatUin(),
};
if (token) {
headers.Authorization = `Bearer ${token}`;
}
return headers;
}

X-WECHAT-UIN是一個(gè)隨機(jī)的 uint32 經(jīng)過(guò) base64 編碼,每次請(qǐng)求都重新生成。AuthorizationType固定為ilink_bot_token

2)getUpdates 長(zhǎng)輪詢:

這是整個(gè)機(jī)器人的「耳朵」。它通過(guò)一個(gè)游標(biāo)get_updates_buf實(shí)現(xiàn)增量同步,服務(wù)端會(huì) hold 住請(qǐng)求直到有新消息或者超時(shí)(默認(rèn) 35 秒):

export asyncfunction getUpdates(
baseUrl: string,
token: string,
buf: string,
timeoutMs = DEFAULT_LONG_POLL_TIMEOUT_MS,
): Promise {
try {
returnawait apiPost (
baseUrl,
"ilink/bot/getupdates",
{ get_updates_buf: buf },
token,
timeoutMs,
);
} catch (err) {
if (err instanceofError && err.name === "AbortError") {
return { ret: 0, msgs: [], get_updates_buf: buf };
}
throw err;
}
}

注意這里對(duì)AbortError(超時(shí))的處理——長(zhǎng)輪詢超時(shí)是正常現(xiàn)象,直接返回空響應(yīng)讓調(diào)用方繼續(xù)下一輪即可。

3)sendMessage:

發(fā)消息需要構(gòu)造一個(gè)符合微信協(xié)議的WeixinMessage結(jié)構(gòu),里面的關(guān)鍵字段是context_token,這是微信用來(lái)標(biāo)識(shí)會(huì)話上下文的令牌,必須從收到的消息里提取出來(lái)回傳:

await apiPost(
baseUrl,
"ilink/bot/sendmessage",
{
msg: {
from_user_id: "",
to_user_id: to,
client_id: clientId,
message_type: MessageType.BOT,
message_state: MessageState.FINISH,
item_list: [{ type: MessageItemType.TEXT, text_item: { text } }],
context_token: contextToken,
},
},
token,
);
三、AI 對(duì)話層

AI 層使用 OpenAI SDK,但通過(guò)baseURL參數(shù)實(shí)現(xiàn)了對(duì)任意兼容接口的支持。所以不管你用 GPT、DeepSeek 還是智譜 GLM,改個(gè)環(huán)境變量就行。

核心設(shè)計(jì)是按用戶維度維護(hù)獨(dú)立的對(duì)話上下文

export class AIChat {
private sessions = new Map();

async chat(userId: string, userMessage: string): Promise {
const session = this.getSession(userId);
session.history.push({ role: "user", content: userMessage });

// 滑動(dòng)窗口,防止上下文過(guò)長(zhǎng)
if (session.history.length > this.maxHistory) {
session.history = session.history.slice(-this.maxHistory);
}

const messages: ChatCompletionMessageParam[] = [
{ role: "system", content: this.systemPrompt },
...session.history,
];

const completion = awaitthis.client.chat.completions.create({
model: this.model,
messages,
});

const reply = completion.choices[0]?.message?.content || "(AI 未返回內(nèi)容)";
session.history.push({ role: "assistant", content: reply });
return reply;
}
}

每個(gè)微信用戶 ID 對(duì)應(yīng)一個(gè)ChatSession,里面存著這個(gè)用戶的對(duì)話歷史。通過(guò)滑動(dòng)窗口來(lái)控制上下文長(zhǎng)度,避免 token 超限。

用戶可以發(fā)送/clear指令來(lái)清空對(duì)話上下文,重新開(kāi)始。

四、Bot 主循環(huán)

最后就是把所有模塊串起來(lái)的 Bot 主循環(huán)。它的核心就是一個(gè)while循環(huán):

while (this.running) {
try {
const resp = await getUpdates(
this.credentials.baseUrl,
this.credentials.token,
this.getUpdatesBuf,
);

// 更新游標(biāo)
if (resp.get_updates_buf) {
this.getUpdatesBuf = resp.get_updates_buf;
}

// 處理每條消息
for (const msg of resp.msgs ?? []) {
awaitthis.handleMessage(msg);
}
} catch (err) {
// 重試 + 退避策略
}
}

消息處理的邏輯:

  1. 過(guò)濾非用戶消息,只處理message_type === USER的消息

  2. 緩存context_token

  3. 提取文本內(nèi)容

  4. 通過(guò)sendMessage發(fā)回去

處理失敗還有重試策略:連續(xù)失敗不超過(guò) 5 次時(shí),每次等 2 秒后重試;超過(guò) 5 次則退避 30 秒,避免頻繁請(qǐng)求被限流。

使用方式 環(huán)境要求

  • Node.js >= 22

三步啟動(dòng)

# 1. 克隆并安裝
git clone https://github.com/user/wx-robot-ilink.git
cd wx-robot-ilink
npm install

# 2. 配置 AI 模型
cp .env.example .env
# 編輯 .env 填入你的 API Key

# 3. 啟動(dòng)
npm run dev

首次啟動(dòng)會(huì)在終端顯示二維碼,微信掃碼后在手機(jī)確認(rèn),就能開(kāi)始使用了。

結(jié)語(yǔ)

以上就是wx-robot-ilink的完整實(shí)現(xiàn)啦。回顧一下,整個(gè)項(xiàng)目做了這幾件事:

  1. @tencent-weixin/openclaw-weixin源碼里提取了微信 iLink HTTP API 協(xié)議

  2. 實(shí)現(xiàn)了掃碼登錄方案是 QR 狀態(tài)機(jī) + 憑證持久化

  3. 實(shí)現(xiàn)了長(zhǎng)輪詢收消息 + 發(fā)消息的通信層

  4. 接入 OpenAI 兼容 AI 模型,支持多輪對(duì)話

  5. 用一個(gè) while 循環(huán)把所有東西串起來(lái)

整體不到 300 行 TypeScript,沒(méi)有任何重型框架依賴,就實(shí)現(xiàn)了一個(gè)微信 AI 機(jī)器人。

當(dāng)然,目前這個(gè)版本還是比較基礎(chǔ)的,后續(xù)可以擴(kuò)展的方向有很多:

  • 圖片/語(yǔ)音支持 —— 協(xié)議本身支持 IMAGE、VOICE、VIDEO、FILE 類型,可以實(shí)現(xiàn)多模態(tài)對(duì)話

  • 持久化對(duì)話歷史 —— 目前對(duì)話在內(nèi)存中,重啟會(huì)丟失,可以接 SQLite 或 Redis

  • 定時(shí)消息 —— 結(jié)合 cron 實(shí)現(xiàn)早報(bào)、天氣推送等

更多功能還是要等微信官方支持~

項(xiàng)目已開(kāi)源:https://github.com/co-pine/wx-robot-ilink,歡迎大家 Star、Fork、提 Issue!

這篇文章是我們編程導(dǎo)航團(tuán)隊(duì)「松柏」同學(xué)的實(shí)戰(zhàn),如果覺(jué)得寫(xiě)得不錯(cuò),可以給個(gè)點(diǎn)贊和關(guān)注支持一下哦~

有問(wèn)題歡迎在評(píng)論區(qū)交流,下期再見(jiàn)!

特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關(guān)推薦
熱點(diǎn)推薦
固態(tài)電池靠邊站!國(guó)產(chǎn)王炸截胡,安全電車或降至4萬(wàn)

固態(tài)電池靠邊站!國(guó)產(chǎn)王炸截胡,安全電車或降至4萬(wàn)

藍(lán)色海邊
2026-04-17 18:25:24
旅游路上怎么全是大媽?大爺都去哪兒了?網(wǎng)友分析讓人爆笑到飆淚

旅游路上怎么全是大媽?大爺都去哪兒了?網(wǎng)友分析讓人爆笑到飆淚

西樓知趣雜談
2026-04-18 15:31:29
美媒:中國(guó)“殲-50”可能只是F-47隱身戰(zhàn)斗機(jī)的“低配仿制型號(hào)”

美媒:中國(guó)“殲-50”可能只是F-47隱身戰(zhàn)斗機(jī)的“低配仿制型號(hào)”

零度Military
2026-04-18 14:36:44
別再尬演情婦了!一臉疲態(tài)、五大三粗,這是迷倒男人該有的皮囊?

別再尬演情婦了!一臉疲態(tài)、五大三粗,這是迷倒男人該有的皮囊?

白面書(shū)誏
2026-04-14 14:09:53
拉比奧特一劍封喉,邁尼昂神撲救主,AC米蘭1-0送維羅納11連敗

拉比奧特一劍封喉,邁尼昂神撲救主,AC米蘭1-0送維羅納11連敗

釘釘陌上花開(kāi)
2026-04-19 23:07:29
3年前就戳穿西貝預(yù)制菜沒(méi)人信,如今被實(shí)錘!這個(gè)探店博主藏得太深了

3年前就戳穿西貝預(yù)制菜沒(méi)人信,如今被實(shí)錘!這個(gè)探店博主藏得太深了

馬蹄燙嘴說(shuō)美食
2026-04-15 18:29:48
人狂必有禍!不顧央視警告,與劉濤傳緋聞的楊爍,下場(chǎng)怪不了別人

人狂必有禍!不顧央視警告,與劉濤傳緋聞的楊爍,下場(chǎng)怪不了別人

陳意小可愛(ài)
2026-04-20 06:31:33
馬筱梅與玥箖割席后,硬要帶親媽住婆婆的別墅,張?zhí)m終于不再沉默

馬筱梅與玥箖割席后,硬要帶親媽住婆婆的別墅,張?zhí)m終于不再沉默

老屬科普
2026-04-18 06:08:23
杭州阿里程序員王偉:50萬(wàn)投洛陽(yáng)鉬業(yè),6年賺300萬(wàn)

杭州阿里程序員王偉:50萬(wàn)投洛陽(yáng)鉬業(yè),6年賺300萬(wàn)

真實(shí)人物采訪
2026-04-17 15:55:03
久保建英成為首個(gè)奪得國(guó)王杯的日本球員,也是其個(gè)人生涯首冠

久保建英成為首個(gè)奪得國(guó)王杯的日本球員,也是其個(gè)人生涯首冠

懂球帝
2026-04-19 15:42:52
寧波為什么沒(méi)有成為熱門(mén)旅游地?網(wǎng)友:寧波最好的就是三步一廁所

寧波為什么沒(méi)有成為熱門(mén)旅游地?網(wǎng)友:寧波最好的就是三步一廁所

君笙的拂兮
2026-03-27 12:25:59
巴基斯坦總理和伊朗總統(tǒng)通話

巴基斯坦總理和伊朗總統(tǒng)通話

財(cái)聯(lián)社
2026-04-20 01:54:04
世體:阿爾瓦雷斯和巴斯托尼都將加盟巴薩視為首選

世體:阿爾瓦雷斯和巴斯托尼都將加盟巴薩視為首選

懂球帝
2026-04-20 07:07:06
女演員千萬(wàn)別整容《八千里路云和月》看43歲萬(wàn)茜和24歲王和就知道

女演員千萬(wàn)別整容《八千里路云和月》看43歲萬(wàn)茜和24歲王和就知道

亦暖追劇隨筆
2026-04-17 12:28:50
開(kāi)走第2輛保時(shí)捷!萊巴金娜橫掃復(fù)仇,奪賽季第2冠+生涯第13冠

開(kāi)走第2輛保時(shí)捷!萊巴金娜橫掃復(fù)仇,奪賽季第2冠+生涯第13冠

全景體育V
2026-04-19 21:21:01
33歲章澤天風(fēng)格大變!穿艷俗紗裙、副乳突出,比實(shí)際年齡成熟10歲

33歲章澤天風(fēng)格大變!穿艷俗紗裙、副乳突出,比實(shí)際年齡成熟10歲

阿訊說(shuō)天下
2026-04-18 14:53:39
20-30元一天,蕭山有家開(kāi)了48年的古早風(fēng)旅館,老板身份不簡(jiǎn)單

20-30元一天,蕭山有家開(kāi)了48年的古早風(fēng)旅館,老板身份不簡(jiǎn)單

蕭內(nèi)網(wǎng)
2026-04-19 20:36:01
李連杰和利智合照曝光,他們已老的難以想象,“換心”謠言被澄清

李連杰和利智合照曝光,他們已老的難以想象,“換心”謠言被澄清

王楔曉
2026-04-19 20:20:07
從1億巨虧到抄底封神!瓜迪奧拉終于學(xué)乖了,曼城摸到了終極密碼

從1億巨虧到抄底封神!瓜迪奧拉終于學(xué)乖了,曼城摸到了終極密碼

章蠞戶外
2026-04-19 17:53:29
醫(yī)生:肝癌最危險(xiǎn)信號(hào),不是腹痛,而是頻繁出現(xiàn)這幾種異常

醫(yī)生:肝癌最危險(xiǎn)信號(hào),不是腹痛,而是頻繁出現(xiàn)這幾種異常

芹姐說(shuō)生活
2026-04-19 12:20:30
2026-04-20 07:27:00
程序員魚(yú)皮 incentive-icons
程序員魚(yú)皮
一手科技資訊和編程干貨
92文章數(shù) 91關(guān)注度
往期回顧 全部

科技要聞

50分26秒破人類紀(jì)錄!300臺(tái)機(jī)器人狂飆半馬

頭條要聞

半年下沉22厘米 女子家中坐擁價(jià)值上億別墅卻沒(méi)法住人

頭條要聞

半年下沉22厘米 女子家中坐擁價(jià)值上億別墅卻沒(méi)法住人

體育要聞

湖人1比0火箭:老詹比烏度卡像教練

娛樂(lè)要聞

何潤(rùn)東漲粉百萬(wàn)!內(nèi)娛隔空掀桌第一人

財(cái)經(jīng)要聞

華誼兄弟,8年虧光85億

汽車要聞

29分鐘大定破萬(wàn) 極氪8X為什么這么多人買?

態(tài)度原創(chuàng)

房產(chǎn)
教育
數(shù)碼
本地
軍事航空

房產(chǎn)要聞

官宣簽約最強(qiáng)城更!海口樓市,突然殺入神秘房企!

教育要聞

中國(guó)為什么不禁網(wǎng)絡(luò)游戲?

數(shù)碼要聞

華為新機(jī)發(fā)布前瞻:闊折疊X Max+影像旗艦Pura 90,都沒(méi)懸念了

本地新聞

12噸巧克力有難,全網(wǎng)化身超級(jí)偵探添亂

軍事要聞

伊朗逼退美掃雷艇:美方求給15分鐘撤退

無(wú)障礙瀏覽 進(jìn)入關(guān)懷版