FloatTech / ZeroBot-Plugin

基于 ZeroBot 的 OneBot 插件
GNU Affero General Public License v3.0
2.49k stars 2.02k forks source link

当zbp和gocq(实际上是openshamrock)不处于同一服务器时,无法发送本地图片 #840

Closed wangfreexx closed 6 months ago

wangfreexx commented 9 months ago

这个是abq的发送:向服务器发送请求: &{send_group_msg map[group_id:364328619 message:[CQ:image,file=file:////home/zbp/data/score/cache/103438060820240103signin.png]] 2}" 但是openshamrock会报错,找不到/home/zbp/data/score/cache这个地方图片,因为没在同一服务器上,请教如何解决

copurxia commented 9 months ago

其实也就签到是本地图片?

copurxia commented 9 months ago

那么可以试试这个方案

const WebSocket = require('ws');

const server = new WebSocket.WebSocketServer({ port: 8280 });

server.on('connection', function connection(ws) {
    const client = new WebSocket('ws://bbbb:6700');

    client.on('message', function message(data) {
        let datax = new TextDecoder("utf-8").decode(new Uint8Array(data));
        const regex = /{"type":"image","data":{"file":"file:\/\/\/([^"]+)"}}/;
        const match = datax.match(regex);
        if (match) {
            ws.send(datax.replace("aaaa","http://bbbb:8080/image/"));
        }
        ws.send(datax);
    });

    ws.on('message', function message(data) {
        let datax = new TextDecoder("utf-8").decode(new Uint8Array(data));
        client.send(datax);
    });
});

通过将本地地址映射为能访问的图床地址(当然此处可以选择更复杂的方案),然后让openshamrock指向8280端口即可 ws://bbbb:6700为原本的zbp地址

调用Cheverto图床

const WebSocket = require('ws');
const FormData = require('form-data');
const fs = require('fs');
const http = require('http');

const server = new WebSocket.WebSocketServer({ port: 监听端口 });

server.on('connection', function connection(ws) {
    const client = new WebSocket('真实的zbp地址');

    client.on('message', function message(data) {
        let datax = new TextDecoder("utf-8").decode(new Uint8Array(data));
        const regex = /{"type":"image","data":{"file":"file:\/\/\/([^"]+)"}}/;
        const match = datax.match(regex);
        if (match) {
            upimg(match[1],datax,ws);
        } else {
            ws.send(datax);
        }
    });

    ws.on('message', function message(data) {
        let datax = new TextDecoder("utf-8").decode(new Uint8Array(data));
        client.send(datax);
    });
});

function upimg(file,datax,ws) {
    let form = new FormData();
    form.append('source', fs.createReadStream(file));  //可以加个replace映射或者直接在docker上处理

    let request = http.request({
        method: 'post',
        host: 'Cheverto图床地址',
        port: 图床端口,
        path: '/api/1/upload/?key=你的apikey&format=json',
        headers: form.getHeaders()
    }, function (res) {
        let str = '';
        res.on('data', function (buffer) {
            str += buffer;
        }
        );
        res.on('end', () => {
            let result = JSON.parse(str);
            ws.send(datax.replace("file:///"+file, result.image.url));
        });
    });
    form.pipe(request);
}

懒得写异步,直接传了 记得打开图床的允许同步上传

wangfreexx commented 9 months ago

我尝试一下

vatebur commented 9 months ago

其实也就签到是本地图片?

还有wordcount wallet bilibili 这三个也是发送本地图片的。都需要改,感觉改成直接发送二进制图片或者base64会好点

copurxia commented 9 months ago

其实也就签到是本地图片?

还有wordcount wallet bilibili 这三个也是发送本地图片的。都需要改,感觉改成直接发送二进制图片或者base64会好点

我的方案是直接加个中转把所有本地图片都丢图床去了,虽然原则上修改插件会好一点