diff --git a/src/common/utils/request.ts b/src/common/utils/request.ts index 628f50ed..d7535147 100644 --- a/src/common/utils/request.ts +++ b/src/common/utils/request.ts @@ -1,7 +1,9 @@ import https from 'node:https'; import http from 'node:http'; -import fs from 'node:fs'; +import fs, { readFileSync } from 'node:fs'; import { NTQQUserApi } from '@/core'; +import path from 'node:path'; +import { request } from 'node:http'; export class RequestUtil { // 适用于获取服务器下发cookies时获取,仅GET static async HttpsGetCookies(url: string): Promise<{ [key: string]: string }> { @@ -108,50 +110,83 @@ export class RequestUtil { static async HttpGetText(url: string, method: string = 'GET', data?: any, headers: { [key: string]: string } = {}) { return this.HttpGetJson(url, method, data, headers, false, false); } - static async HttpUploadFileForOpenPlatform(filePath: string) { - const cookies = Object.entries(await NTQQUserApi.getCookies('connect.qq.com')).map(([key, value]) => `${key}=${value}`).join('; '); - return new Promise((resolve, reject) => { - var options = { - 'method': 'POST', - 'hostname': 'cgi.connect.qq.com', - 'path': '/qqconnectopen/upload_share_image', - 'headers': { - 'Referer': 'https://cgi.connect.qq.com', - 'Cookie': cookies, - 'Accept': '*/*', - 'Host': 'cgi.connect.qq.com', - 'Connection': 'keep-alive', - 'Content-Type': 'multipart/form-data; boundary=--------------------------800945582706338065206240' - }, - 'maxRedirects': 20 - }; - let body; - let req = https.request(options, function (res) { - let chunks: any = []; - - res.on("data", function (chunk) { - chunks.push(chunk); - }); - res.on("end", function () { - body = Buffer.concat(chunks); - console.log(body.toString()); + static async createFormData(boundary: string, filePath: string): Promise { + let type = 'image/png'; + if (filePath.endsWith('.jpg')) { + type = 'image/jpeg'; + } + const formDataParts = [ + `------${boundary}\r\n`, + `Content-Disposition: form-data; name="share_image"; filename="${filePath}"\r\n`, + `Content-Type: ` + type + `\r\n\r\n` + ]; + + const fileContent = readFileSync(filePath); + const footer = `\r\n------${boundary}--`; + return Buffer.concat([ + Buffer.from(formDataParts.join(''), 'utf8'), + fileContent, + Buffer.from(footer, 'utf8') + ]); + } + + static async uploadImageForOpenPlatform(filePath: string): Promise { + return new Promise(async (resolve, reject) => { + type retType = { retcode: number, result?: { url: string } }; + try { + const cookies = Object.entries(await NTQQUserApi.getCookies('connect.qq.com')).map(([key, value]) => `${key}=${value}`).join('; '); + const options = { + hostname: 'cgi.connect.qq.com', + port: 443, + path: '/qqconnectopen/upload_share_image', + method: 'POST', + headers: { + 'Referer': 'https://cgi.connect.qq.com', + 'Cookie': cookies, + 'Accept': '*/*', + 'Connection': 'keep-alive', + 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' + } + }; + const req = https.request(options, async (res) => { + let responseBody = ''; + + res.on('data', (chunk: string | Buffer) => { + responseBody += chunk.toString(); + }); + + res.on('end', () => { + + try { + if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) { + const responseJson = JSON.parse(responseBody) as retType; + resolve(responseJson.result?.url!); + } else { + reject(new Error(`Unexpected status code: ${res.statusCode}`)); + } + } catch (parseError) { + reject(parseError); + } + + }); + }); - res.on("error", function (error) { - console.error(error); + req.on('error', (error) => { + console.error('Error during upload:', error); }); - }); - var postData = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"share_image\"; filename=\"C:/1.png\"\r\nContent-Type: \"{Insert_File_Content_Type}\"\r\n\r\n" + fs.readFileSync(filePath) + "\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"; - req.setHeader('content-type', 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'); - req.write(postData); - req.end(); - if (body) { - resolve(JSON.parse(body)); - } else { - reject(); + const body = await RequestUtil.createFormData('WebKitFormBoundary7MA4YWxkTrZu0gW', filePath); + // req.setHeader('Content-Length', Buffer.byteLength(body)); + // console.log(`Prepared data size: ${Buffer.byteLength(body)} bytes`); + req.write(body); + req.end(); + return; + } catch (error) { + reject(error); } + return undefined; }); } } \ No newline at end of file diff --git a/src/core b/src/core index b1a865f2..12a3fc51 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit b1a865f29d8c418bb077db31a33f4a63d3edf8ea +Subproject commit 12a3fc511ebbd6db9db70e7551afbff7a0102478 diff --git a/src/onebot11/main.ts b/src/onebot11/main.ts index c54954fc..fc533457 100644 --- a/src/onebot11/main.ts +++ b/src/onebot11/main.ts @@ -23,7 +23,7 @@ import { getGroup, getGroupMember, groupNotifies, selfInfo, tempGroupCodeMap } f import { dbUtil } from '@/common/utils/db'; import { BuddyListener, GroupListener, NodeIKernelBuddyListener } from '@/core/listeners'; import { OB11FriendRequestEvent } from '@/onebot11/event/request/OB11FriendRequest'; -import { NTQQGroupApi, NTQQUserApi } from '@/core/apis'; +import { NTQQGroupApi, NTQQUserApi, SignMusicWrapper } from '@/core/apis'; import { log, logDebug, logError, setLogSelfInfo } from '@/common/utils/log'; import { OB11GroupRequestEvent } from '@/onebot11/event/request/OB11GroupRequest'; import { OB11GroupAdminNoticeEvent } from '@/onebot11/event/notice/OB11GroupAdminNoticeEvent'; @@ -38,6 +38,7 @@ import { Data as DeviceData } from '@/proto/SysMessage.DeviceChange'; import { OB11FriendPokeEvent, OB11GroupPokeEvent } from './event/notice/OB11PokeEvent'; import { isEqual } from '@/common/utils/helper'; import { MiniAppUtil } from '@/common/utils/Packet' +import { RequestUtil } from '@/common/utils/request'; //下面几个其实应该移进Core-Data 缓存实现 但是现在在这里方便 // @@ -574,4 +575,7 @@ export class NapCatOnebot11 { // setTimeout(async () => { // let ret = await MiniAppUtil.RunMiniAppWithGUI(); // console.log(ret); -// }, 20000); \ No newline at end of file +// }, 20000); +// setTimeout(async () => { +// await SignMusicWrapper('429450678'); +// }, 15000) \ No newline at end of file