需将autMan更新至3.3.6及以上版本。
Gewe的项目地址为:https://github.com/Devo919/Gewechat
拉取镜像: 执行命令
docker pull registry.cn-hangzhou.aliyuncs.com/gewe/gewe:latest
然后使用
docker tag registry.cn-hangzhou.aliyuncs.com/gewe/gewe gewe
命令进行标记。
创建目录并运行容器:
mkdir -p /root/temp
docker run -itd -v /root/temp:/root/temp -p 2531:2531 -p 2532:2532 --privileged=true --name=gewe gewe /usr/sbin/init
解决可能出现的问题:
若运行该镜像后日志出现bash Failed to allocate manager object, freezing 1
提示:
使用第三方粉丝重新打包的镜像registry.cn-chengdu.aliyuncs.com/tu1h/wechotd:alpine
,此镜像仅提升系统版本,不会出现上述错误,使用该镜像后无需看解决方法2的内容。
第三方粉丝重新打包的镜像,操作如下:
docker pull registry.cn-chengdu.aliyuncs.com/tu1h/wechotd:alpine
docker tag registry.cn-chengdu.aliyuncs.com/tu1h/wechotd:alpine gewe
cd ~
mkdir temp
docker run -itd \
-v /root/temp:/root/temp \
-p 2531:2531 \
-p 2532:2532 \
--privileged=true \
--restart unless-stopped \
--name=gewe_autman \
gewe
让系统同时兼容cgroup v1和v2,操作如下:
- 编辑`/etc/default/grub`文件,添加内容`GRUB_CMDLINE_LINUX="SYSTEMD_CGROUP_ENABLE_LEGACY_FORCE=1 systemd.unified_cgroup_hierarchy=0"`。
- 执行`regenerate grub.cfg`(实际操作可能是对应的生成配置文件命令,如`grub-mkconfig -o /boot/grub/grub.cfg`)。
- 执行`reboot system`命令重启系统,重启后再次运行创建的容器。
访问管理地址IP+端口号2531访问 如图:
更新autMan官方市场最新的Gewechat登录器插件,设置好配参之后,给你的bot发送指令gewechat
,然后根据提示操作。注意最后填写回调地址时不要写autman文件里面那个ws地址,要写http://奥特曼ip:端口/gw/receive
。
将以下代码复制到文件adapter_gw_http.js
中(文件名固定,不要修改),并将adapter_gw_http.js
文件放进autMan主文件夹中plugin/adapters
下面,然后重启autMan。
//[param: {"required":true,"key":"im.gw.gewe_url","bool":false,"placeholder":"","name":"Gewechat接口地址","desc":"示例:http://192.168.31.49:2531"}]
//[param: {"required":true,"key":"im.gw.gewe_token","bool":false,"placeholder":"","name":"Gewechat的Token","desc":"示例:203ae5a1028b4299a5d9cc6168e5ab88"}]
//[param: {"required":true,"key":"im.gw.gewe_appId","bool":false,"placeholder":"","name":"Gewechat的appId","desc":"示例:wx_9iXhu-hi8NE_NIuDHKPV_"}]
//[param: {"required":true,"key":"im.gw.gewe_uuid","bool":false,"placeholder":"","name":"Gewechat的uuid","desc":""}]
const { WebSocket } = require('ws');
const axios = require('axios');
const middleware = require('./plugin/scripts/middleware.js');
var imHttpApi, token, appId, port;
// 接收自动数据
async function receiveAutData(websocketAut) {
websocketAut.on('message', async (message) => {
try {
console.log(`【gewechat适配器】Received from gewe: `);
const messageJson = JSON.parse(message);
console.log(`【gewechat适配器】解析json信息完成`);
// 判断消息来源,并传递给对应的处理函数
if ("Data" in messageJson && "TypeName" in messageJson) {
// 消息来自社交平台,调用fromgw处理
await fromgw(websocketAut, messageJson);
} else if ("aut_echo" in messageJson) {
// 消息来自aut,调用fromaut处理
await fromaut(websocketAut, messageJson);
}
} catch (e) {
console.log(`【gewechat适配器】JSON解析错误: `);
}
});
}
// 处理来自gewechat的消息
async function fromgw(websocketAut, messageJson) {
const wxid = messageJson.Wxid; // 发送者微信ID
const msg_data = messageJson.Data; // 消息数据
if (msg_data) {
// 判断是否为自己发送的消息
if (msg_data['FromUserName']['string'] === wxid) {
console.log("【gewechat适配器】自己的消息不做处理");
return; // 自己的消息不处理
}
console.log("【gewechat适配器】开始处理消息:", JSON.stringify(msg_data));
// 判断是群聊还是私聊
const isGroupChat = msg_data['FromUserName']['string'].includes('@chatroom');
const fromUserName = msg_data['FromUserName']['string'];
const toUserName = messageJson.Wxid; // 使用发送方的微信ID作为toUserName
const pushContent = msg_data['PushContent']? msg_data['PushContent'] : msg_data["Content"]["string"]; // 消息内容
const content = msg_data["Content"]["string"].split(":\n").length > 1? msg_data["Content"]["string"].split(":\n")[1] : msg_data["Content"]["string"];
const msgId = msg_data['MsgId']? msg_data['MsgId'].toString() : "";
// 提取用户名(冒号前的部分)
let userName = pushContent? pushContent.split(':')[0].trim() : ""; // 从PushContent中提取用户名
const commsg = {
bot_id: toUserName, // 使用发送方的微信ID作为bot_id
user_name: userName, // 从PushContent中提取的用户名
im_type: "gw",
message_id: msgId, // 使用NewMsgId作为消息ID
content: content // 消息内容(冒号后的部分)
};
// 根据消息类型确定chat_id和user_id
if (isGroupChat) {
commsg["chat_id"] = fromUserName; // 群聊ID
commsg["user_id"] = userName; // 发消息的用户ID
} else {
commsg["user_id"] = fromUserName; // 单聊对方ID
}
var str = JSON.stringify(commsg);
await websocketAut.send(str);
} else {
console.log("【gewechat适配器】data is null or undefined");
}
}
// 处理来自aut的消息
async function fromaut(websocketAut, messageJson) {
if (messageJson["aut_action"] === "reply_message" || messageJson["aut_action"] === "push_message") {
const autEcho = messageJson["aut_echo"];
var send_content = messageJson['aut_params']['content'];
let final_text = send_content;
let images = [];
try {
const regex = /\[CQ:image,file=.*?\]/g;
// 判断正则表达式匹配图片链接
if (send_content.match(regex) === null) {
// 没有图片链接,直接发送文本消息
const replyMessage = {
appId: appId, // 替换成实际的设备ID
toWxid: messageJson["aut_params"]["chat_id"]? messageJson["aut_params"]["chat_id"] : messageJson["aut_params"]["user_id"],
content: final_text,
};
const messageId = await postData(replyMessage, imHttpApi + '/v2/api/message/postText');
//必须给autMan发送回执
const echoMessage = {
aut_echo: autEcho,
aut_params: messageId? `` : "",
};
await websocketAut.send(JSON.stringify(echoMessage));
return;
}
// 有图片链接,提取图片链接
const matches = send_content.match(regex);
for (let index = 0; index < matches.length; index++) {
const image = matches[index];
final_text = final_text.replace(image, '');
var tmp = image.replace("[CQ:image,file=", "").replace("]", "");
if (tmp) {
images.push(tmp);
}
}
} catch (error) {
console.log("【gewechat适配器】提取图片出错:", error);
}
final_text = final_text.replace(/\s*\n\s*\n/g, '\n'); // 去掉连续的空行
let echo_messageIds = [];
// 发送文本消息
if (final_text.length > 0) {
const replyMessage = {
appId: appId, // 替换成实际的设备ID
toWxid: messageJson["aut_params"]["chat_id"]? messageJson["aut_params"]["chat_id"] : messageJson["aut_params"]["user_id"],
content: final_text,
};
const messageId = await postData(replyMessage, imHttpApi + '/v2/api/message/postText');
if (messageId) {
echo_messageIds.push(``);
}
}
// 发送图片消息
if (images.length > 0) {
for (let index = 0; index < images.length; index++) {
const image = images[index];
const replyMessage = {
appId: appId, // 替换成实际的设备ID
toWxid: messageJson["aut_params"]["chat_id"]? messageJson["aut_params"]["chat_id"] : messageJson["aut_params"]["user_id"],
imgUrl: image, // 图片URL
};
const messageId = await postData(replyMessage, imHttpApi + '/v2/api/message/postImage');
console.log("【gewechat适配器】发送图片消息的返回值:", messageId);
if (messageId) {
echo_messageIds.push(``);
}
}
}
//必须给autMan发送回执且只能发送一次
const echoMessage = {
aut_echo: autEcho,
aut_params: echo_messageIds? echo_messageIds : "",
};
await websocketAut.send(JSON.stringify(echoMessage));
}
}
// 发送数据到HTTP接口,返回msgId或null
async function postData(data, url) {
try {
const headers = {
'Content-Type': 'application/json',
'X-GEWE-TOKEN': token,
};
const response = await axios.post(url, data, { headers });
console.log('【gewechat适配器】Response:', response.data);
return response.data.data.msgId; // 根据API文档,msgId在data对象内
} catch (error) {
console.error('【gewechat适配器】Error sending POST request:', error);
return null;
}
}
//获取token,返回token或null
async function getToken() {
try {
const headers = {
'Content-Type': 'application/json',
};
const response = await axios.post(imHttpApi + "/v2/api/tools/getTokenId", {}, { headers });
console.log('【gewechat适配器】Response:', response.data);
return response.data.data;
} catch (error) {
console.error('【gewechat适配器】Error sending POST request:', error);
return token;
}
}
// 主函数,启动WebSocket连接
async function main() {
// //不断更新token
// setInterval(async () => {
// token = await getToken();
// }, 1000 * 60); //每分钟获取一次token
//下面的地址需要根据自己autMan的端口修改一下
while (true) {
port = await middleware.port();
imHttpApi = await middleware.bucketGet("im.gw", "gewe_url");
token = await middleware.bucketGet("im.gw", "gewe_token");
appId = await middleware.bucketGet("im.gw", "gewe_appId");
if (imHttpApi && token && appId && port) {
break;
} else {
//等待5s
await new Promise((resolve) => setTimeout(resolve, 5000));
}
}
let uriAut = `ws://127.0.0.1:/gw/adapter`;
console.log(`【gewechat适配器】Connecting to autMan at `);
const websocketAut = new WebSocket(uriAut);
await receiveAutData(websocketAut);
}
main();
若使用Gewechat设置器成功登陆后会自动生成相关3个参数,无需自己填写。
完成上述对接操作后,启用相关设置并重启autMan,使其生效。