starting to add qm sessions and symbols

This commit is contained in:
Boki 2025-06-16 22:07:40 -04:00
parent e9ff913b7e
commit f05d26d703
13 changed files with 652 additions and 432 deletions

View file

@ -0,0 +1,151 @@
/**
* WebShare Provider for proxy management
*/
import { getLogger } from '@stock-bot/logger';
import type { ProviderConfigWithSchedule } from '@stock-bot/queue';
import { providerRegistry } from '@stock-bot/queue';
const logger = getLogger('webshare-provider');
// In-memory proxy storage
let proxies: string[] = [];
let lastFetchTime: Date | null = null;
let currentProxyIndex = 0;
export function getProxy(): string | null {
if (proxies.length === 0) {
return null;
}
const proxy = proxies[currentProxyIndex];
currentProxyIndex = (currentProxyIndex + 1) % proxies.length;
return proxy;
}
// Initialize and register the WebShare provider
export function initializeWebShareProvider() {
logger.info('Registering WebShare provider with scheduled jobs...');
const webShareProviderConfig: ProviderConfigWithSchedule = {
name: 'webshare',
operations: {
'fetch-proxies': async _payload => {
logger.info('Fetching proxies from WebShare API');
try {
const fetchedProxies = await fetchProxiesFromWebShare();
if (fetchedProxies && fetchedProxies.length > 0) {
proxies = fetchedProxies;
lastFetchTime = new Date();
logger.info('Successfully updated proxy list', {
count: proxies.length,
lastFetchTime: lastFetchTime.toISOString(),
});
return {
success: true,
count: proxies.length,
lastFetchTime: lastFetchTime.toISOString(),
};
} else {
logger.warn('No proxies fetched from WebShare API');
return {
success: false,
count: 0,
error: 'No proxies returned from API',
};
}
} catch (error) {
logger.error('Failed to fetch proxies from WebShare', { error });
return {
success: false,
count: proxies.length,
error: error instanceof Error ? error.message : 'Unknown error',
};
}
},
},
scheduledJobs: [
{
type: 'fetch-proxies',
operation: 'fetch-proxies',
payload: {},
description: 'Fetch proxies from WebShare API',
cronPattern: '*/5 * * * *', // Every 5 minutes
priority: 2,
immediately: true, // Fetch immediately on startup
},
],
};
// Register the provider
providerRegistry.registerWithSchedule(webShareProviderConfig);
logger.info('WebShare provider registered successfully');
}
export const webShareProvider = {
initialize: initializeWebShareProvider,
getProxy,
};
async function fetchProxiesFromWebShare(): Promise<string[] | null> {
try {
const apiKey = process.env.WEBSHARE_API_KEY;
const apiUrl = process.env.WEBSHARE_API_URL;
if (!apiKey || !apiUrl) {
logger.error('Missing WebShare configuration', {
hasApiKey: !!apiKey,
hasApiUrl: !!apiUrl,
});
return null;
}
logger.info('Fetching proxies from WebShare API');
const response = await fetch(`${apiUrl}proxy/list/?mode=direct&page=1&page_size=100`, {
method: 'GET',
headers: {
Authorization: `Token ${apiKey}`,
'Content-Type': 'application/json',
},
});
if (!response.ok) {
logger.error('WebShare API request failed', {
status: response.status,
statusText: response.statusText,
});
return null;
}
const data = await response.json();
if (!data.results || !Array.isArray(data.results)) {
logger.error('Invalid response format from WebShare API', { data });
return null;
}
// Transform proxy data to the format: http://username:password@host:port
const fetchedProxies = data.results.map(
(proxy: { username: string; password: string; proxy_address: string; port: number }) => {
return `http://${proxy.username}:${proxy.password}@${proxy.proxy_address}:${proxy.port}`;
}
);
logger.info('Successfully fetched proxies from WebShare', {
count: fetchedProxies.length,
total: data.count || fetchedProxies.length,
});
// console.log('Fetched Proxies:', fetchedProxies);
return fetchedProxies;
} catch (error) {
logger.error('Failed to fetch proxies from WebShare', { error });
return null;
}
}