Open feilongproject opened 2 years ago
附议,帖子
的接口nodeSDK也该跟进一下
+1
目前自己写了个example
import FormData from 'form-data';////需要自己安装
import fetchfrom 'node-fetch';//需要自己安装
import fs from 'fs';
import { IMessage } from 'qq-guild-bot';
export async function sendImage(msg: IMessage, picName: string,) {
picName = picName?.startsWith("/") ? picName : `${config.picPath.out}/${picName}`;
log.debug(`uploading ${picName}`);
var picData = fs.createReadStream(picName);
var formdata = new FormData();
formdata.append("msg_id", msg.id);
//formdata.append("content", "123456");
formdata.append("file_image", picData);
await fetch(`https://api.sgroup.qq.com/channels/${msg.channel_id}/messages`, {
method: "POST",
headers: {
"Content-Type": formdata.getHeaders()["content-type"],
"Authorization": `Bot ${config.appID}.${config.token}`
},
body: formdata
}).then(async res => {
const body = await res.json();
if (body.code)
throw new Error(body);
}).catch(error => {
log.error(error);
})
}
https://github.com/satorijs/qq-guild-sdk/blob/master/packages/core/test/index.spec.ts#L48-L53
欢迎试试我的,或者尝试一下 koishi ,koishi 的 adapter 也是基于该 sdk 封装的
如果有人想自己实现发送图片,楼上的代码是对的,但是有一点需要说明,就是主动发送图片会触发异常,异常消息为正在审核,也就是 fetch 后始终跳转到 catch 中,这是正常的。我用了一个 promise 来等待审核通过
let passPromise = null;
try {
const response = await axios.post(apiUrl, formData, {
headers: {
...formData.getHeaders(),
Authorization: `Bot ${qqGuildConfig.appID}.${qqGuildConfig.token}`
}, timeout: 10 * 1000
}
);
// 正常会有异常,触发审核,不会走到下面
console.log(`[${new Date().toLocaleString()} Guild] 图片发送成功: photo ${photoPath}`, response.data);
return response;
} catch (error) {
// 等待审核中
if (error.response.status === 500 && error.response.data.code === 304023) {
passPromise = new Promise((resolve, reject) => {
handlePassPromise = data => {
if (data.msg.audit_id === error.response.data.data.message_audit.audit_id) {
if (data.eventType === 'MESSAGE_AUDIT_PASS')
resolve(data);
else
reject(data);
}
};
setTimeout(() => reject(new Error('审核超时')), 10 * 1000);
});
} else {
console.error(`[${new Date().toLocaleString()} Guild] 图片发送失败: photo ${photoPath}, error: ${error}`);
}
}
if (passPromise) {
try {
const audit = await passPromise;
console.log(`[${new Date().toLocaleString()} Guild] 图片发送成功: photo ${photoPath}`, audit);
return audit;
} catch ( error ) {
console.error(`[${new Date().toLocaleString()} Guild] 审核未通过或超时: ${error}`);
}
}
return null;
下面的 websocket 中调用处理函数,handlePassPromise
为全局变量
ws.on('MESSAGE_AUDIT', (data) => {
console.log('[MESSAGE_AUDIT] 事件接收 :', data);
if (handlePassPromise)
handlePassPromise(data);
});
在官方API文档里有说明,可以通过
multipart/form-data
参数里的file_image
字段,直接通过文件上传的方式发送图片,请求适配