This commit is contained in:
2025-10-29 18:44:21 +08:00
parent 98210ef15c
commit da867e258e
10 changed files with 168 additions and 8 deletions

View File

@@ -1,11 +1,45 @@
import { type INodeType, type INodeTypeDescription } from 'n8n-workflow';
import { createHash } from 'crypto';
import {
type INodeType,
type INodeTypeDescription,
IExecuteFunctions,
INodeExecutionData,
} from 'n8n-workflow';
import { distributionDescription } from './resources/distribution';
/**
* 生成 MD5 签名
* @param params 参数数组
* @returns MD5 签名字符串
*/
function getSign(params: (string | number)[]): string {
const paramStr = params.join('');
return createHash('md5').update(paramStr).digest('hex');
}
/**
* 创建认证参数
* @param distributorId 分销商 ID
* @param secretKey 签名密钥
* @returns
*/
function createAuthParams(
distributorId: string,
secretKey: string,
): Record<string, string | number> {
const timeStamp = Math.floor(Date.now() / 1000);
return {
distributor_id: distributorId,
ts: timeStamp,
sign: getSign([distributorId, secretKey, timeStamp]),
};
}
export class GwezzChangdunovel implements INodeType {
description: INodeTypeDescription = {
displayName: 'Gwezz 常读分销',
name: 'gwezzChangdunovel',
icon: { light: 'file:gwezz.svg', dark: 'file:gwezz.dark.svg' },
icon: { light: 'file:../../icons/gwezz.svg', dark: 'file:../../icons/gwezz.dark.svg' },
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
@@ -16,7 +50,7 @@ export class GwezzChangdunovel implements INodeType {
usableAsTool: true,
inputs: ['main'],
outputs: ['main'],
credentials: [],
credentials: [{ name: 'gwezzChangdunovelApi', required: true }],
requestDefaults: {
baseURL: 'https://www.changdunovel.com/novelsale/openapi',
headers: {
@@ -41,4 +75,53 @@ export class GwezzChangdunovel implements INodeType {
...distributionDescription,
],
};
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
const items = this.getInputData();
const returnData: INodeExecutionData[] = [];
const resource = this.getNodeParameter('resource', 0);
const operation = this.getNodeParameter('operation', 0);
const credentials = await this.getCredentials('gwezzChangdunovelApi');
const distributorId = credentials.distributor_id as string;
const secretKey = credentials.secret_key as string;
let responseData;
for (let i = 0; i < items.length; i++) {
try {
if (resource === 'distribution') {
if (operation === 'contentBookMetaV1') {
const bookId = this.getNodeParameter('book_id', i) as string;
const authParams = createAuthParams(distributorId, secretKey);
const qs = {
...authParams,
book_id: bookId,
};
responseData = await this.helpers.httpRequest({
method: 'GET',
url: '/v1/content/book/meta',
qs,
});
}
}
returnData.push({ json: responseData, itemIndex: i });
} catch (error) {
if (this.continueOnFail()) {
returnData.push({
json: {
error: (error as Error).message,
},
itemIndex: i,
});
continue;
}
throw error;
}
}
return [this.helpers.returnJsonArray(returnData)];
}
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 20 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -8,7 +8,7 @@ const showOnlyForDistributionContentBookMetaV1 = {
export const contentBookMetaV1Description: INodeProperties[] = [
{
displayName: '书籍 ID',
name: 'bookId',
name: 'book_id',
type: 'string',
required: true,
default: '',

View File

@@ -18,7 +18,7 @@ export const distributionDescription: INodeProperties[] = [
{
name: '获取书籍信息',
value: 'contentBookMetaV1',
action: 'Get content book metadata',
action: '获取书籍信息',
routing: {
request: {
method: 'GET',