Skip to content

Latest commit

Β 

History

History
486 lines (394 loc) Β· 19 KB

File metadata and controls

486 lines (394 loc) Β· 19 KB

Telegram Bot - Setup i Implementacija

Pregled

Ovaj dokument opisuje kako kreirati i konfigurisati Telegram bota za Panic Button aplikaciju.


Kreiranje Bota

Korak 1: BotFather

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  KREIRANJE BOTA PREKO @BotFather                                                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                 β”‚
β”‚  1. Otvori Telegram i pronaΔ‘i @BotFather                                        β”‚
β”‚                                                                                 β”‚
β”‚  2. PoΕ‘alji komandu: /newbot                                                    β”‚
β”‚                                                                                 β”‚
β”‚  3. BotFather pita za ime bota:                                                 β”‚
β”‚     > Patrola Bot                                                               β”‚
β”‚                                                                                 β”‚
β”‚  4. BotFather pita za username (mora zavrΕ‘iti sa "bot"):                        β”‚
β”‚     > patrola_skola_bot                                                         β”‚
β”‚                                                                                 β”‚
β”‚  5. BotFather ti daje TOKEN:                                                    β”‚
β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚     β”‚  Done! Congratulations on your new bot.                             β”‚     β”‚
β”‚     β”‚                                                                     β”‚     β”‚
β”‚     β”‚  Use this token to access the HTTP API:                             β”‚     β”‚
β”‚     β”‚  123456789:ABCdefGHIjklMNOpqrsTUVwxyz_0123456789                    β”‚     β”‚
β”‚     β”‚                                                                     β”‚     β”‚
β”‚     β”‚  Keep your token secure and store it safely.                        β”‚     β”‚
β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚                                                                                 β”‚
β”‚  ⚠️ SAČUVAJ TOKEN! Nikada ga ne objavljuj javno.                                β”‚
β”‚                                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Korak 2: PodeΕ‘avanje Bota

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  DODATNA PODEΕ AVANJA (opciono)                                                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                 β”‚
│  Poőalji @BotFather sledeće komande:                                            │
β”‚                                                                                 β”‚
β”‚  /setdescription                                                                β”‚
β”‚  > Patrola Bot - Notifikacije o alarmima za bezbednost dece                     β”‚
β”‚                                                                                 β”‚
β”‚  /setabouttext                                                                  β”‚
β”‚  > Bot za koordinaciju roditeljskih patrola oko Ε‘kola                           β”‚
β”‚                                                                                 β”‚
β”‚  /setuserpic                                                                    β”‚
β”‚  > [Upload sliku/logo]                                                          β”‚
β”‚                                                                                 β”‚
β”‚  /setcommands                                                                   β”‚
β”‚  > start - Pokreni bota                                                         β”‚
│  > help - Pomoć                                                                 │
β”‚  > status - Status sistema                                                      β”‚
β”‚                                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Kreiranje Grupe

Korak 3: Nova Telegram Grupa

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  KREIRANJE TELEGRAM GRUPE                                                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                 β”‚
β”‚  1. U Telegram-u klikni na ≑ (hamburger menu)                                   β”‚
β”‚                                                                                 β”‚
β”‚  2. "New Group"                                                                 β”‚
β”‚                                                                                 β”‚
β”‚  3. Dodaj bar jednog člana (moΕΎe biti tvoj drugi nalog ili @patrola_skola_bot)  β”‚
β”‚                                                                                 β”‚
β”‚  4. Unesi ime grupe:                                                            β”‚
β”‚     > OΕ  KovačiΔ‡ - Patrola                                                      β”‚
β”‚                                                                                 β”‚
β”‚  5. Klikni βœ“ da kreiraΕ‘ grupu                                                   β”‚
β”‚                                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Korak 4: Dodavanje Bota kao Admina

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  POSTAVLJANJE BOTA KAO ADMINA                                                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                 β”‚
β”‚  ⚠️ VAΕ½NO: Bot MORA biti admin da bi mogao slati poruke u grupu!                β”‚
β”‚                                                                                 β”‚
β”‚  1. Otvori grupu                                                                β”‚
β”‚                                                                                 β”‚
β”‚  2. Klikni na ime grupe (header) da otvoriΕ‘ info                                β”‚
β”‚                                                                                 β”‚
β”‚  3. Klikni na ✏️ (Edit)                                                         β”‚
β”‚                                                                                 β”‚
β”‚  4. "Administrators"                                                            β”‚
β”‚                                                                                 β”‚
β”‚  5. "Add Administrator"                                                         β”‚
β”‚                                                                                 β”‚
β”‚  6. PronaΔ‘i i izaberi @patrola_skola_bot                                        β”‚
β”‚                                                                                 β”‚
β”‚  7. Dodeli permisije (minimum):                                                 β”‚
β”‚     βœ“ Post messages                                                             β”‚
β”‚     βœ“ Edit messages                                                             β”‚
β”‚                                                                                 β”‚
β”‚  8. Klikni "Done"                                                               β”‚
β”‚                                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Dobijanje Chat ID

