
В 2013-м году братья Дуровы создали инновационный мессенджер Telegram, который за девять лет был установлен на мобильные устройства свыше одного миллиарда раз (если верить статистике). Однако не только компании и обычные пользователи любят Телеграм. Платформу активно используют и разработчики для создания интерактивных чат-ботов. Однако иногда они сталкиваются с ошибкой 409, которая сопровождается сообщением «Не получается установить бот API Telegram».
Причины ошибки
Предполагаем, что этот материал будут читать не только опытные специалисты, но и начинающие разработчики, которые только недавно познакомились с возможностями API Telegram. Потому для начала расскажем, с чем могут быть связаны ошибки, возникающие во время работы с ботом. Весь процесс работы с API состоит из следующих этапов:

- Пользователь или программа отправляет запрос на сервер в виде функции.
- Сервер обрабатывает введенные параметры и сам запрос, а после выдает ответ.
- Пользователь считывает полученный ответ и оперирует с ним.
Если разработчик получил ошибку из заголовка, то значит, он столкнулся с невозможностью корректно обработать введенный запрос. Это ограничение может быть спровоцировано следующими факторами:
- Переданы некорректные аргументы или значения. В особенности проверьте правильность указанного токена.
- Бот запущен на нескольких серверах сразу. Нельзя указать один и тот же токен на двух хостингах.
- Проблема на стороне сервера Telegram. Глобальные сбои бывают редко, но не будем исключать их вероятность.
Отталкиваясь от возможных причин, автор составил список возможных решений. Ознакомиться с ним можете в разделе ниже.
Способы исправления
Примечательно, что автор и сам однажды столкнулся с этой проблемой, когда случайно загружал заброшенного на старом сервере бота на новый хостинг. По правилам разработчик должен сначала остановить чат-бота на старом устройстве, а после только запустить его на новом. Чтобы проверить, запущен ли уже бот, просто отправьте ему сообщение с командой /start. Обычно большинство приложений запрограммировано реагировать на эту команду.
В зависимости от результата ввода команды будут меняться и дальнейшие действия:
- Приложение ответило. Значит, оно запущено на старом сервере. Откройте его интерфейс и завершите работу процесса.
- Ответ не пришел. В таком случае, скорее всего, проблема кроется в самом токене. Проверьте, указан ли в конфигурациях выданный BotFather токен и укажите корректный идентификатор.

