The Cross-Promotion Problem
Every mobile game studio knows cross-promotion works. You have Game A with 10,000 players, you show them an ad for Game B, and some percentage installs it. The math is simple. The execution is not.
Most studios handle cross-promotion through ad networks, which means:
- You pay for impressions you're serving to your own users
- You're locked into SDK integrations for each network
- You can't easily A/B test creatives across your own portfolio
- Reporting is fragmented across multiple dashboards
At CCFish, we wanted a different approach: a self-owned, zero-cost cross-promotion engine that lives inside our existing Telegram Mini App infrastructure. Here's how we built it.
The Architecture: A Bot as a Storefront
The PlayableTon bot acts as a game portfolio manager. When a user opens the bot, they see a menu of all available games:
```
/start → Welcome to PlayableTon!
Choose your game:
🎰 Casino Slot — Spin to win
🐟 CCFish — Catch, collect, compete
🎮 Crisis Empire — Build your empire
🐰 ChezBot — Bunny adventure
🎲 SlotX — Classic slots
```
Each game is a Cloudflare Pages deployment with Telegram Mini App SDK integration. The bot is powered by grammY + Prisma on Cloudflare Workers, with game metadata stored in D1.
How Cross-Promotion Works
1. In-Game Sharing (Viral Loop)
Each game's TMA includes a share button that uses Telegram's built-in share API:
```javascript
// TMA share integration
function shareGame() {
Telegram.WebApp.shareToStory(
'https://playableton-ccfish.pages.dev/share.png',
{ text: 'Can you beat my high score in CCFish? 🐟' }
);
}
// Or direct message sharing
function inviteFriend() {
Telegram.WebApp.openTelegramLink(
'https://t.me/playableton_bot/ccfish'
);
}
```
When a player shares their score, their friends see the game — with a direct link back to the bot. This is zero-cost UA driven entirely by organic gameplay.
2. Bot-Powered Game Discovery
The bot's `/play` command shows the full portfolio. When a user finishes one game, they can quickly switch to another without leaving Telegram:
```typescript
// grammY bot — game menu handler
bot.command('play', async (ctx) => {
const games = await prisma.game.findMany({
where: { active: true }
});
const buttons = games.map(g => ({
text: g.name,
web_app: { url: g.gameUrl }
}));
// Arrange in 2-column grid
const keyboard = [];
for (let i = 0; i < buttons.length; i += 2) {
keyboard.push(buttons.slice(i, i + 2));
}
await ctx.reply('Choose your game:', {
reply_markup: { inline_keyboard: keyboard }
});
});
```
3. Analytics-Driven Recommendations
Cloudflare Workers capture play events from each TMA session. By analyzing which games users play and in what order, we can surface smart recommendations:
```typescript
// Worker analytics collector
async function recordPlayEvent(userId: string, gameSlug: string) {
await DB.prepare(`
INSERT INTO play_events (user_id, game_slug, played_at)
VALUES (?, ?, datetime('now'))
`).bind(userId, gameSlug).run();
}
// Recommendation query
async function getRecommendations(userId: string) {
const result = await DB.prepare(`
SELECT game_slug, COUNT(*) as plays
FROM play_events
WHERE user_id != ?
AND game_slug NOT IN (
SELECT game_slug FROM play_events WHERE user_id = ?
)
GROUP BY game_slug
ORDER BY plays DESC
LIMIT 3
`).bind(userId, userId).all();
return result.results;
}
```
Comparing Cost Structures
| Method | Cost per Install | Control | Speed |
|--------|-----------------|---------|-------|
| Facebook Ads | $5-7 | Limited | Instant |
| Ad Networks | $3-5 (rev share) | Low | Days |
| Cross-promo (bot) | $0 | Full | Instant |
| Organic sharing | $0 | Full | Viral |
The Data So Far
With 5 games in the portfolio (CCFish, Casino Slot, SlotX, Crisis Empire, ChezBot) serving through a single bot:
- **Zero infrastructure cost** — all hosting on Cloudflare free tier
- **Instant portfolio expansion** — a new game goes live in under 60 seconds
- **Organic cross-play** — users naturally explore the portfolio after finishing one game
- **No SDK lock-in** — everything runs through Telegram's built-in WebApp API
Building Your Own
If you have a portfolio of HTML5 or Cocos Creator games, here's the minimum setup:
1. Deploy each game to Cloudflare Pages
2. Inject Telegram WebApp SDK into each game's index.html
3. Set up a grammY bot with Prisma and D1
4. Add your games to the bot's seed data
5. Serve game menu via `/play` command with inline keyboards
Total code: about 200 lines of TypeScript. Total cost: $0.
The Takeaway
Cross-promotion doesn't need to be expensive or complicated. By treating your Telegram bot as a game storefront and each Cloudflare Pages deployment as a mini app, you get a self-owned distribution channel that costs nothing to operate and scales with your portfolio.
For indie studios and small teams, this isn't just a nice-to-have — it's the difference between being visible and being invisible in a crowded market. Your infrastructure already does the heavy lifting. The bot and the mini apps are just the packaging.
Build the games. Deploy to Pages. Wire up the bot. The distribution takes care of itself.