# Proxying

{% hint style="warning" %}
This method is outdated. We recommend using MtProto or API instead, as they are more flexible and reliable.
{% endhint %}

The Telegram Bot API operates on two work schemes:

**webhook**: when a user writes to the bot, the Telegram server automatically sends a HTTPS request to your bot's address

**getUpdates** (long polling): your bot independently requests updates from the Telegram server

<figure><img src="https://2370640460-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3WNx9aQcXCICPDH9Ok6x%2Fuploads%2FdJZOhJjSWlhzHB4vfret%2Ftg-bot.jpg?alt=media&#x26;token=9d4fbfc7-6554-4740-a141-caee0d72cee1" alt=""><figcaption><p>The above diagram shows the standard scheme for exchanging data between the bot and Telegram servers.</p></figcaption></figure>

To make connecting to the platform simple and fast, we have developed a special proxy server that is installed between the Telegram server and your bot.

<figure><img src="https://2370640460-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3WNx9aQcXCICPDH9Ok6x%2Fuploads%2Fcm2uD6GL5wzSGHt9GtlN%2FUntitled-1.jpg?alt=media&#x26;token=2a8c45d0-4eb3-4103-955d-11cf5c089118" alt=""><figcaption><p>This is what the scheme looks like after connecting graspi.</p></figcaption></figure>

#### **If your bot operates via Webhook**

You can manually connect your bot (without entering a token), for this when adding a bot you need to select the appropriate item and follow the instructions. You will need to replace your **webhook** with ours.

#### **If your bot operates via getUpdates**

There are two ways to connect a bot working through the getUpdate method, via the API (see the section "[Connecting a bot via the API](https://docs.graspil.com/en/connect-bot/broken-reference)") or by replacing the host with **api.telegram.org** .&#x20;

Bots of this type independently request updates from Telegram using HTTPS requests using the **getUpdate** method. To connect the bot to analytics, you need to change the host **api.telegram.org** to the host that the system will give you when you connect.

After changing the host, our platform will proxy all requests to the host **api.telegram.org** and collect statistics for you. Not only **getUpdate** requests can be sent to this address, but also all other types of requests (sending messages, files, etc.). All requests are proxied to the Telegram servers unchanged.&#x20;

### How to change the host connection in the bot?

Changing the host api.telegram.org provided by the Telegram Bot API, most libraries have the ability to change this address.&#x20;

