117 lines
3.4 KiB
TypeScript
117 lines
3.4 KiB
TypeScript
import { getRandomUserAgent } from '@stock-bot/utils';
|
|
import type { CeoHandler } from '../ceo.handler';
|
|
|
|
export async function processIndividualSymbol(
|
|
this: CeoHandler,
|
|
payload: any,
|
|
_context: any
|
|
): Promise<unknown> {
|
|
const { ceoId, symbol, timestamp } = payload;
|
|
const proxy = this.proxy?.getProxy();
|
|
if (!proxy) {
|
|
this.logger.warn('No proxy available for processing individual CEO symbol');
|
|
return;
|
|
}
|
|
|
|
this.logger.debug('Processing individual CEO symbol', {
|
|
ceoId,
|
|
timestamp,
|
|
});
|
|
try {
|
|
// Fetch detailed information for the individual symbol
|
|
const response = await this.http.get(
|
|
`https://api.ceo.ca/api/get_spiels?channel=${ceoId}&load_more=top` +
|
|
(timestamp ? `&until=${timestamp}` : ''),
|
|
{
|
|
proxy: proxy,
|
|
headers: {
|
|
'User-Agent': getRandomUserAgent(),
|
|
},
|
|
}
|
|
);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to fetch details for ceoId ${ceoId}: ${response.statusText}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
const spielCount = data.spiels.length;
|
|
if (spielCount === 0) {
|
|
this.logger.warn(`No spiels found for ceoId ${ceoId}`);
|
|
return null; // No data to process
|
|
}
|
|
const latestSpielTime = data.spiels[0]?.timestamp;
|
|
const posts = data.spiels.map((spiel: any) => ({
|
|
ceoId,
|
|
spiel: spiel.spiel,
|
|
spielReplyToId: spiel.spiel_reply_to_id,
|
|
spielReplyTo: spiel.spiel_reply_to,
|
|
spielReplyToName: spiel.spiel_reply_to_name,
|
|
spielReplyToEdited: spiel.spiel_reply_to_edited,
|
|
userId: spiel.user_id,
|
|
name: spiel.name,
|
|
timestamp: spiel.timestamp,
|
|
spielId: spiel.spiel_id,
|
|
color: spiel.color,
|
|
parentId: spiel.parent_id,
|
|
publicId: spiel.public_id,
|
|
parentChannel: spiel.parent_channel,
|
|
parentTimestamp: spiel.parent_timestamp,
|
|
votes: spiel.votes,
|
|
editable: spiel.editable,
|
|
edited: spiel.edited,
|
|
featured: spiel.featured,
|
|
verified: spiel.verified,
|
|
fake: spiel.fake,
|
|
bot: spiel.bot,
|
|
voted: spiel.voted,
|
|
flagged: spiel.flagged,
|
|
ownSpiel: spiel.own_spiel,
|
|
score: spiel.score,
|
|
savedId: spiel.saved_id,
|
|
savedTimestamp: spiel.saved_timestamp,
|
|
poll: spiel.poll,
|
|
votedInPoll: spiel.voted_in_poll,
|
|
}));
|
|
|
|
await this.mongodb.batchUpsert('ceoPosts', posts, ['spielId']);
|
|
this.logger.info(`Fetched ${spielCount} spiels for ceoId ${ceoId}`);
|
|
|
|
// Update Shorts
|
|
const shortRes = await this.http.get(
|
|
`https://api.ceo.ca/api/short_positions/one?symbol=${symbol}`,
|
|
{
|
|
proxy: proxy,
|
|
headers: {
|
|
'User-Agent': getRandomUserAgent(),
|
|
},
|
|
}
|
|
);
|
|
|
|
if (shortRes.ok) {
|
|
const shortData = await shortRes.json();
|
|
if (shortData && shortData.positions) {
|
|
await this.mongodb.batchUpsert('ceoShorts', shortData.positions, ['id']);
|
|
}
|
|
|
|
await this.scheduleOperation('process-individual-symbol', {
|
|
ceoId: ceoId,
|
|
timestamp: latestSpielTime,
|
|
}, {priority: 0});
|
|
}
|
|
|
|
this.logger.info(
|
|
`Successfully processed channel ${ceoId} and added channel ${ceoId} at timestamp ${latestSpielTime}`
|
|
);
|
|
|
|
return { ceoId, spielCount, timestamp };
|
|
} catch (error) {
|
|
this.logger.error(`Failed to process individual symbol ${symbol}`, {
|
|
error,
|
|
ceoId,
|
|
timestamp,
|
|
});
|
|
throw error;
|
|
}
|
|
}
|