File size: 6,418 Bytes
9f1fdb9 dc7f0d5 8128600 50856b4 45751a3 50856b4 45751a3 8128600 b548c5a 8128600 d1c5d0f 8128600 8854423 48b2af6 5488d4e d1c5d0f 5488d4e d1c5d0f 50856b4 d1c5d0f 50856b4 5488d4e 11e6e87 7161e89 9f1fdb9 dc7f0d5 7161e89 8128600 7212c19 11e6e87 7212c19 ece5cde 7212c19 11e6e87 8128600 45751a3 8128600 b548c5a 8128600 8854423 48b2af6 5488d4e a2fc38f 5488d4e 50856b4 5488d4e 11e6e87 8128600 9f1fdb9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | import 'dotenv/config';
export function getConfig() {
const token = process.env.DISCORD_TOKEN?.trim();
const guildId = process.env.GUILD_ID?.trim() || null;
const databaseUrl = process.env.DATABASE_URL?.trim();
const port = Number(process.env.PORT || 7860);
const adminRoleName = process.env.ADMIN_ROLE_NAME?.trim() || 'Admin';
const oddsApiKey = process.env.ODDS_API_KEY?.trim() || null;
const oddsApiBaseUrl = process.env.ODDS_API_BASE_URL?.trim() || 'https://api.the-odds-api.com/v4';
const oddsApiSportKey = process.env.ODDS_API_SPORT_KEY?.trim() || 'baseball_mlb';
const oddsApiRegions = process.env.ODDS_API_REGIONS?.trim() || 'us,us2,us_dfs,us_ex';
const oddsApiBookmakers = (process.env.ODDS_API_BOOKMAKERS?.trim()
|| 'fanduel,draftkings,betmgm,williamhill_us,fanatics,ballybet,hardrockbet,betr_us_dfs,pick6,prizepicks,underdog,kalshi,novig,polymarket,prophetx')
.split(',')
.map((value) => value.trim())
.filter(Boolean);
const oddsApiMarkets = (process.env.ODDS_API_MARKETS?.trim()
|| 'batter_home_runs,batter_hits,batter_total_bases,batter_rbis,batter_runs_scored,batter_hits_runs_rbis,pitcher_strikeouts')
.split(',')
.map((value) => value.trim())
.filter(Boolean);
const circaDropboxUrl = process.env.CIRCA_DROPBOX_URL?.trim() || null;
const scanReportChannelId = process.env.SCAN_REPORT_CHANNEL_ID?.trim() || null;
const scanAlertChannelId = process.env.SCAN_ALERT_CHANNEL_ID?.trim() || null;
const scanMorningTime = process.env.SCAN_MORNING_TIME?.trim() || '08:00';
const scanMorningFallbackTime = process.env.SCAN_MORNING_FALLBACK_TIME?.trim() || '09:45';
const scanTimeZone = process.env.SCAN_TIMEZONE?.trim() || 'America/Chicago';
const scanMinBooks = Number(process.env.SCAN_MIN_BOOKS || 6);
const scanDisagreementThreshold = Number(process.env.SCAN_DISAGREEMENT_THRESHOLD || 0.08);
const scanAlertCooldownMinutes = Number(process.env.SCAN_ALERT_COOLDOWN_MINUTES || 180);
const scanFrequencyMinutes = Number(process.env.SCAN_FREQUENCY_MINUTES || 15);
const scanHttpTimeoutMs = Number(process.env.SCAN_HTTP_TIMEOUT_MS || 15000);
const directOddsCacheTtlMs = Number(process.env.DIRECT_ODDS_CACHE_TTL_MS || 60000);
const sharpEdgeAlertThreshold = Number(process.env.SHARP_EDGE_ALERT_THRESHOLD || 0.04);
const sharpEdgeAlertMinBooks = Number(process.env.SHARP_EDGE_ALERT_MIN_BOOKS || 6);
const staleBookAlertThreshold = Number(process.env.STALE_BOOK_ALERT_THRESHOLD || 0.025);
const reverseAlertThreshold = Number(process.env.REVERSE_ALERT_THRESHOLD || 0.03);
const dfsScanMinBooks = Number(process.env.DFS_SCAN_MIN_BOOKS || 4);
const dfsEdgeAlertThreshold = Number(process.env.DFS_EDGE_ALERT_THRESHOLD || sharpEdgeAlertThreshold);
const dfsReverseAlertThreshold = Number(process.env.DFS_REVERSE_ALERT_THRESHOLD || reverseAlertThreshold);
const dfsStaleAlertThreshold = Number(process.env.DFS_STALE_ALERT_THRESHOLD || staleBookAlertThreshold);
const exchangeScanMinBooks = Number(process.env.EXCHANGE_SCAN_MIN_BOOKS || 4);
const exchangeEdgeAlertThreshold = Number(process.env.EXCHANGE_EDGE_ALERT_THRESHOLD || sharpEdgeAlertThreshold);
const exchangeReverseAlertThreshold = Number(process.env.EXCHANGE_REVERSE_ALERT_THRESHOLD || reverseAlertThreshold);
const exchangeStaleAlertThreshold = Number(process.env.EXCHANGE_STALE_ALERT_THRESHOLD || staleBookAlertThreshold);
const marketBoardDefaultLimit = Number(process.env.MARKET_BOARD_DEFAULT_LIMIT || 10);
const sharpEdgeAlertsEnabled = process.env.SHARP_EDGE_ALERTS_ENABLED?.trim() !== 'false';
const staleBookAlertsEnabled = process.env.STALE_BOOK_ALERTS_ENABLED?.trim() !== 'false';
const reverseAlertsEnabled = process.env.REVERSE_ALERTS_ENABLED?.trim() !== 'false';
const circaChannelId = process.env.CIRCA_CHANNEL_ID?.trim() || null;
const circaDailyTime = process.env.CIRCA_DAILY_TIME?.trim() || '09:30';
const circaTimeZone = process.env.CIRCA_TIMEZONE?.trim() || 'America/Chicago';
const circaRetryMinutes = Number(process.env.CIRCA_RETRY_MINUTES || 30);
const circaMovementFrequencyMinutes = Number(process.env.CIRCA_MOVEMENT_FREQUENCY_MINUTES || 5);
const matchupHostedBaseUrl = process.env.MLB_HOSTED_BASE_URL?.trim() || null;
const matchupArtifactCacheTtlMs = Number(process.env.MATCHUP_ARTIFACT_CACHE_TTL_MS || 300000);
const matchupFallbackDays = Number(process.env.MATCHUP_FALLBACK_DAYS || 7);
if (!token) {
throw new Error('Missing DISCORD_TOKEN in environment.');
}
if (!databaseUrl) {
throw new Error('Missing DATABASE_URL in environment.');
}
return {
token,
guildId,
databaseUrl,
port,
adminRoleName,
matchups: {
enabled: Boolean(matchupHostedBaseUrl || databaseUrl),
hosted: {
baseUrl: matchupHostedBaseUrl,
cacheTtlMs: matchupArtifactCacheTtlMs,
fallbackDays: matchupFallbackDays,
},
databaseUrl,
},
scanner: {
enabled: Boolean(
circaDropboxUrl
&& circaChannelId
|| oddsApiKey
&& scanReportChannelId
&& scanAlertChannelId
&& circaDropboxUrl
),
oddsWorkflowEnabled: Boolean(
oddsApiKey
&& scanReportChannelId
&& scanAlertChannelId
&& circaDropboxUrl
),
circaWorkflowEnabled: Boolean(circaDropboxUrl && circaChannelId),
oddsApiKey,
oddsApiBaseUrl,
oddsApiSportKey,
oddsApiRegions,
oddsApiBookmakers,
oddsApiMarkets,
circaDropboxUrl,
scanReportChannelId,
scanAlertChannelId,
scanMorningTime,
scanMorningFallbackTime,
scanTimeZone,
scanMinBooks,
scanDisagreementThreshold,
scanAlertCooldownMinutes,
scanFrequencyMinutes,
scanHttpTimeoutMs,
directOddsCacheTtlMs,
sharpEdgeAlertThreshold,
sharpEdgeAlertMinBooks,
staleBookAlertThreshold,
reverseAlertThreshold,
dfsScanMinBooks,
dfsEdgeAlertThreshold,
dfsReverseAlertThreshold,
dfsStaleAlertThreshold,
exchangeScanMinBooks,
exchangeEdgeAlertThreshold,
exchangeReverseAlertThreshold,
exchangeStaleAlertThreshold,
marketBoardDefaultLimit,
sharpEdgeAlertsEnabled,
staleBookAlertsEnabled,
reverseAlertsEnabled,
circaChannelId,
circaDailyTime,
circaTimeZone,
circaRetryMinutes,
circaMovementFrequencyMinutes,
},
};
}
|