Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.fieldfunded.com/llms.txt

Use this file to discover all available pages before exploring further.

Build a Telegram Odds Bot with Inline Search

A Telegram bot that serves live odds via commands and inline search. Users can type @yourbot Lakers in any chat to see odds without opening the bot.

What You’ll Use

SDK MethodEndpointPurpose
search()GET /v1/searchFind events by team name
getEventOdds()GET /v1/events/{id}/oddsGet odds for a matched event
getScores()GET /v1/scoresList all live scores
getSports()GET /v1/sportsList available sports

Prerequisites

  • Node.js 18+
  • A Telegram bot token (from @BotFather)
  • A free FieldFunded API key
npm install telegraf @fieldfunded/sdk

Step 1: Initialize

import { Telegraf } from 'telegraf';
import { FieldFundedSDK } from '@fieldfunded/sdk';

const bot = new Telegraf(process.env.TELEGRAM_TOKEN!);
const ff = new FieldFundedSDK({
  apiKey: process.env.FIELDFUNDED_API_KEY!,
  baseUrl: 'https://api.fieldfunded.com/v1',
});

Step 2: /odds Command

bot.command('odds', async (ctx) => {
  const team = ctx.message.text.split('/odds ')[1];
  if (!team) {
    return ctx.reply('Usage: /odds <team name>\nExample: /odds Barcelona');
  }

  const results = await ff.search(team, { limit: 3 });

  if (!results.events || results.events.length === 0) {
    return ctx.reply(`No events found for "${team}"`);
  }

  for (const event of results.events) {
    const odds = await ff.getEventOdds(event.id);
    const mainMarket = odds.markets?.[0];

    let message = `⚽ *${event.home_team} vs ${event.away_team}*\n`;
    message += `📍 ${event.league}${event.status}\n`;

    if (mainMarket) {
      message += `\n📊 *${mainMarket.name}*\n`;
      for (const sel of mainMarket.selections) {
        message += `  ${sel.name}: \`${sel.odds}\`\n`;
      }
    }

    await ctx.reply(message, { parse_mode: 'Markdown' });
  }
});

Step 3: /scores Command

bot.command('scores', async (ctx) => {
  const sport = ctx.message.text.split('/scores ')[1] || undefined;
  const data = await ff.getScores({ sport });

  if (!data.scores || data.scores.length === 0) {
    return ctx.reply('No live games right now 📺');
  }

  let message = '🔴 *Live Scores*\n\n';

  for (const game of data.scores.slice(0, 15)) {
    message += `${game.home_team} *${game.score.home}-${game.score.away}* ${game.away_team}\n`;
    message += `  _${game.league}_\n\n`;
  }

  await ctx.reply(message, { parse_mode: 'Markdown' });
});

Step 4: Inline Search (the killer feature)

Users type @yourbot Lakers in any chat and get odds results as inline cards:
bot.on('inline_query', async (ctx) => {
  const query = ctx.inlineQuery.query;
  if (!query || query.length < 2) return;

  const results = await ff.search(query, { limit: 5 });

  if (!results.events) return ctx.answerInlineQuery([]);

  const inlineResults = await Promise.all(
    results.events.map(async (event: any, i: number) => {
      const odds = await ff.getEventOdds(event.id);
      const mainMarket = odds.markets?.[0];

      let description = `${event.league}${event.status}`;
      let message = `⚽ *${event.home_team} vs ${event.away_team}*\n`;
      message += `📍 ${event.league}\n`;

      if (mainMarket) {
        const oddsLine = mainMarket.selections
          .map((s: any) => `${s.name}: ${s.odds}`)
          .join(' | ');
        message += `📊 ${mainMarket.name}: ${oddsLine}`;
        description += ` | ${oddsLine}`;
      }

      return {
        type: 'article' as const,
        id: String(i),
        title: `${event.home_team} vs ${event.away_team}`,
        description,
        input_message_content: {
          message_text: message,
          parse_mode: 'Markdown' as const,
        },
      };
    })
  );

  await ctx.answerInlineQuery(inlineResults);
});

Step 5: Launch

bot.launch();
console.log('Bot is running!');

// Graceful shutdown
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));

Deploy

Deploy to Render or Railway (both have free tiers):
# Set environment variables
TELEGRAM_TOKEN=your_telegram_token
FIELDFUNDED_API_KEY=your_api_key

Rate Limit Math

  • /odds = 2 requests (search + odds)
  • /scores = 1 request
  • Inline query = 1-6 requests (search + odds per result)
  • Free tier handles ~2,000 bot interactions/month

Search API Reference

See search endpoint docs →

Get Your Free API Key

Start building in 5 minutes — 10,000 free requests/month