UNPKG

coze-plugin-utils

Version:

Comprehensive utility library for Coze plugins with multimedia processing, browser automation, cloud storage integration, and AI-powered video/audio generation capabilities

167 lines 6.27 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.applyToken = applyToken; exports.getTempPath = getTempPath; exports.uploadFile = uploadFile; exports.createTempDir = createTempDir; exports.downloadFile = downloadFile; exports.downloadFiles = downloadFiles; const node_path_1 = __importDefault(require("node:path")); const node_fs_1 = __importDefault(require("node:fs")); const api_1 = require("@coze/api"); const axios_1 = __importDefault(require("axios")); const form_data_1 = __importDefault(require("form-data")); const mime_1 = __importDefault(require("mime")); const uuid_1 = require("uuid"); const config_1 = require("./config"); let tokenBuffer = null; async function applyToken() { const now = Date.now(); if (tokenBuffer && tokenBuffer.expires_in * 1000 > now) { return tokenBuffer; } const config = (0, config_1.getGlobalConfig)('jwt'); const baseUrl = (0, config_1.getGlobalConfig)('baseUrl'); if (!config) { throw new Error('JWT 配置不存在'); } const payload = { baseURL: baseUrl, appId: config.appId, aud: new URL(baseUrl).host, keyid: config.keyid, privateKey: config.privateKey, sessionName: config.userId, }; // 如果缓存不存在或即将过期,获取新 token tokenBuffer = await (0, api_1.getJWTToken)(payload); return tokenBuffer; } function getTempPath(tmpPath) { const match = tmpPath.match(/^(\/tmp\/.*?)\//); if (!match) { throw new Error('无法找到目录,这个文件不是临时文件'); } const tmpDir = match[1]; return tmpDir; } async function uploadFile(tmpFile, autoClear = true) { try { const jwtToken = (await applyToken()).access_token; const buffer = node_fs_1.default.readFileSync(tmpFile); const parsedFile = node_path_1.default.parse(tmpFile); const ext = parsedFile.ext || ''; // 构建 form-data const form = new form_data_1.default(); form.append('file', buffer, { filename: parsedFile.name + ext, contentType: mime_1.default.getType(ext) || 'application/octet-stream', }); const baseURL = (0, config_1.getGlobalConfig)('baseUrl'); // 提交请求 const response = await axios_1.default.post(`${baseURL}/v1/files/upload`, form, { headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${jwtToken}`, }, }); const data = response.data; const file_id = data.data.id; const workflowApi = 'https://api.coze.cn/v1/workflow/run'; const headers = { Authorization: `Bearer ${jwtToken}`, 'Content-Type': 'application/json', }; const workflows = (0, config_1.getGlobalConfig)('workflows'); if (!workflows) { throw new Error('workflows 配置不存在'); } const body = { workflow_id: workflows?.fileUploader, parameters: { file: JSON.stringify({ file_id }), }, }; const ret = await fetch(workflowApi, { method: 'POST', headers, body: JSON.stringify(body), }); try { const resData = await ret.json(); if (resData.code > 299) { throw new Error(resData.msg); } const { url } = JSON.parse(resData.data); return { url, }; } catch (ex) { throw ex; } } finally { // 上传完成后删掉整个目录 if (autoClear) { const tmpDir = getTempPath(tmpFile); console.log('removing tmp dir...', tmpDir); node_fs_1.default.rmSync(tmpDir, { recursive: true, force: true }); } } } function createTempDir() { const tempDir = node_path_1.default.join('/', 'tmp', (0, uuid_1.v4)()); node_fs_1.default.mkdirSync(tempDir, { recursive: true }); return tempDir; } async function downloadFile(url, filename, tempDir = createTempDir()) { if (url.startsWith('/tmp')) { // 这是本地文件,直接返回,这样的话才能允许ffmpeg的几个方法串行使用 return { file: url, createOutput: (filename) => { const tmpDir = node_path_1.default.join(getTempPath(url), (0, uuid_1.v4)()); node_fs_1.default.mkdirSync(tmpDir, { recursive: true }); return node_path_1.default.join(tmpDir, filename); }, }; } const filePath = node_path_1.default.join(tempDir, filename); try { const response = await (0, axios_1.default)({ url, method: 'GET', responseType: 'stream' }); const writer = node_fs_1.default.createWriteStream(filePath); response.data.pipe(writer); await new Promise((resolve, reject) => { writer.on('finish', resolve); writer.on('error', (err) => reject(err)); }); const ret = { file: filePath, // 用 createOutput 创建的文件可以随着 output 上传自动删除,不会留在 tmp 目录下 // 确保不会重名 createOutput: (filename) => { const tmpDir = node_path_1.default.join(getTempPath(filePath), (0, uuid_1.v4)()); node_fs_1.default.mkdirSync(tmpDir, { recursive: true }); return node_path_1.default.join(tmpDir, filename); }, }; const contentType = response.headers['content-type']; if (contentType) ret.contentType = contentType; return ret; } catch (ex) { await node_fs_1.default.rmSync(tempDir, { recursive: true, force: true }); throw ex; } } async function downloadFiles(files) { const tempDir = createTempDir(); const ret = await Promise.all(files.map((file) => downloadFile(file.url, file.filename, tempDir))); return ret; } //# sourceMappingURL=coze.js.map