一、引言
微信公眾號作為當(dāng)前最流行的社交媒體平臺之一,為企業(yè)和個人提供了與粉絲互動、傳播信息的絕佳渠道。而Node.js作為一種高效、輕量級的JavaScript運行環(huán)境,非常適合用于微信公眾號開發(fā)。本文將詳細(xì)介紹如何使用Node.js開發(fā)微信公眾號,幫助開發(fā)者快速上手。
二、準(zhǔn)備工作
在開始開發(fā)之前,我們需要準(zhǔn)備以下工具和材料:
- Node.js環(huán)境:確保你的計算機(jī)上已經(jīng)安裝了Node.js和npm(Node Package Manager)。
- 微信公眾號測試號:在微信公眾平臺申請一個測試號,用于開發(fā)和測試。
- 編輯器:選擇一個你喜歡的代碼編輯器,如Visual Studio Code、Sublime Text等。
三、服務(wù)器配置
- 填寫服務(wù)器配置
登錄微信公眾平臺官網(wǎng)后,在公眾平臺官網(wǎng)的開發(fā)-基本設(shè)置頁面,勾選協(xié)議成為開發(fā)者,點擊“修改配置”按鈕,填寫服務(wù)器地址(URL)、Token和EncodingAESKey。其中,URL是開發(fā)者用來接收微信消息和事件的接口URL;Token可由開發(fā)者任意填寫,用作生成簽名(該Token會和接口URL中包含的Token進(jìn)行比對,從而驗證安全性);EncodingAESKey由開發(fā)者手動填寫或隨機(jī)生成,將用作消息體加解密密鑰。
同時,開發(fā)者可選擇消息加解密方式:明文模式、兼容模式和安全模式。模式的選擇與服務(wù)器配置在提交后都會立即生效,請開發(fā)者謹(jǐn)慎填寫及選擇。加解密方式的默認(rèn)狀態(tài)為明文模式,選擇兼容模式和安全模式需要提前配置好相關(guān)加解密代碼。
注意:URL字段填寫一個接口,不能是IP地址,而且域名必須指向80端口,需要后端配合,能夠響應(yīng)微信發(fā)送的驗證。如果接口異常無法配置成功,可以使用natapp等基于ngrok的域名映射工具。
- 驗證服務(wù)器地址的有效性
開發(fā)者提交信息后,微信服務(wù)器將發(fā)送GET請求到填寫的服務(wù)器地址URL上,GET請求攜帶參數(shù)包括signature、timestamp、nonce和echostr。開發(fā)者需要對signature進(jìn)行校驗,確認(rèn)此次GET請求來自微信服務(wù)器。校驗方式如下:
(1)將token、timestamp、nonce三個參數(shù)進(jìn)行字典序排序; (2)將三個參數(shù)字符串拼接成一個字符串進(jìn)行sha1加密; (3)獲得加密后的字符串可與signature對比,標(biāo)識該請求來源于微信。
若確認(rèn)此次GET請求來自微信服務(wù)器,請原樣返回echostr參數(shù)內(nèi)容,則接入生效,成為開發(fā)者成功;否則接入失敗。
以下是一個Node.js示例代碼,用于驗證服務(wù)器地址的有效性:
const express = require('express');
const crypto = require('crypto');
const app = express();
const port = 3000;
const token = 'your_token'; // 填寫你的Token
app.get('/wechat', (req, res) => {
const signature = req.query.signature;
const timestamp = req.query.timestamp;
const nonce = req.query.nonce;
const echostr = req.query.echostr;
// 校驗signature
const arr = [token, timestamp, nonce].sort();
const str = arr.join('');
const sha1 = crypto.createHash('sha1');
sha1.update(str);
const result = sha1.digest('hex');
if (result === signature) {
res.send(echostr);
} else {
res.send('error');
}
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});
將上述代碼保存為一個JavaScript文件,并在終端中運行該文件。然后,在微信公眾平臺的服務(wù)器配置頁面填寫你的服務(wù)器地址(如http://localhost:3000/wechat
)、Token和EncodingAESKey,點擊提交。如果配置成功,你將看到“接入成功”的提示。
四、消息處理
- 接收消息
當(dāng)粉絲向公眾號發(fā)送消息時,微信服務(wù)器會將消息推送到開發(fā)者填寫的服務(wù)器地址上。消息包括文本消息、圖片消息、語音消息、視頻消息等。開發(fā)者需要根據(jù)消息類型進(jìn)行相應(yīng)的處理。
以下是一個接收文本消息的示例代碼:
app.post('/wechat', express.json(), (req, res) => {
const msgType = req.body.MsgType;
const fromUserName = req.body.FromUserName;
const toUserName = req.body.ToUserName;
const content = req.body.Content;
if (msgType === 'text') {
// 處理文本消息
const replyMsg = `您發(fā)送的文本消息是:${content}`;
const replyXml = `
<xml>
<ToUserName><![CDATA[${fromUserName}]]></ToUserName>
<FromUserName><![CDATA[${toUserName}]]></FromUserName>
<CreateTime>${Math.floor(Date.now() / 1000)}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[${replyMsg}]]></Content>
</xml>
`;
res.send(replyXml);
} else {
// 處理其他類型的消息
res.send('success');
}
});
在上述代碼中,我們使用express.json()
中間件來解析POST請求的JSON數(shù)據(jù)。然后,根據(jù)MsgType
字段判斷消息類型,并進(jìn)行相應(yīng)的處理。對于文本消息,我們構(gòu)造一個回復(fù)消息,并將其以XML格式發(fā)送給微信服務(wù)器。
- 發(fā)送消息
開發(fā)者也可以主動向粉絲發(fā)送消息,包括文本消息、圖片消息、語音消息等。以下是一個發(fā)送文本消息的示例代碼:
const accessToken = 'your_access_token'; // 填寫你的access_token
const sendTextMessage = (toUserName, content) => {
const url = `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${accessToken}`;
const data = {
"touser": toUserName,
"msgtype": "text",
"text": {
"content": content
}
};
axios.post(url, data)
.then(response => {
console.log('消息發(fā)送成功', response.data);
})
.catch(error => {
console.error('消息發(fā)送失敗', error);
});
};
// 調(diào)用發(fā)送消息函數(shù)
sendTextMessage('user_open_id', '這是一條測試消息');
在上述代碼中,我們使用axios庫向微信服務(wù)器發(fā)送POST請求,發(fā)送文本消息給指定的粉絲。注意,access_token
是調(diào)用微信API的憑證,需要定期獲取和更新。你可以使用微信提供的API接口獲取access_token
。
五、菜單設(shè)置
微信公眾號還支持自定義菜單功能,開發(fā)者可以根據(jù)自己的需求設(shè)置菜單項和菜單事件。以下是一個設(shè)置自定義菜單的示例代碼:
const createMenu = () => {
const accessToken = 'your_access_token'; // 填寫你的access_token
const url = `https://api.weixin.qq.com/cgi-bin/menu/create?access_token=${accessToken}`;
const data = {
"button": [
{
"type": "click",
"name": "今日歌曲",
"key": "V1001_TODAY_MUSIC"
},
{
"type": "view",
"name": "官網(wǎng)",
"url": "http://www.example.com"
},
{
"name": "菜單",
"sub_button": [
{
"type": "click",
"name": "搜索",
"key": "V1002_TODAY_NEWS"
},
{
"type": "view",
"name": "視頻",
"url": "http://www.qq.com"
},
{
"type": "click",
"name": "贊一下我們",
"key": "V1003_GOOD"
}
]
}
]
};
axios.post(url, data)
.then(response => {
console.log('菜單設(shè)置成功', response.data);
})
.catch(error => {
console.error('菜單設(shè)置失敗', error);
});
};
// 調(diào)用設(shè)置菜單函數(shù)
createMenu();
在上述代碼中,我們使用axios庫向微信服務(wù)器發(fā)送POST請求,設(shè)置自定義菜單。菜單項包括點擊事件和跳轉(zhuǎn)鏈接兩種類型。你可以根據(jù)自己的需求設(shè)置不同的菜單項和菜單事件。
六、總結(jié)
本文詳細(xì)介紹了如何使用Node.js開發(fā)微信公眾號,包括服務(wù)器配置、消息處理、菜單設(shè)置