n8n-nodes-exchangerate-api
Version:
n8n community node for the Exchange Rate API
363 lines • 16 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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExchangeRateAPI = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const currencyCodes = __importStar(require("currency-codes"));
const getCurrencyOptions = () => {
const codes = currencyCodes.codes();
return codes.map((code) => {
const details = currencyCodes.code(code);
if (!details) {
return {
name: code,
value: code,
description: 'Currency code',
};
}
return {
name: `${code} - ${details.currency}`,
value: code,
description: `${details.currency} (${details.countries.join(', ')})`,
};
});
};
const currencyOptions = getCurrencyOptions();
class ExchangeRateAPI {
constructor() {
this.description = {
displayName: 'ExchangeRate API',
name: 'exchangeRateAPI',
icon: 'file:exchangerate.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}',
description: 'Consume ExchangeRate API',
defaults: {
name: 'ExchangeRate API',
},
inputs: [{ type: "main" }],
outputs: [{ type: "main" }],
credentials: [
{
name: 'exchangeRateCredentialsApi',
required: true,
},
],
codex: {
categories: ['Finance'],
resources: {
primaryDocumentation: [
{
url: 'https://docs.n8n.io/integrations/community-nodes/nodes/n8n-nodes-exchangerate-api/',
},
],
},
subcategories: {
Finance: ['Currency Exchange'],
},
},
properties: [
{
displayName: 'Resource',
name: 'resource',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Exchange Rate',
value: 'exchangeRate',
},
],
default: 'exchangeRate',
required: true,
description: 'Resource to consume',
},
{
displayName: 'Operation',
name: 'operation',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Get Exchange Rates',
value: 'getExchangeRates',
description: 'Get latest exchange rates from a base currency',
action: 'Get latest exchange rates',
},
{
name: 'Convert Value',
value: 'convertValue',
description: 'Convert a value from one currency to another',
action: 'Convert a value from one currency to another',
},
],
default: 'getExchangeRates',
},
{
displayName: 'Base Currency',
name: 'baseCurrency',
type: 'options',
options: currencyOptions,
default: 'USD',
required: true,
displayOptions: {
show: {
operation: ['getExchangeRates'],
},
},
description: 'The three-letter currency code to get exchange rates for',
},
{
displayName: 'Amount',
name: 'amount',
type: 'number',
default: 1,
required: true,
displayOptions: {
show: {
operation: ['convertValue'],
},
},
description: 'The amount to convert',
},
{
displayName: 'From Currency',
name: 'fromCurrency',
type: 'options',
options: currencyOptions,
default: 'USD',
required: true,
displayOptions: {
show: {
operation: ['convertValue'],
},
},
description: 'The three-letter currency code to convert from',
},
{
displayName: 'To Currency',
name: 'toCurrency',
type: 'options',
options: currencyOptions,
default: 'EUR',
required: true,
displayOptions: {
show: {
operation: ['convertValue'],
},
},
description: 'The three-letter currency code to convert to',
},
{
displayName: 'Use Conversion Fee',
name: 'useConversionFee',
type: 'boolean',
default: false,
displayOptions: {
show: {
operation: ['convertValue'],
},
},
description: 'Whether to apply a percentage fee to the conversion',
},
{
displayName: 'Conversion Fee (%)',
name: 'conversionFee',
type: 'number',
default: '',
displayOptions: {
show: {
operation: ['convertValue'],
useConversionFee: [true],
},
},
description: 'Percentage fee to add to the conversion',
},
{
displayName: 'Use Decimal Places',
name: 'useDecimalPlaces',
type: 'boolean',
default: false,
displayOptions: {
show: {
operation: ['convertValue'],
},
},
description: 'Whether to round the result to specific decimal places',
},
{
displayName: 'Decimal Places',
name: 'decimalPlaces',
type: 'number',
default: '',
displayOptions: {
show: {
operation: ['convertValue'],
useDecimalPlaces: [true],
},
},
description: 'Number of decimal places to round the result to',
},
{
displayName: 'Return Detailed Response',
name: 'detailedResponse',
type: 'boolean',
default: true,
displayOptions: {
show: {
operation: ['convertValue'],
},
},
description: 'Whether to return a detailed response or just the converted amount',
},
],
};
}
async execute() {
const items = this.getInputData();
const returnData = [];
let responseData = {};
const operation = this.getNodeParameter('operation', 0);
const credentials = await this.getCredentials('exchangeRateCredentialsApi');
const apiKey = credentials.apiKey;
if (!apiKey || apiKey.trim() === '') {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'API key is empty. Please provide a valid API key in the credentials.');
}
for (let i = 0; i < items.length; i++) {
try {
if (operation === 'getExchangeRates') {
const baseCurrency = this.getNodeParameter('baseCurrency', i);
const baseUrl = 'https://v6.exchangerate-api.com/v6';
const url = `${baseUrl}/latest/${baseCurrency}`;
const headers = {
Authorization: `Bearer ${apiKey}`,
};
const options = {
method: 'GET',
uri: url,
headers: headers,
json: true,
};
responseData = await this.helpers.request(options);
if (responseData.result === 'success') {
if (!responseData.conversion_rates ||
typeof responseData.conversion_rates !== 'object') {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid API response: conversion_rates data is missing or has an unexpected format');
}
}
else {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `API Error: ${responseData.error_type || 'Unknown error'} - ${responseData.error_message || 'No error message provided'}`, { itemIndex: i });
}
}
else if (operation === 'convertValue') {
const amount = this.getNodeParameter('amount', i);
if (amount <= 0) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Amount must be a positive number');
}
const fromCurrency = this.getNodeParameter('fromCurrency', i);
const toCurrency = this.getNodeParameter('toCurrency', i);
const useConversionFee = this.getNodeParameter('useConversionFee', i);
const useDecimalPlaces = this.getNodeParameter('useDecimalPlaces', i);
let conversionFee = 0;
if (useConversionFee) {
conversionFee = this.getNodeParameter('conversionFee', i);
}
let decimalPlaces;
if (useDecimalPlaces) {
decimalPlaces = this.getNodeParameter('decimalPlaces', i);
if (decimalPlaces < 0 || !Number.isInteger(decimalPlaces)) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Decimal places must be a non-negative integer');
}
}
const baseUrl = 'https://v6.exchangerate-api.com/v6';
const url = `${baseUrl}/latest/${fromCurrency}`;
const headers = {
Authorization: `Bearer ${apiKey}`,
};
const options2 = {
method: 'GET',
uri: url,
headers: headers,
json: true,
};
responseData = await this.helpers.request(options2);
if (responseData.result === 'success') {
if (!responseData.conversion_rates ||
typeof responseData.conversion_rates !== 'object') {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid API response: conversion_rates data is missing or has an unexpected format');
}
const rates = responseData.conversion_rates;
if (!rates[toCurrency]) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Currency ${toCurrency} not found in exchange rates`);
}
const exchangeRate = rates[toCurrency];
const convertedValue = amount * exchangeRate;
let valueWithFee = convertedValue;
if (useConversionFee) {
valueWithFee = convertedValue * (1 + conversionFee / 100);
}
let roundedValue = valueWithFee;
if (useDecimalPlaces && decimalPlaces !== undefined) {
roundedValue = Number(valueWithFee.toFixed(decimalPlaces));
}
const detailedResponse = this.getNodeParameter('detailedResponse', i);
if (detailedResponse) {
responseData = {
result: 'success',
from: fromCurrency,
to: toCurrency,
amount: amount,
exchange_rate: exchangeRate,
conversion_fee_percentage: useConversionFee ? conversionFee : 0,
converted_amount: roundedValue,
time_last_update_utc: responseData.time_last_update_utc,
};
}
else {
responseData = {
converted_amount: roundedValue,
};
}
}
else {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `API Error: ${responseData.error_type || 'Unknown error'} - ${responseData.error_message || 'No error message provided'}`, { itemIndex: i });
}
}
returnData.push(responseData);
}
catch (error) {
if (this.continueOnFail()) {
returnData.push({ error: error.message });
continue;
}
throw error;
}
}
return [this.helpers.returnJsonArray(returnData)];
}
}
exports.ExchangeRateAPI = ExchangeRateAPI;
//# sourceMappingURL=ExchangeRateAPI.node.js.map