Вам помогло? Поделитесь с друзьями — помогите и нам!
для начала удалите
if __name__ == '__main__':
bot.polling(none_stop=True)
а webhook, у меня работает так:
WEBHOOK_HOST = 'URL' #без http:// и https://
WEBHOOK_PORT = 88 # 443, 80, 88 or 8443 (port need to be 'open')
WEBHOOK_LISTEN = '0.0.0.0' # In some VPS you may need to put here the IP addr
WEBHOOK_SSL_CERT = '/etc/nginx/ssl/FILE.cer' # Path to the ssl certificate
WEBHOOK_SSL_PRIV = '/etc/nginx/ssl/FILE.key' # Path to the ssl private key
WEBHOOK_URL_BASE = "https://%s:%s" % (WEBHOOK_HOST, WEBHOOK_PORT)
WEBHOOK_URL_PATH = "/%s/" % (constant.token)
bot = telebot.TeleBot(constant.token)
class WebhookServer(object):
@cherrypy.expose
def index(self):
if 'content-length' in cherrypy.request.headers and
'content-type' in cherrypy.request.headers and
cherrypy.request.headers['content-type'] == 'application/json':
length = int(cherrypy.request.headers['content-length'])
json_string = cherrypy.request.body.read(length).decode("utf-8")
update = telebot.types.Update.de_json(json_string)
# Эта функция обеспечивает проверку входящего сообщения
bot.process_new_updates([update])
return ''
else:
raise cherrypy.HTTPError(403)
bot.remove_webhook()
bot.set_webhook(url=WEBHOOK_URL_BASE + WEBHOOK_URL_PATH,
certificate=open(WEBHOOK_SSL_CERT, 'r'))
cherrypy.config.update({
'server.socket_host': WEBHOOK_LISTEN,
'server.socket_port': WEBHOOK_PORT,
'server.ssl_module': 'builtin',
'server.ssl_certificate': WEBHOOK_SSL_CERT,
'server.ssl_private_key': WEBHOOK_SSL_PRIV
})
cherrypy.quickstart(WebhookServer(), WEBHOOK_URL_PATH, {'/': {}})
18.11.2022
324 Просмотры
Природа происхождения ошибки 409 кроется в конфликте запросов. Не всегда эти запросы относятся к пользовательским. Например, такая ошибка может возникнуть при конфликте файлов сайта, если они обращаются к разным данным в одном файле. В результате этого, сервер возвращает ошибку, которая на самом деле не имеет отношения к запросам пользователей.
Основные причины возникновения ошибки 409:
- Пользователь обращается к данным, имеющим отличное значение или более новую версию. В итоге, сервер выдает ошибку 409, т.к. существует обновленная версия файла, страницы или скрипта.
- Ошибка 409 появилась в результате конфликтующих запросов внутри файлов на сервере. Решить проблему может программист.
- Использование прокси, которое конфликтует с определенными адресами или форматами запрашиваемых данных. Не путайте эту ошибку с ошибкой 407.
- Более распространенная причина – троян или вирус, который блокирует запросы к определенным сайтам или подгружает файл, который имеет конфликт с конфигурацией браузера.
- Ошибка 409 Conflicting Request в большинстве случае решается системным администратором или программистом, если это не касается заражения компьютера вирусом или трояном. Как проверить и какой программой расскажем ниже.
Чистим от вируса или трояна, чтобы убрать ошибку 409
Определить вирус/троян у вас или нет просто – установите программу Cureit от Dr.Web и просканируйте систему этой программой. Она бесплатная и не требует установки. Скачиваем только с официального сайта. В программе отмечаем все пункты для проверки и шагаем спать/на работу, т.к. сама проверка займет длительное время. На скриншоте ниже вы можете рассмотреть, как и что отмечать в программе. Свой антивирус лучше отключить перед проверкой.
Можно также использовать бесплатную утилиту от Касперского, но она довольно сложная и нужно понимать, какие скрипты вводить в консоль. Остальные программы – платные, поэтому не пишу о них. Кстати, не рекомендую скачивать бесплатные ключи, т.к. такие генераторы могут с собой принести тот самый вирус или троян. Не пожалейте 30$ в год за нормальную защиту.
Исправляем ошибку 409 в конкретном браузере
В случае, если ошибка 409 Conflicting Request появляется буквально на каждом сайте, чтобы вы ни нажимали – это точно троян или вирус. Причем это должно происходить в любом браузере. Если нет – можете сразу удалить и заново установить браузер. Возможно произошел сбой конфигурации браузера. Заранее нужно сохранить закладки, т.к. можно потерять все нажитое непосильным трудом. Делается это просто. На скриншоте выше вы видите пример сохранения настроек в браузере Mozilla. Аналогично делается и в остальных браузерах.
Последнее слово про ошибку
Если уж сильно хочется – установите программу CCleaner и пройдитесь по реестру с помощью этой программы. Во всяком случае это безопаснее, чем делать что-то лично ручками. Манипуляции с компьютером в случае с ошибкой 409 делать не стоит.
Загрузка…
A request to the Telegram API was unsuccessful and produced the following error.
telebot.apihelper.ApiException A request to the Telegram API was
unsuccessful. The Server returned HTTP 409 conflict
Telegram API was unsuccessful. The server returned HTTP 409 Conflict.
Response body:
[b'{"ok":false,"error_code":409,"description":"Conflict:
terminated by other getUpdates request; make sure that only one bot
instance is running"}']
ERROR - TeleBot: "A request to the Telegram API was unsuccessful.
The server returned HTTP 409 Conflict.
Response body:
[b'{"ok":false,"error_code":409,"description":"Conflict: terminated by other getUpdates
request; make sure that only one bot instance is running"}']"
(util.py:65 Polling Thread) ERROR - TeleBot: "ApiException occurred,
args=('A request to the Telegram API was unsuccessful. The server returned
HTTP 409 Conflict.
Response body:
n[b'{"ok":false,"error_code":409,"description":"Conflict: terminated by other getUpdates
request; make sure that only one bot instance is running"}']',)
What does this error mean?
|
Tiralion 0 / 0 / 0 Регистрация: 28.02.2021 Сообщений: 1 |
||||
|
1 |
||||
|
Telegram Bot 28.02.2021, 13:50. Показов 26624. Ответов 2 Метки нет (Все метки)
При написании простого бота
выползает ошибка ERROR — TeleBot: «A request to the Telegram API was unsuccessful. Error code: 409. Description: Conflict: can’t use getUpdates method while webhook is active; use deleteWebhook to delete the webhook first» что не так я делаю?
__________________
0 |
|
rooffall 1 / 1 / 0 Регистрация: 28.06.2020 Сообщений: 1 |
||||
|
25.03.2021, 23:52 |
2 |
|||
|
Видимо до этого пытались запустить бота не через polling, а webhook методом. Перед первом запуском кода вставьте строчку.
Позже эту строку можно будет удалить.
1 |
|
VetalM 1 / 1 / 0 Регистрация: 30.03.2020 Сообщений: 40 |
||||
|
28.03.2021, 10:33 |
3 |
|||
|
Попробуйте в самый конец файла добавить:
0 |
After deploy i have error on server
dokku logs kaufman-bot
root@vpsXXXX:~# dokku logs kaufman-bot
2022-02-21T04:47:54.805369331Z app[web.1]:
2022-02-21T04:47:54.805447585Z app[web.1]: > kaufman-bot@0.0.0 start /app
2022-02-21T04:47:54.805456814Z app[web.1]: > node dist/apps/server/main.js
2022-02-21T04:47:54.805462429Z app[web.1]:
2022-02-21T04:47:55.814014072Z app[web.1]: [Nest] 189 - 02/21/2022, 4:47:55 AM LOG [NestFactory] Starting Nest application...
2022-02-21T04:47:55.879257923Z app[web.1]: [Nest] 189 - 02/21/2022, 4:47:55 AM LOG [InstanceLoader] TelegrafModule dependencies initialized +102ms
2022-02-21T04:47:55.879823802Z app[web.1]: [Nest] 189 - 02/21/2022, 4:47:55 AM LOG [InstanceLoader] ScraperModule dependencies initialized +1ms
2022-02-21T04:47:55.880439058Z app[web.1]: [Nest] 189 - 02/21/2022, 4:47:55 AM LOG [InstanceLoader] DiscoveryModule dependencies initialized +0ms
2022-02-21T04:47:55.881300807Z app[web.1]: [Nest] 189 - 02/21/2022, 4:47:55 AM LOG [InstanceLoader] AppModule dependencies initialized +1ms
2022-02-21T04:47:56.099608409Z app[web.1]: [Nest] 189 - 02/21/2022, 4:47:56 AM LOG [InstanceLoader] TelegrafCoreModule dependencies initialized +219ms
2022-02-21T04:47:56.107084992Z app[web.1]: [Nest] 189 - 02/21/2022, 4:47:56 AM LOG [RoutesResolver] AppController {/api}: +7ms
2022-02-21T04:47:56.111708653Z app[web.1]: [Nest] 189 - 02/21/2022, 4:47:56 AM LOG [RouterExplorer] Mapped {/api, GET} route +5ms
2022-02-21T04:47:56.118433520Z app[web.1]: [Nest] 189 - 02/21/2022, 4:47:56 AM LOG [NestApplication] Nest application successfully started +7ms
2022-02-21T04:47:56.122906904Z app[web.1]: [Nest] 189 - 02/21/2022, 4:47:56 AM LOG 🚀 Application is running on: http://localhost:5000/api
2022-02-21T04:48:00.985747154Z app[web.1]: (node:189) UnhandledPromiseRejectionWarning: Error: 409: Conflict: terminated by other getUpdates request; make sure that only one bot instance is running
2022-02-21T04:48:00.985810814Z app[web.1]: at Telegram.callApi (/app/node_modules/telegraf/lib/core/network/client.js:264:19)
2022-02-21T04:48:00.985819571Z app[web.1]: at processTicksAndRejections (internal/process/task_queues.js:95:5)
2022-02-21T04:48:00.985826394Z app[web.1]: at async Polling.[Symbol.asyncIterator] (/app/node_modules/telegraf/lib/core/network/polling.js:27:33)
2022-02-21T04:48:00.985849961Z app[web.1]: at async Polling.loop (/app/node_modules/telegraf/lib/core/network/polling.js:70:30)
2022-02-21T04:48:00.985856303Z app[web.1]: (Use `node --trace-warnings ...` to show where the warning was created)
2022-02-21T04:48:00.985872448Z app[web.1]: (node:189) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
2022-02-21T04:48:00.985936312Z app[web.1]: (node:189) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Enter fullscreen mode
Exit fullscreen mode

For solve this error change libs/plugins/server/src/lib/scraper/scraper-services/scraper.service.ts
import { Inject, Injectable, Logger } from '@nestjs/common';
import axios from 'axios';
import charset from 'charset';
import cheerio from 'cheerio';
import encoding from 'encoding';
import htmlToText from 'html-to-text';
import jschardet from 'jschardet';
import { render } from 'mustache';
import {
ScraperConfig,
SCRAPER_CONFIG,
} from '../scraper-config/scraper.config';
import { ScraperCommandsEnum } from '../scraper-types/scraper-commands';
@Injectable()
export class ScraperService {
private readonly logger = new Logger(ScraperService.name);
constructor(
@Inject(SCRAPER_CONFIG)
private readonly scraperConfig: ScraperConfig
) {}
async onMessage(msg) {
const locale = msg.from?.language_code || null;
const spyWord = this.scraperConfig.spyWords.find((spyWord) =>
msg.text.toLowerCase().includes(spyWord.toLowerCase())
);
if (spyWord) {
if (
msg.text.includes(`/${ScraperCommandsEnum.help}`) ||
msg.text.includes(ScraperCommandsEnum.help)
) {
const replayHelpMessage =
(locale && this.scraperConfig.helpLocale?.[locale]) ||
this.scraperConfig.help;
return replayHelpMessage;
}
const preparedText = msg.text
.split(spyWord)
.join('')
.split(' ')
.join('')
.trim();
const replayMessage = await this.scrap(locale, preparedText);
if (replayMessage) {
return replayMessage;
}
this.logger.warn(`Unhandled commands for text: "${msg.text}"`);
this.logger.debug(msg);
}
return null;
}
private async scrap(locale: string, text: string) {
/*const parsedVariables = parse(this.scraperConfig.uri)
.filter((arr) => arr[0] === 'name')
.map((arr) => arr[1]);
const otherText = text;*/
const replaceVariables = { text: encodeURIComponent(text.trim()), locale };
(this.scraperConfig.removeWords || []).forEach((removeWord: string) => {
text = text
.replace(new RegExp(removeWord, 'ig'), '')
.replace(new RegExp(' {2}', 'ig'), ' ')
.trim();
});
const textArray = text.split(' ');
if (textArray.length > 0) {
textArray.forEach((textArrayItem: string, textArrayIndex: number) => {
replaceVariables[`text ${textArrayIndex + 1}`] = textArrayItem;
});
textArray.forEach((textArrayItem: string, textArrayIndex: number) => {
replaceVariables[`text${textArrayIndex + 1}`] =
textArrayItem.toLowerCase();
});
textArray.forEach((textArrayItem: string, textArrayIndex: number) => {
replaceVariables[`TEXT${textArrayIndex + 1}`] =
textArrayItem.toUpperCase();
});
}
const repalcedUri = render(this.scraperConfig.uri, replaceVariables);
// const replacedText = render(text, replaceVariables);
const axiosInstance = axios.create({
timeout: this.scraperConfig.timeout,
responseEncoding: this.scraperConfig.contentCodepage || 'binary',
});
try {
const response = await axiosInstance.get(repalcedUri);
const $ = cheerio.load(response.data);
let content = this.scraperConfig.contentSelector
.split(',')
.map((selector: string) => htmlToText.fromString($(selector).html()))
.join('nn');
console.log(content);
const enc =
charset(response.headers, response.data) ||
jschardet.detect(response.data).encoding.toLowerCase();
if (enc !== 'utf8') {
content = encoding
.convert(Buffer.from(content, 'binary'), 'utf8', enc, true)
.toString('utf8');
}
return content;
} catch (err) {
this.logger.error(err, err.stack);
return err.toString();
}
}
}
Enter fullscreen mode
Exit fullscreen mode
Change libs/plugins/server/src/lib/scraper/scraper.module.ts
import { DynamicModule, Module } from '@nestjs/common';
import { ScraperConfig, SCRAPER_CONFIG } from './scraper-config/scraper.config';
import { ScraperService } from './scraper-services/scraper.service';
@Module({})
export class ScraperModule {
static forRoot(config: ScraperConfig): DynamicModule {
return {
module: ScraperModule,
providers: [
{
provide: SCRAPER_CONFIG,
useValue: config,
},
ScraperService,
],
exports: [ScraperService],
};
}
}
Enter fullscreen mode
Exit fullscreen mode
And change apps/server/src/app/app.service.ts
import { ScraperService } from '@kaufman-bot/plugins/server';
import { Injectable } from '@nestjs/common';
import { Hears, Help, On, Start, Update, Message } from 'nestjs-telegraf';
import { Context } from 'telegraf';
@Update()
@Injectable()
export class AppService {
constructor(private readonly scraperService: ScraperService) {}
getData(): { message: string } {
return { message: 'Welcome to server!' };
}
@Start()
async startCommand(ctx: Context) {
await ctx.reply('Welcome');
}
@Help()
async helpCommand(ctx: Context) {
await ctx.reply('Send me a sticker');
}
@On('sticker')
async onSticker(ctx: Context) {
await ctx.reply('👍');
}
@Hears('hi')
async hearsHi(ctx: Context) {
await ctx.reply('Hey there');
}
@On('text')
async onMessage(@Message() msg) {
const scraperReplayMessage = await this.scraperService.onMessage(msg);
return scraperReplayMessage;
}
}
Enter fullscreen mode
Exit fullscreen mode