n8n-nodes-duckduckgo-search
Version:
A powerful and comprehensive n8n community node that seamlessly integrates DuckDuckGo search capabilities into your workflows. Search the web, find images, discover news, and explore videos - all with privacy-focused, reliable results.
229 lines (228 loc) • 8.32 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.searchVideosWithAPI = exports.searchNewsWithAPI = exports.searchImagesWithAPI = exports.searchWithAPI = exports.SearchAPIClient = void 0;
const axios_1 = __importDefault(require("axios"));
class SearchAPIClient {
constructor(apiKey) {
this.baseUrl = 'https://www.searchapi.io/api/v1/search';
this.apiKey = apiKey || process.env.SEARCHAPI_KEY || 'demo-key';
}
async search(options) {
var _a, _b, _c;
const url = new URL(this.baseUrl);
url.searchParams.set('engine', 'duckduckgo');
url.searchParams.set('q', options.q);
if (options.locale) {
url.searchParams.set('locale', options.locale);
}
if (options.safe) {
url.searchParams.set('safe', options.safe);
}
if (options.time_period) {
url.searchParams.set('time_period', options.time_period);
}
if (options.next_page_token) {
url.searchParams.set('next_page_token', options.next_page_token);
}
const headers = {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json',
'User-Agent': 'n8n-duckduckgo-node/1.0'
};
try {
const response = await axios_1.default.get(url.toString(), {
headers,
timeout: 30000,
});
return response.data;
}
catch (error) {
if (axios_1.default.isAxiosError(error)) {
const status = ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) || 'unknown';
const statusText = ((_b = error.response) === null || _b === void 0 ? void 0 : _b.statusText) || 'unknown';
const errorData = ((_c = error.response) === null || _c === void 0 ? void 0 : _c.data) || error.message;
throw new Error(`SearchAPI request failed: ${status} ${statusText} - ${errorData}`);
}
if (error instanceof Error) {
throw new Error(`SearchAPI error: ${error.message}`);
}
throw new Error('Unknown SearchAPI error occurred');
}
}
convertToLegacyFormat(response) {
const results = [];
if (response.organic_results) {
for (const result of response.organic_results) {
results.push({
title: result.title,
url: result.link,
description: result.snippet,
hostname: this.extractHostname(result.link),
body: result.snippet,
});
}
}
return {
results,
vqd: null,
noResults: results.length === 0,
metadata: response.search_metadata || {},
originalResponse: response
};
}
convertImageResults(response) {
const results = [];
if (response.inline_images) {
for (const image of response.inline_images) {
results.push({
title: image.title,
image: image.original.link,
thumbnail: image.thumbnail,
url: image.source.link,
source: image.source.name,
height: image.original.height,
width: image.original.width,
});
}
}
return {
results,
vqd: null,
noResults: results.length === 0,
};
}
convertNewsResults(response) {
const results = [];
if (response.news_results) {
for (const news of response.news_results) {
results.push({
title: news.title,
url: news.link,
description: news.snippet,
date: news.date,
source: news.source,
image: news.thumbnail,
body: news.snippet,
});
}
}
return {
results,
vqd: null,
noResults: results.length === 0,
};
}
convertVideoResults(response) {
const results = [];
if (response.inline_videos) {
for (const video of response.inline_videos) {
results.push({
title: video.title,
url: video.link,
description: `Video from ${video.source}`,
duration: 'Unknown',
uploaded: video.date,
views: video.views || 0,
uploader: video.uploader || video.channel,
thumbnail: video.thumbnail,
embed: video.video_link,
});
}
}
return {
results,
vqd: null,
noResults: results.length === 0,
};
}
extractHostname(url) {
try {
return new URL(url).hostname;
}
catch {
return '';
}
}
static convertSafeSearch(value) {
switch (value) {
case 0:
return 'on';
case -1:
return 'moderate';
case -2:
return 'off';
default:
return 'moderate';
}
}
static convertTimePeriod(value) {
switch (value) {
case 'pastDay':
case 'd':
return 'past_day';
case 'pastWeek':
case 'w':
return 'past_week';
case 'pastMonth':
case 'm':
return 'past_month';
case 'pastYear':
case 'y':
return 'past_year';
case 'anyTime':
case 'a':
default:
return 'any_time';
}
}
}
exports.SearchAPIClient = SearchAPIClient;
const searchWithAPI = async (query, options = {}) => {
const client = new SearchAPIClient();
const searchOptions = {
q: query,
locale: options.locale || 'en-us',
safe: SearchAPIClient.convertSafeSearch(options.safeSearch || -1),
time_period: SearchAPIClient.convertTimePeriod(options.time),
};
const response = await client.search(searchOptions);
return client.convertToLegacyFormat(response);
};
exports.searchWithAPI = searchWithAPI;
const searchImagesWithAPI = async (query, options = {}) => {
const client = new SearchAPIClient();
const searchOptions = {
q: `${query} images`,
locale: options.locale || 'en-us',
safe: SearchAPIClient.convertSafeSearch(options.safeSearch || -1),
};
const response = await client.search(searchOptions);
return client.convertImageResults(response);
};
exports.searchImagesWithAPI = searchImagesWithAPI;
const searchNewsWithAPI = async (query, options = {}) => {
const client = new SearchAPIClient();
const searchOptions = {
q: `${query} news`,
locale: options.locale || 'en-us',
safe: SearchAPIClient.convertSafeSearch(options.safeSearch || -1),
time_period: SearchAPIClient.convertTimePeriod(options.time),
};
const response = await client.search(searchOptions);
return client.convertNewsResults(response);
};
exports.searchNewsWithAPI = searchNewsWithAPI;
const searchVideosWithAPI = async (query, options = {}) => {
const client = new SearchAPIClient();
const searchOptions = {
q: `${query} videos`,
locale: options.locale || 'en-us',
safe: SearchAPIClient.convertSafeSearch(options.safeSearch || -1),
};
const response = await client.search(searchOptions);
return client.convertVideoResults(response);
};
exports.searchVideosWithAPI = searchVideosWithAPI;