n8n-nodes-cos-uploadfile
Version:
A custom n8n node to upload files to Tencent Cloud Object Storage (COS).
287 lines (286 loc) • 12.3 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CosUpload = void 0;
// 导入腾讯云 COS SDK
const cos_nodejs_sdk_v5_1 = __importDefault(require("cos-nodejs-sdk-v5"));
// 导入 Node.js 的文件系统模块 (使用 promises API 更方便处理异步)
const fs = __importStar(require("fs/promises")); // Changed to fs/promises for async readFile
const path = __importStar(require("path")); // Useful for path manipulation
class CosUpload {
constructor() {
this.description = {
displayName: '腾讯云 COS 文件上传',
name: 'cosUpload',
icon: 'fa:cloud-arrow-up', // 使用一个更贴切的图标
group: ['storage'], // 分组为存储类
version: 1,
description: '上传本地文件到腾讯云对象存储 COS',
defaults: {
name: 'COS 文件上传',
},
// 修复 inputs 和 outputs 的类型错误
inputs: ['main'], // 使用 any 绕过严格的类型检查
outputs: ['main'], // 使用 any 绕过严格的类型检查
// 定义节点所需的凭证类型
credentials: [
{
name: 'tencentCosApi', // 凭证的内部名称,后续会创建
required: true,
},
],
properties: [
// 上传模式选择
{
displayName: '上传模式',
name: 'uploadMode',
type: 'options',
options: [
{ name: '本地文件上传', value: 'localFile' },
{ name: 'HTML内容上传', value: 'htmlContent' },
],
default: 'localFile',
description: '选择上传模式:本地文件或HTML内容',
required: true,
},
// 文件路径
{
displayName: '本地文件路径',
name: 'filePath',
type: 'string',
default: '',
placeholder: '/path/to/your/file.txt',
description: '要上传的本地文件的绝对路径',
required: true,
displayOptions: {
show: {
uploadMode: ['localFile'],
},
},
},
// HTML内容
{
displayName: 'HTML内容',
name: 'htmlContent',
type: 'string',
typeOptions: {
rows: 10,
},
default: '',
placeholder: '<html><body><h1>Hello World</h1></body></html>',
description: '要上传的HTML内容',
required: true,
displayOptions: {
show: {
uploadMode: ['htmlContent'],
},
},
},
// HTML文件名
{
displayName: 'HTML文件名',
name: 'htmlFileName',
type: 'string',
default: 'index.html',
placeholder: 'index.html',
description: '生成的HTML文件名',
required: true,
displayOptions: {
show: {
uploadMode: ['htmlContent'],
},
},
},
// 存储桶名称
{
displayName: '存储桶名称 (Bucket)',
name: 'bucket',
type: 'string',
default: '',
placeholder: 'your-bucket-name-125xxxxxxxx',
description: '您的腾讯云 COS 存储桶名称 (包含 APPID)',
required: true,
},
// 存储桶地域
{
displayName: '存储桶地域 (Region)',
name: 'region',
type: 'options', // 使用选项类型
options: [
{ name: '北京 (ap-beijing)', value: 'ap-beijing' },
{ name: '南京 (ap-nanjing)', value: 'ap-nanjing' },
{ name: '上海 (ap-shanghai)', value: 'ap-shanghai' },
{ name: '广州 (ap-guangzhou)', value: 'ap-guangzhou' },
{ name: '成都 (ap-chengdu)', value: 'ap-chengdu' },
{ name: '重庆 (ap-chongqing)', value: 'ap-chongqing' },
{ name: '香港 (ap-hongkong)', value: 'ap-hongkong' },
{ name: '新加坡 (ap-singapore)', value: 'ap-singapore' },
{ name: '硅谷 (na-siliconvalley)', value: 'na-siliconvalley' },
// ... 更多地域可以根据需要添加
],
default: 'ap-guangzhou',
description: '存储桶所在的地域',
required: true,
},
// 存储在桶里的对象键
{
displayName: '对象键 (Key)',
name: 'key',
type: 'string',
default: '',
placeholder: 'images/my-photo.jpg',
description: '文件在 COS 中的路径和名称',
required: true,
},
],
};
}
async execute() {
const items = this.getInputData(); // 获取输入数据 (如果需要从上一个节点获取文件路径等)
const returnData = [];
// 获取凭证
const credentials = (await this.getCredentials('tencentCosApi'));
const secretId = credentials.secretId;
const secretKey = credentials.secretKey;
// 获取节点参数
const uploadMode = this.getNodeParameter('uploadMode', 0);
const bucket = this.getNodeParameter('bucket', 0);
const region = this.getNodeParameter('region', 0);
const key = this.getNodeParameter('key', 0);
// 根据上传模式获取相应参数
let filePath = '';
let htmlContent = '';
let htmlFileName = '';
if (uploadMode === 'localFile') {
filePath = this.getNodeParameter('filePath', 0);
}
else if (uploadMode === 'htmlContent') {
htmlContent = this.getNodeParameter('htmlContent', 0);
htmlFileName = this.getNodeParameter('htmlFileName', 0);
}
// 确保 SecretId 和 SecretKey 存在
if (!secretId || !secretKey) {
throw new Error('腾讯云 COS 凭证 (SecretId 和 SecretKey) 未配置或不完整。');
}
// 初始化 COS 实例
const cos = new cos_nodejs_sdk_v5_1.default({
SecretId: secretId,
SecretKey: secretKey,
});
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
try {
if (uploadMode === 'localFile') { // 本地文件上传
// 执行文件上传
const uploadResult = await new Promise((resolve, reject) => {
cos.uploadFile({
Bucket: bucket,
Region: region,
Key: key,
FilePath: filePath, // 本地文件路径
}, function (err, data) {
if (err) {
return reject(err);
}
resolve(data);
});
});
// 将上传结果添加到输出数据
returnData.push({
json: {
success: true,
message: `文件 '${filePath}' 成功上传到 COS`,
cosResponse: uploadResult,
},
pairedItem: {
item: itemIndex,
},
});
}
else if (uploadMode === 'htmlContent') {
// HTML内容上传
const htmlFilePath = path.join(process.cwd(), htmlFileName);
// 先写入HTML内容到临时文件
await fs.writeFile(htmlFilePath, htmlContent);
// 执行文件上传
const uploadResult = await new Promise((resolve, reject) => {
cos.uploadFile({
Bucket: bucket,
Region: region,
Key: key,
FilePath: htmlFilePath, // 使用刚创建的临时文件路径
}, function (err, data) {
if (err) {
return reject(err);
}
resolve(data);
});
});
// 将上传结果添加到输出数据
returnData.push({
json: {
success: true,
message: `HTML内容成功上传到 COS`,
cosResponse: uploadResult,
},
pairedItem: {
item: itemIndex,
},
});
// 清理临时文件
await fs.unlink(htmlFilePath);
}
}
catch (error) {
const errorMessage = (error instanceof Error) ? error.message : String(error);
const files = await fs.readdir('/home/node/.cache/n8n/public');
returnData.push({
json: {
success: false,
message: `文件上传失败 ${JSON.stringify(files)}`,
error: errorMessage,
},
pairedItem: {
item: itemIndex,
},
});
}
}
return this.prepareOutputData(returnData);
}
}
exports.CosUpload = CosUpload;