Korak 5: Dobijanje ID grupe

# Metoda 1: Preko getUpdates API-ja

# 1. PoΕ‘alji bilo koju poruku u grupu

# 2. Pozovi API (zameni <TOKEN> sa tvojim tokenom):
curl "https://api.telegram.org/bot<TOKEN>/getUpdates"

# 3. U JSON response-u, naΔ‘i:
# {
#   "message": {
#     "chat": {
#       "id": -100123456789,  <-- OVO JE CHAT_ID
#       "title": "OΕ  KovačiΔ‡ - Patrola",
#       "type": "supergroup"
#     }
#   }
# }

# NAPOMENA: ID grupe je NEGATIVAN broj (počinje sa -)
# Metoda 2: Koristi @userinfobot

# 1. Dodaj @userinfobot u grupu
# 2. Bot Δ‡e automatski poslati info o grupi, uključujuΔ‡i ID
# 3. Zatim moΕΎeΕ‘ ukloniti bota

Primer Response-a

{
  "ok": true,
  "result": [
    {
      "update_id": 123456789,
      "message": {
        "message_id": 1,
        "from": {
          "id": 12345678,
          "first_name": "Marko"
        },
        "chat": {
          "id": -1001234567890,
          "title": "OΕ  KovačiΔ‡ - Patrola",
          "type": "supergroup"
        },
        "date": 1705671600,
        "text": "Test"
      }
    }
  ]
}

Testiranje

Korak 6: Test Slanja Poruke

# Test slanja poruke u grupu

curl -X POST "https://api.telegram.org/bot<TOKEN>/sendMessage" \
  -H "Content-Type: application/json" \
  -d '{
    "chat_id": "-1001234567890",
    "text": "πŸš€ Test poruka - Patrola Bot je uspeΕ‘no povezan!",
    "parse_mode": "Markdown"
  }'

# Očekivani response:
# {
#   "ok": true,
#   "result": {
#     "message_id": 2,
#     "chat": {"id": -1001234567890, ...},
#     "text": "πŸš€ Test poruka - Patrola Bot je uspeΕ‘no povezan!"
#   }
# }

Test Alarm Poruke

# Simuliraj alarm poruku

curl -X POST "https://api.telegram.org/bot<TOKEN>/sendMessage" \
  -H "Content-Type: application/json" \
  -d '{
    "chat_id": "-1001234567890",
    "text": "🚨 *ALARM*\n\nπŸ“ Lokacija: [Otvori mapu](https://maps.google.com/?q=44.8125,20.4612)\nπŸ’¬ \"Prate me\"\nπŸ‘€ Od: Marko P.\n\nπŸ‘† [Otvori u aplikaciji](https://patrola.rs/alarm/test)",
    "parse_mode": "Markdown",
    "disable_web_page_preview": false
  }'

Integracija sa Convex

Environment Variables

# Postavi u Convex
npx convex env set TELEGRAM_BOT_TOKEN "123456789:ABCdefGHIjklMNOpqrsTUVwxyz"
npx convex env set TELEGRAM_CHAT_ID "-1001234567890"
npx convex env set APP_URL "https://patrola.rs"

# Proveri
npx convex env list

Convex Action

// convex/telegram.ts

import { internalAction } from "./_generated/server";
import { v } from "convex/values";

export const sendMessage = internalAction({
  args: {
    text: v.string(),
    parseMode: v.optional(v.string()),
  },
  handler: async (ctx, { text, parseMode = "Markdown" }) => {
    const botToken = process.env.TELEGRAM_BOT_TOKEN;
    const chatId = process.env.TELEGRAM_CHAT_ID;

    if (!botToken || !chatId) {
      throw new Error("Telegram not configured");
    }

    const response = await fetch(
      `https://api.telegram.org/bot${botToken}/sendMessage`,
      {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          chat_id: chatId,
          text,
          parse_mode: parseMode,
          disable_web_page_preview: false,
        }),
      }
    );

    const result = await response.json();

    if (!result.ok) {
      console.error("Telegram API error:", result);
      throw new Error(result.description || "Failed to send message");
    }

    return result;
  },
});

API Reference

KoriΕ‘Δ‡eni Endpoints

Endpoint Metoda Opis
/getMe GET Info o botu
/getUpdates GET Dobij nove poruke
/sendMessage POST PoΕ‘alji poruku
/editMessageText POST Izmeni poruku
/deleteMessage POST ObriΕ‘i poruku

sendMessage Parametri

interface SendMessageParams {
  chat_id: string | number;      // ID grupe
  text: string;                  // Tekst poruke
  parse_mode?: "Markdown" | "HTML" | "MarkdownV2";
  disable_web_page_preview?: boolean;
  disable_notification?: boolean;
  reply_to_message_id?: number;
  reply_markup?: InlineKeyboardMarkup;
}

Markdown Formatiranje

*bold*
_italic_
`code`
```code block```
[link](http://example.com)

Napredne Funkcije (Pun Sistem)

Inline Keyboard za Akcije

// Poruka sa dugmićima

const message = {
  chat_id: chatId,
  text: "🚨 *ALARM*\n\nNeko treba pomoΔ‡!",
  parse_mode: "Markdown",
  reply_markup: {
    inline_keyboard: [
      [
        {
          text: "πŸƒ Preuzimam",
          url: "https://patrola.rs/alarm/abc123?action=take"
        }
      ],
      [
        {
          text: "πŸ“ Lokacija",
          url: "https://maps.google.com/?q=44.81,20.46"
        }
      ]
    ]
  }
};

Webhook (umesto Polling)

// Setup webhook za primanje poruka od bota

// 1. Registruj webhook
// POST https://api.telegram.org/bot<TOKEN>/setWebhook
// body: { "url": "https://xxx.convex.site/telegram-webhook" }

// 2. Convex HTTP endpoint
import { httpAction } from "./_generated/server";

export const telegramWebhook = httpAction(async (ctx, request) => {
  const body = await request.json();

  // Handle bot commands
  if (body.message?.text?.startsWith("/")) {
    const command = body.message.text.split(" ")[0];
    const chatId = body.message.chat.id;

    switch (command) {
      case "/start":
        await sendWelcomeMessage(chatId);
        break;
      case "/status":
        await sendStatusMessage(chatId);
        break;
    }
  }

  return new Response("OK");
});

Kod-bazirano Povezivanje Grupe

// Kada bot detektuje da je dodat u grupu, Ε‘alje kod

export const handleBotAdded = internalAction({
  args: {
    chatId: v.string(),
    chatTitle: v.string(),
  },
  handler: async (ctx, { chatId, chatTitle }) => {
    // GeneriΕ‘i kod
    const code = `TG-${Math.random().toString(36).substring(2, 8).toUpperCase()}`;

    // Sačuvaj u bazu
    await ctx.runMutation(internal.telegram.saveLinkCode, {
      code,
      chatId,
      chatTitle,
      expiresAt: Date.now() + 15 * 60 * 1000, // 15 min
    });

    // PoΕ‘alji poruku sa kodom
    await ctx.runAction(internal.telegram.sendMessage, {
      chatId,
      text: `πŸ‘‹ Zdravo! Ja sam PatrolaBot.

Da poveΕΎete ovu grupu sa aplikacijom, admin treba da unese ovaj kod u app:

πŸ”‘ *KOD: ${code}*

Kod vaΕΎi 15 minuta.`,
    });
  },
});

Troubleshooting

Česti Problemi

Problem ReΕ‘enje
Bot ne Ε‘alje poruke Proveri da li je bot ADMIN u grupi
"Chat not found" Proveri CHAT_ID (mora biti negativan za grupe)
"Bot was blocked" Korisnik je blokirao bota
Rate limit exceeded Implementiraj queue za poruke
"Forbidden" Bot nema permisije u grupi

Debug Koraci

# 1. Proveri da li bot radi
curl "https://api.telegram.org/bot<TOKEN>/getMe"

# 2. Proveri recent updates
curl "https://api.telegram.org/bot<TOKEN>/getUpdates"

# 3. Proveri webhook status (ako koristiΕ‘)
curl "https://api.telegram.org/bot<TOKEN>/getWebhookInfo"

# 4. Test poruka
curl -X POST "https://api.telegram.org/bot<TOKEN>/sendMessage" \
  -d "chat_id=<CHAT_ID>&text=test"

Bezbednost

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  BEZBEDNOSNE PREPORUKE                                                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                                 β”‚
β”‚  βœ“ Nikada ne objavljuj BOT_TOKEN javno                                          β”‚
β”‚  βœ“ Koristi environment variables                                                β”‚
β”‚  βœ“ Rotiraj token ako je kompromitovan (/revoke @BotFather)                      β”‚
β”‚  βœ“ Minimalna poruka u TG (detalji u app-u)                                      β”‚
β”‚  βœ“ Verifikuj webhook requests (ako koristiΕ‘)                                    β”‚
β”‚  βœ“ Rate limit za slanje poruka                                                  β”‚
β”‚                                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Dokument kreiran: Januar 2026