If you have not found the instructions for your library or you have problems connecting, please contact our [technical support](https://graspil.com/ru#contact) or fill out the form at the end of this page.

{% hint style="danger" %}
**Important**. The examples use the address "<https://tgrasp.co> ", you can use this address only if the bot **token** was specified in your personal account. In other cases, use only the address that you received in your personal account at the stage of setting up the bot.&#x20;

If you have set a **token** for the bot in your personal account, the system will give you the address "**<https://tgrasp.co>** " otherwise the address will be "**https\://{code} .tgrasp.co**"
{% endhint %}

### Connection instructions for specific libraries

Select the library you are using

{% hint style="info" %}
If you have not found the instructions you need, write to us in the chat on the website or fill out the form at the end of this page
{% endhint %}

### Python <a href="#python" id="python"></a>

<details>

<summary>Aiogram</summary>

**Repositroy** - <https://github.com/aiogram/aiogram>

Information on how to change the host in the documentation <https://docs.aiogram.dev/en/dev-3.x/api/session/custom_server.html>

```python
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.client.telegram import TelegramAPIServer


session = AiohttpSession(
    api=TelegramAPIServer.from_base('https://tgrasp.co')
)
bot = Bot(..., session=session)

```

**Полный листинг кода**

Pay attention to lines 11 and 12, objects are imported into them. Lines 51-53 specify the address. An attribute is added to line 56 `, session=session`

{% code lineNumbers="true" %}

```python
import asyncio
import logging
import sys
from os import getenv

from aiogram import Bot, Dispatcher, Router, types
from aiogram.enums import ParseMode
from aiogram.filters import CommandStart
from aiogram.types import Message
from aiogram.utils.markdown import hbold
from aiogram.client.session.aiohttp import AiohttpSession
from aiogram.client.telegram import TelegramAPIServer

# Bot token can be obtained via https://t.me/BotFather
TOKEN = getenv("BOT_TOKEN")

# All handlers should be attached to the Router (or Dispatcher)
dp = Dispatcher()


@dp.message(CommandStart())
async def command_start_handler(message: Message) -> None:
    """
    This handler receives messages with `/start` command
    """
    # Most event objects have aliases for API methods that can be called in events' context
    # For example if you want to answer to incoming message you can use `message.answer(...)` alias
    # and the target chat will be passed to :ref:`aiogram.methods.send_message.SendMessage`
    # method automatically or call API method directly via
    # Bot instance: `bot.send_message(chat_id=message.chat.id, ...)`
    await message.answer(f"Hello, {hbold(message.from_user.full_name)}!")


@dp.message()
async def echo_handler(message: types.Message) -> None:
    """
    Handler will forward receive a message back to the sender

    By default, message handler will handle all message types (like a text, photo, sticker etc.)
    """
    try:
        # Send a copy of the received message
        await message.send_copy(chat_id=message.chat.id)
    except TypeError:
        # But not all the types is supported to be copied so need to handle it
        await message.answer("Nice try!")


async def main() -> None:

    session = AiohttpSession(
        api=TelegramAPIServer.from_base('https://tgrasp.co') # your address
    )

    # Initialize Bot instance with a default parse mode which will be passed to all API calls
    bot = Bot(TOKEN, parse_mode=ParseMode.HTML, session=session)
    
    # And the run events dispatching
    await dp.start_polling(bot)


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO, stream=sys.stdout)
    asyncio.run(main())
```

{% endcode %}

</details>

<details>

<summary>eternnoir/pyTelegramBotAPI</summary>

**Repository -** <https://github.com/eternnoir/pyTelegramBotAPI>

To change the host, you need to import `apihelper` and set the `API_URL` parameter. You can read about how to change the host in the [official documentation](https://github.com/eternnoir/pyTelegramBotAPI#using-local-bot-api-sever)

```python
from telebot import apihelper

apihelper.API_URL = "https://tgrasp.co/bot{0}/{1}"
```

#### Full code listing

For a full-fledged example, we used an example from the official repository at [*https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/echo\_bot.py*](https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/echo_bot.py)

Pay attention to lines 7 and 11. An object is imported into them and the address is changed

{% code lineNumbers="true" %}

```python
#!/usr/bin/python

# This is a simple echo bot using the decorator mechanism.
# It echoes any incoming text messages.

import telebot
from telebot import apihelper

API_TOKEN = '<api_token>'

apihelper.API_URL = "https://tgrasp.co/bot{0}/{1}" # your address

bot = telebot.TeleBot(API_TOKEN)


# Handle '/start' and '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
    bot.reply_to(message, """\
Hi there, I am EchoBot.
I am here to echo your kind words back to you. Just say anything nice and I'll say the exact same thing to you!\
""")


# Handle all other messages with content_type 'text' (content_types defaults to ['text'])
@bot.message_handler(func=lambda message: True)
def echo_message(message):
    bot.reply_to(message, message.text)


bot.infinity_polling()
```

{% endcode %}

</details>

<details>

<summary><strong>python-telegram-bot/python-telegram-bot</strong></summary>

Repository **-** [**https://github.com/python-telegram-bot/python-telegram-bot**](https://github.com/python-telegram-bot/python-telegram-bot)

Information on how to change the host in the documentation [**https://github.com/python-telegram-bot/python-telegram-bot/wiki/Local-Bot-API-Server**](https://github.com/python-telegram-bot/python-telegram-bot/wiki/Local-Bot-API-Server)

You can change the host using the `base_url` method. For clarity, we used the basic example from the documentation. Pay attention to line **14** where the address changes `.base_url('https://tgrasp.co/bot')`

{% code overflow="wrap" lineNumbers="true" %}

```python
import logging
from telegram import Update
from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler

logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await context.bot.send_message(chat_id=update.effective_chat.id, text="I'm a bot, please talk to me!")

if __name__ == '__main__':

# Replace the address with your own
    application = ApplicationBuilder().base_url('https://tgrasp.co/bot').token('6789412258:AAG_W1L7WtYhvG0LSpj2tsGVUon7QgG-e14').build()
    
    start_handler = CommandHandler('start', start)
    application.add_handler(start_handler)
    
    application.run_polling()
```

{% endcode %}

</details>

### PHP

<details>

<summary><strong>telegram-bot-sdk/telegram-bot-sdk</strong></summary>

**Repository** - <https://github.com/telegram-bot-sdk/telegram-bot-sdk>

The library supports working with multiple bots, so there are two connection options below

**If you have one bot**

```php
use Telegram\Bot\Api;

// replace the fourth attribute with the address that you received in your personal account.
// note the addition of /bot at the end
$telegram = new Api('<BOT TOKEN>', false, null, 'https://tgrasp.co/bot');

$response = $telegram->getUpdates([
    'offset' => 0,
    'timeout'=>10
]);
```

**If you have multiple bots**

```php
use Telegram\Bot\BotsManager;

$config = [
    'bots' => [
        'mybot' => [
            'token' => '<BOT TOKEN>',
        ],
    ],
    // replace the fourth attribute with the address that you received in your personal account.
    // note the addition of /bot at the end
    'base_bot_url' => 'https://tgrasp.co/bot'
];

$telegram = new BotsManager($config);

// Example usage
$response = $telegram->bot('mybot')->getUpdates([
    'offset' => 0,
    'timeout'=> 10
]);
```

</details>

<details>

<summary>php-telegram-bot/core</summary>

**Repository -** <https://github.com/php-telegram-bot/core>

Information on how to change the host in the documentation <https://github.com/php-telegram-bot/core#using-a-custom-bot-api-server>

<pre class="language-php"><code class="lang-php">Longman\TelegramBot\Request::setCustomBotApiUri(
<strong>    $api_base_uri = 'https://tgrasp.co'
</strong>);
</code></pre>

</details>

<details>

<summary>TelegramBot/Api</summary>

**Repository -** [https://github.com/TelegramBot/Api](https://github.com/TelegramBot/Api?tab=readme-ov-file#local-bot-api-server)

Information on how to change the host in the documentation <https://github.com/TelegramBot/Api?tab=readme-ov-file#local-bot-api-server>

At the time of writing this documentation, the ability to change the address is present only in dev version 2.6. By default, version 2.5 is installed&#x20;

To update your library version to version 2.6

Change it in composer.json on`"^2.6"` and add the parameters `"minimum-stability": "dev", "prefer-stable": true`

{% code title="Composer.json example" %}

```json
{
    "require": {
        "telegram-bot/api": "^2.6"
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}
```

{% endcode %}

**Changing the address**

When creating a **BotApi** object, pass our address as the fourth parameter

```php
try {

    $bot = new \TelegramBot\Api\BotApi(
        '<BOT TOKEN>', 
        null, 
        null, 
        'https://tgrasp.co/bot' // replace it with the address you received in your personal account
    );
    $updates = $bot->getUpdates(0, 100, 10);
    
} catch (\TelegramBot\Api\Exception $e) {
    $e->getMessage();
}
```

</details>

<details>

<summary>defstudio/telegraph</summary>

Repository - <https://github.com/defstudio/telegraph>

You can change the connection URL in the defstudio/telegraph configuration. Replace the value of the *telegram\_api\_url* parameter with the desired address (e.g., *<https://tgrasp.co>*).<br>

For more details about the configuration file, refer to the [documentation](https://docs.defstudio.it/telegraph/v1/installation#content-configuration)

{% code overflow="wrap" lineNumbers="true" %}

```php
return [
    /*
     * Telegram API base URL, it can be overridden
     * for self-hosted servers
     */
    //'telegram_api_url' => 'https://api.telegram.org/',
    'telegram_api_url' => 'https://tgrasp.co/', // <------- your address
];
```

{% endcode %}

</details>

### JavaScript

<details>

<summary>yagop/node-telegram-bot-api</summary>

**Repository** - [*https://github.com/yagop/node-telegram-bot-api*](https://github.com/yagop/node-telegram-bot-api)

In order to change the host, you need to pass the parameter `baseApiUrl: 'https://tgrasp.co'` in attribute `options` when creating object a `new TelegramBot(token, [options])`

{% code overflow="wrap" %}

```javascript
const options = { 
    polling: true, 
    baseApiUrl: 'https://tgrasp.co' //replace it with the address you received in your personal account
}; 
const bot = new TelegramBot(TOKEN, options);
```

{% endcode %}

#### **Full code listing**

For a full-fledged example, we used an example from the official repository at [*https://github.com/yagop/node-telegram-bot-api/blob/master/examples/polling.js*](https://github.com/yagop/node-telegram-bot-api/blob/master/examples/polling.js)

Pay attention to line 12, the address changes in it

{% code overflow="wrap" lineNumbers="true" %}

```javascript
/**
 * This example demonstrates using polling.
 * It also demonstrates how you would process and send messages.
 */

const TOKEN = process.env.TELEGRAM_TOKEN || 'YOUR_TELEGRAM_BOT_TOKEN';
const TelegramBot = require('node-telegram-bot-api');
const request = require('@cypress/request');

const options = {
  polling: true,
  baseApiUrl: 'https://tgrasp.co' // your address
};

const bot = new TelegramBot(TOKEN, options);


// Matches /photo
bot.onText(/\/photo/, function onPhotoText(msg) {
  // From file path
  const photo = `${__dirname}/../test/data/photo.gif`;
  bot.sendPhoto(msg.chat.id, photo, {
    caption: "I'm a bot!"
  });
});


// Matches /audio
bot.onText(/\/audio/, function onAudioText(msg) {
  // From HTTP request
  const url = 'https://upload.wikimedia.org/wikipedia/commons/c/c8/Example.ogg';
  const audio = request(url);
  bot.sendAudio(msg.chat.id, audio);
});


// Matches /love
bot.onText(/\/love/, function onLoveText(msg) {
  const opts = {
    reply_to_message_id: msg.message_id,
    reply_markup: JSON.stringify({
      keyboard: [
        ['Yes, you are the bot of my life ❤'],
        ['No, sorry there is another one...']
      ]
    })
  };
  bot.sendMessage(msg.chat.id, 'Do you love me?', opts);
});


// Matches /echo [whatever]
bot.onText(/\/echo (.+)/, function onEchoText(msg, match) {
  const resp = match[1];
  bot.sendMessage(msg.chat.id, resp);
});


// Matches /editable
bot.onText(/\/editable/, function onEditableText(msg) {
  const opts = {
    reply_markup: {
      inline_keyboard: [
        [
          {
            text: 'Edit Text',
            // we shall check for this value when we listen
            // for "callback_query"
            callback_data: 'edit'
          }
        ]
      ]
    }
  };
  bot.sendMessage(msg.from.id, 'Original Text', opts);
});


// Handle callback queries
bot.on('callback_query', function onCallbackQuery(callbackQuery) {
  const action = callbackQuery.data;
  const msg = callbackQuery.message;
  const opts = {
    chat_id: msg.chat.id,
    message_id: msg.message_id,
  };
  let text;

  if (action === 'edit') {
    text = 'Edited Text';
  }

  bot.editMessageText(text, opts);
});
```

{% endcode %}

</details>

<details>

<summary>grammyjs/grammY</summary>

Instructions on how to change the address in the official documentation - <https://grammy.dev/guide/api#configuring-grammy-to-use-the-local-bot-api-server>

To connect the address, change the creation of the `Bot` object

{% code overflow="wrap" lineNumbers="true" %}

```javascript
const bot = new Bot("", { // <-- use the same token as before
  client: { apiRoot: "https://tgrasp.co" },
});
```

{% endcode %}

**Example**

As an example, we used a basic example from the official documentation. Pay attention to the 4-7 lines in which the address changes.

{% code overflow="wrap" lineNumbers="true" %}

```javascript
const { Bot } = require("grammy");


const bot = new Bot("< BOT_TOKEN >",
{ // <-- use the same token as before
  client: { apiRoot: "https://tgrasp.co" }, // replace it with the address you received in your personal account
});

// Handle the /start command.
bot.command("start", (ctx) => ctx.reply("Welcome! Up and running."));

// Start the bot.
bot.start();
```

{% endcode %}

</details>

<details>

<summary>telegraf/telegraf</summary>

Repository — [https://github.com/telegraf/telegraf ](https://github.com/telegraf/telegraf)

To connect, change the creation of the `Telegraf` object. Below is an example of a simple bot with a changed address. Pay attention to lines 5-8, the address changes in them. Replace the address with the one you received in your personal account.&#x20;

After making changes, restart the bot.

{% code overflow="wrap" lineNumbers="true" %}

```javascript
const { Telegraf } = require('telegraf');

// Specify here your token that you received from BotFather
const bot = new Telegraf('< BOT_TOKEN >',
  {
  telegram: {
    apiRoot: 'https://tgrasp.co' // replace it with the address you received in your personal account
  }
});

// Response to the command /start
bot.start((ctx) => ctx.reply('Hi! I am a simple bot using long polling.'));

// Launching the bot in long pollin mode
bot.launch().then(() => {
  console.log('The bot is running in the mode long polling');
});

// Processing an application shutdown
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));
```

{% endcode %}

</details>

### Go

<details>

<summary>go-telegram-bot-api/telegram-bot-api</summary>

**Repository** - <https://github.com/go-telegram-bot-api/telegram-bot-api>

Use the method `SetAPIEndpoint` to change the connection host

{% code overflow="wrap" lineNumbers="true" %}

```go
bot, err := tgbotapi.NewBotAPI("<api_token>")

bot.SetAPIEndpoint("https://tgrasp.co/bot%s/%s") //replace it with the address you received in your personal account
```

{% endcode %}

**A full-fledged example**

Pay attention to line **17**, the address changes in it

{% code overflow="wrap" lineNumbers="true" %}

```go
package main

import (
	"log"

	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
)

func main() {
	bot, err := tgbotapi.NewBotAPI("<api_token>")
	if err != nil {
		log.Panic(err)
	}

	bot.Debug = true

	bot.SetAPIEndpoint("https://tgrasp.co/bot%s/%s") // your address

	log.Printf("Authorized on account %s", bot.Self.UserName)

	u := tgbotapi.NewUpdate(0)
	u.Timeout = 60

	updates := bot.GetUpdatesChan(u)

	for update := range updates {
		if update.Message != nil { // If we got a message
			log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)

			msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text)
			msg.ReplyToMessageID = update.Message.MessageID

			bot.Send(msg)
		}
	}
}
```

{% endcode %}

</details>

<details>

<summary>tucnak/telebot</summary>

Repository - <https://github.com/tucnak/telebot>

To change the connection host, pass the desired address to the URL parameter

{% code overflow="wrap" lineNumbers="true" %}

```go
pref := tele.Settings{
  URL: "https://tgrasp.co", //the address that you received in your personal account
  Token:  os.Getenv("TOKEN"),
  Poller: &tele.LongPoller{Timeout: 10 * time.Second},
}
```

{% endcode %}

**A full-fledged example**

Pay attention to line 13, the address changes in it

{% code overflow="wrap" lineNumbers="true" %}

```go
package main

import (
	"log"
	"os"
	"time"

	tele "gopkg.in/telebot.v3"
)

func main() {
	pref := tele.Settings{
		URL: "https://tgrasp.co", //the address that you received in your personal account
		Token:  os.Getenv("TOKEN"),
		Poller: &tele.LongPoller{Timeout: 10 * time.Second},
	}

	b, err := tele.NewBot(pref)
	if err != nil {
		log.Fatal(err)
		return
	}

	b.Handle("/hello", func(c tele.Context) error {
		return c.Send("Hello!")
	})

	b.Start()
}
```

{% endcode %}

</details>

### Java

<details>

<summary>rubenlagus/TelegramBots</summary>

Repository - <https://github.com/rubenlagus/TelegramBots>

As an example, we used the repository <https://github.com/rubenlagus/TelegramBotsExample>

To connect incoming traffic, you need to pass the `TelegramUrl` object to the function `TelegramBotsLongPollingApplication.registerBot()`

Note line **8**, this is the standard method for connecting to the TG Bot API. In the next line, we added 2 parameters to this function, including passing a new address for the connection. Replace it with the address provided by your system.

{% code overflow="wrap" lineNumbers="true" %}

```java
//import org.telegram.telegrambots.meta.TelegramUrl;
//import org.telegram.telegrambots.longpolling.util.DefaultGetUpdatesGenerator;

public static void main(String[] args) {

    TelegramBotsLongPollingApplication botsApplication = new TelegramBotsLongPollingApplication();
    try {
         // botsApplication.registerBot(BotConfig.COMMANDS__TOKEN, new CommandsHandler(BotConfig.COMMANDS__TOKEN, BotConfig.COMMANDS__USER));
         botsApplication.registerBot(
            BotConfig.WEATHER_TOKEN, 
            () -> new TelegramUrl("https", "tgrasp.co", 443), //<!-- replace the address with yours
            new DefaultGetUpdatesGenerator(), 
            new CommandsHandler(BotConfig.COMMANDS_TOKEN, BotConfig.COMMANDS_USER)
         );

        } catch (TelegramApiException e) {
            log.error("Error registering bot", e);
        }
}
```

{% endcode %}

</details>

## Possible errors <a href="#vozmozhnye-oshibki" id="vozmozhnye-oshibki"></a>

All errors related to the work of the bot fall into the [bot errors section](https://app.graspil.com/bot_errors) in the personal account.

<table><thead><tr><th width="74">Код</th><th>Описание</th><th>Решение</th></tr></thead><tbody><tr><td>409</td><td>Conflict: terminated by other getUpdates request; make sure that only one bot instance is running</td><td>The error occurs when the telegram servers record two simultaneous getUpdates requests. Make sure that you have only one data acquisition thread running</td></tr><tr><td>502</td><td>502 Bad Gateway</td><td>Make sure that you are sending the request with the correct structure. Sometimes problems occur on telegram servers and they may respond with this error.</td></tr><tr><td>404</td><td>404 Not Found</td><td><ol><li>Make sure you are using the correct address for the connection. Compare it with the address provided by the system. The address tgrasp.co can only be used if a token has been provided.</li><li>If you are using tgrasp.co, ensure that the bot ID (the first part of the token) matches the one you provided in graspil. The current bot ID in graspil is displayed below the connection address field.</li></ol></td></tr></tbody></table>
