The card image service has been successfully implemented as a standalone, encapsulated service that can be imported and used from the main project.
card-image-service/
βββ src/
β βββ index.ts # Main exports
β βββ generateAndSendCard.ts # Core service logic
β βββ config.ts # Configuration loader
β βββ logger.ts # Logging utilities
β βββ cache.ts # Image caching system
β βββ telegram.ts # Telegram API service
β βββ types.ts # TypeScript interfaces
β βββ bot.ts # Standalone bot
β βββ image/
β βββ composer.ts # Image generation logic
βββ assets/
β βββ card/ # Card images by style
β β βββ general/ # General style cards
β βββ card_area/ # Background images by area
βββ package.json # Dependencies and scripts
βββ tsconfig.json # TypeScript configuration
βββ env.example # Environment variables template
βββ README.md # Comprehensive documentation
- Uses Sharp library for high-quality image composition
- Supports multiple card styles (
general,blue,red, etc.) - Supports multiple background areas (
general,club, etc.) - Automatic layout calculation based on card count
- Debug tag support for image identification
- Intelligent caching with 24-hour expiry
- Hash-based cache keys for identical requests
- JSON file storage for persistence
- Automatic cache cleanup of expired entries
- Dedicated bot for image sending
- Channel-based image delivery
- File ID and message ID tracking
- Error handling and retry logic
- Independent bot with health check commands
- Cache management commands (
/cache,/clearcache) - Status monitoring (
/status)
import { generateAndSendCardImage } from '@/utils/cardImageService';
// Generate and send card image
const messageId = await generateAndSendCardImage(
['ace_of_hearts', 'king_of_spades', 'queen_of_diamonds'],
'general', // style
'club', // area
'Player Hand' // debug tag
);import { generateAndSendCard } from './card-image-service/src';
const messageId = await generateAndSendCard(
['2_of_clubs', '3_of_hearts'],
'general',
'general',
'Test Hand'
);grammy- Telegram bot frameworksharp- Image processing librarydotenv- Environment variable managementpino- Structured logging
typescript- Type checking and compilationeslint- Code lintingvitest- Testing framework
BOT_TOKEN=your_card_image_bot_token_here
TARGET_CHANNEL_ID=@your_channel_username_or_id
LOG_LEVEL=infoassets/
βββ card/
β βββ general/ # Style name
β βββ 2_of_clubs.png
β βββ 3_of_clubs.png
β βββ ace_of_hearts.png
β βββ ...
βββ card_area/
βββ general.png # Area name
βββ club.png
βββ ...
cd card-image-service
pnpm install
pnpm build
pnpm test# Start the standalone bot
pnpm dev
# Test image generation
pnpm tsx src/test.tsCreated src/utils/cardImageService.ts as a clean interface:
- Dynamic loading to avoid build-time dependencies
- Proper error handling and logging
- Type-safe function signatures
Example integration in poker stake handler:
// Example usage (commented out for now)
// import { generateAndSendCardImage } from '@/utils/cardImageService';
// In game logic:
// const messageId = await generateAndSendCardImage(
// playerCards,
// 'general',
// 'club',
// `Player ${playerName} Hand`
// );- Completely independent service
- No reverse dependencies
- Self-contained configuration
- Intelligent caching system
- Avoids regenerating identical images
- Efficient image composition
- Multiple card styles and backgrounds
- Debug tags for identification
- Standalone or integrated usage
- Clean separation of concerns
- Comprehensive logging
- Type-safe interfaces
Place actual card images in the assets structure:
card-image-service/assets/card/general/
βββ 2_of_clubs.png
βββ 3_of_clubs.png
βββ ace_of_hearts.png
βββ ... (all 52 cards)
Place background images in:
card-image-service/assets/card_area/
βββ general.png
βββ club.png
βββ ... (other backgrounds)
cd card-image-service
cp env.example .env
# Edit .env with your bot token and channel ID# Build the service
cd card-image-service && pnpm build
# Test from main project
cd ..
pnpm type-check- Card images must be placed in the correct directory structure
- Image names must match the card array parameters exactly
- PNG format is recommended for transparency support
- Requires a separate bot token for the card image service
- Bot must have permission to send messages to the target channel
- Channel ID must be correctly configured
- Cache entries expire after 24 hours
- Cache is stored in
card-image-service/cache.json - Cache can be cleared via bot commands or programmatically
- Missing images throw descriptive errors
- Telegram API failures are handled gracefully
- Cache failures don't prevent image generation
- README.md - Comprehensive usage guide
- example-usage.ts - Practical examples
- test.ts - Testing utilities
- types.ts - Complete type definitions
- β Service Implementation - Complete
- β TypeScript Compilation - Working
- β Dependencies - Installed
- β Documentation - Comprehensive
- β Integration Wrapper - Created
- β³ Asset Setup - Requires card images
- β³ Environment Configuration - Requires bot token
- β³ Testing - Ready for testing with assets
The card image service is now ready for use! Just add the card images and configure the environment variables to start generating and sending card images to your Telegram channel.