The Streamer Alerts Bot is designed to be extensible. Follow this guide to add support for new streaming platforms.
Overview
Adding a new platform requires:
Creating a platform checker function
Defining platform configuration
Registering the platform in the platform registry
Adding platform constants (color, emoji, URL template)
Every platform must implement the PlatformChecker type:
export type PlatformChecker = ( username : string ) => Promise < LiveStatus >;
The LiveStatus interface defines what data your checker should return:
export interface LiveStatus {
/** Whether the streamer is currently live */
isLive : boolean ;
/** Platform name */
platform : Platform ;
/** Username checked */
username : string ;
/** Stream title */
title ?: string ;
/** Current viewer count */
viewers ?: number ;
/** Follower/subscriber count */
followers ?: number ;
/** Stream thumbnail URL */
thumbnail ?: string ;
/** Profile image URL */
profileImage ?: string ;
/** Stream start time (ISO timestamp) */
startedAt ?: string ;
/** Direct URL to the stream */
url : string ;
/** Verified status */
verified ?: boolean ;
/** Bio/description */
bio ?: string ;
/** Stream category/game */
category ?: string ;
/** Category icon URL */
categoryIcon ?: string ;
/** Stream tags */
tags ?: string [];
/** Stream language */
language ?: string ;
/** Whether stream is marked as mature */
isMature ?: boolean ;
/** Error message if check failed */
error ?: string ;
}
Step-by-Step Implementation
Create the platform checker file
Create a new file in src/platforms/ named after your platform (e.g., newplatform.ts). Here’s the basic structure using Kick as an example: import type { LiveStatus } from "./types.js" ;
import { cleanString } from "../utils/formatters.js" ;
import { logger } from "../utils/logger.js" ;
/**
* Check if a Kick streamer is live via API fetch
*/
export async function checkKickLive ( username : string ) : Promise < LiveStatus > {
const url = `https://kick.com/ ${ username } ` ;
const apiUrl = `https://kick.com/api/v2/channels/ ${ username } ` ;
const baseResult : LiveStatus = {
isLive: false ,
platform: "kick" ,
username ,
url ,
};
try {
const response = await fetch ( apiUrl , {
headers: {
"User-Agent" :
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" ,
Accept: "application/json" ,
},
});
if ( ! response . ok ) {
if ( response . status === 404 ) {
return baseResult ;
}
throw new Error ( `HTTP ${ response . status } ` );
}
const data = await response . json ();
// Check if livestream exists and is live
if ( data . livestream ?. is_live ) {
return {
isLive: true ,
platform: "kick" ,
username: data . user ?. username ?? username ,
title: data . livestream . session_title ?? undefined ,
viewers: data . livestream . viewer_count ?? undefined ,
followers: data . followers_count ?? undefined ,
profileImage: data . user ?. profile_pic ?? undefined ,
startedAt: data . livestream . start_time ?? undefined ,
url ,
verified: data . verified ?? false ,
category: data . livestream . categories ?.[ 0 ]?. name ,
tags: data . livestream . tags ,
language: data . livestream . language ,
isMature: data . livestream . is_mature ,
};
}
// Not live, but return profile data
return {
... baseResult ,
followers: data . followers_count ?? undefined ,
profileImage: data . user ?. profile_pic ?? undefined ,
verified: data . verified ?? false ,
};
} catch ( error ) {
logger . error ( `Error checking Kick live status for ${ username } :` , error );
return { ... baseResult , error: String ( error ) };
}
}
Key points:
Always return a LiveStatus object
Set isLive: false by default
Handle errors gracefully with try/catch
Return partial data even when the streamer is offline
Use the logger utility for error logging
Define API response types
Define TypeScript interfaces for the API response to ensure type safety: interface KickChannelResponse {
id : number ;
slug : string ;
followers_count : number ;
verified : boolean ;
user : {
username : string ;
profile_pic : string ;
};
livestream : {
session_title : string ;
is_live : boolean ;
viewer_count : number ;
start_time : string ;
language : string ;
is_mature : boolean ;
tags : string [];
categories : Array <{ name : string }>;
} | null ;
}
Add platform type
Update the Platform type in src/types/streamer.ts: export type Platform = "kick" | "twitch" | "youtube" | "rumble" | "tiktok" | "newplatform" ;
Register the platform
Add your platform to the registry in src/platforms/index.ts: import { checkNewPlatformLive } from "./newplatform.js" ;
export const platformCheckers : Record < Platform , PlatformChecker > = {
kick: checkKickLive ,
twitch: checkTwitchLive ,
youtube: checkYouTubeLive ,
rumble: checkRumbleLive ,
tiktok: checkTikTokLive ,
newplatform: checkNewPlatformLive , // Add your platform here
};
// Also export the checker
export { checkNewPlatformLive } from "./newplatform.js" ;
Add platform constants
Add platform configuration in src/utils/constants.ts: export const PLATFORMS = {
newplatform: {
name: "NewPlatform" ,
color: 0x00FF00 , // Hex color as number
emoji: "🟢" ,
urlTemplate: "https://newplatform.com/{username}" ,
},
// ... other platforms
};
Platform branding guidelines:
Use the platform’s official brand color
Choose an appropriate emoji (or use the platform’s emoji if available)
Ensure the URL template uses {username} as a placeholder
Update slash command choices
Add your platform to the /streamer add command choices in src/commands/streamer.ts: . addStringOption ( option =>
option
. setName ( 'platform' )
. setDescription ( 'Streaming platform' )
. setRequired ( true )
. addChoices (
{ name: '🟢 Kick' , value: 'kick' },
{ name: '🟣 Twitch' , value: 'twitch' },
{ name: '🔴 YouTube' , value: 'youtube' },
{ name: '🟢 Rumble' , value: 'rumble' },
{ name: '⚫ TikTok' , value: 'tiktok' },
{ name: '🟢 NewPlatform' , value: 'newplatform' } // Add here
)
)
Test your implementation
Test your platform checker: Test locally
Type check
Lint
Test with a known live streamer and a non-live streamer to ensure both cases work correctly.
Implementation Patterns
Using Public APIs
If the platform has a public API:
const apiUrl = `https://api.platform.com/users/ ${ username } /live` ;
const response = await fetch ( apiUrl , {
headers: {
'Accept' : 'application/json' ,
'User-Agent' : 'Mozilla/5.0 ...'
}
});
const data = await response . json ();
HTML Parsing (when no API available)
If you need to parse HTML:
const response = await fetch ( `https://platform.com/ ${ username } ` );
const html = await response . text ();
// Use regex or a parser to extract data
const isLiveMatch = html . match ( /"isLive": ( true | false ) / );
const isLive = isLiveMatch ?.[ 1 ] === 'true' ;
HTML parsing is fragile and can break if the platform changes their HTML structure. Always prefer official APIs when available.
Error Handling
Always handle common error cases:
try {
const response = await fetch ( apiUrl );
// User not found
if ( response . status === 404 ) {
return baseResult ;
}
// Other errors
if ( ! response . ok ) {
throw new Error ( `HTTP ${ response . status } ` );
}
// Process data...
} catch ( error ) {
logger . error ( `Error checking platform:` , error );
return { ... baseResult , error: String ( error ) };
}
Best Practices
Use appropriate HTTP headers
Return all available data
Even when a streamer is offline, return their profile data (followers, profile image, etc.) for a better user experience.
For startedAt and other timestamps, use ISO 8601 format: startedAt : new Date ( timestamp ). toISOString ()
Testing Checklist
Before submitting your platform implementation:
Need Help?
If you’re stuck or have questions: