<commit_before>const request  = require('request');
const config   = require('../config');
const db       = require('../db');
const compiler = require('./compiler.js');
const logger   = require('bole')('tg');
const fs       = require('fs');

var token = config('telegram').token;

if (!token) {
	throw new Error('Missing token');
}

const BASE_URL = 'https://api.telegram.org/bot' + token;

const ENDPOINTS = {
	sendMessage: BASE_URL + '/sendMessage',
	sendPhoto: BASE_URL + '/sendPhoto',
	editMessage: BASE_URL + '/editMessageText',
	answerCallbackQuery: BASE_URL + '/answerCallbackQuery',
	sendChatAction: BASE_URL + '/sendChatAction',
	getFile: BASE_URL + '/getFile'
};

config['baseFileUrl'] = 'https://api.telegram.org/file/bot' + token;

class TelegramClient {
	constructor() {
		
	}
	
	/**
	 * Analyze Telegram response. Generates a "result" object
	 */
	_analyzeResponse(req, err, res, body) {
		var result = { ok: true };
		
		// Network error
		if (err) {
			var e = {
				request: req,
				error: {
					name: err.name,
					message: err.message,
					stack: err.stack,
					code: err.code
				}
			};
			
			logger.error(e, 'Network error');
			
			result['ok'] = false;
			//result['retry'] = true;
		}
		// Response code is not OK
		else if (res.statusCode != 200) {
			result['ok'] = false;
			//result['retry'] = false;
			
			// Retry the req. in case of Too Many Requests
			// or Telegram server error
			//if (res.statusCode.toString()[0] == '5' || res.statusCode == 429) {
			//	result['retry'] = true;
			//}
			
			if (body && typeof body === 'object') {
				var description = body['description'];
				
				var reasons = [
					// the bot was blocked by the user
					{ text: 'Bot was blocked', status: -10 },
					// the user doesn't exist anymore
					{ text: 'deleted user', status: -20 },
					{ text: 'user is deleted', status: -20 },
					{ text: 'user is deactivated', status: -20 },
					// the group has been deleted
					{ text: 'group chat is deactivated', status: -30 },
					// the bot was removed from the (super)group
					{ text: 'bot was kicked from the', status: -40 },
					{ text: 'bot is not a member of the supergroup chat', status: -40 }
				];
				
				reasons.forEach((r) => {
					if (description.includes(r['text'])) {
						result['newStatus'] = r['status'];
					}
				});
				
				if (description.includes('migrated to a supergroup')) {
					result['migrate'] = body['parameters']['migrate_to_chat_id'];
				}
				
				if (description.includes('message is not modified')) {
					result['ignore'] = true;
				}
			}
			
			if (!result['newStage'] && !result['migrate'] && !result['ignore']) {
				logger.error({ response: body, request: req }, 'Response error:', res.statusCode);
			}
		}
		// Response content not ok and for some reason statusCode is 200 OK
		else if (body['ok'] === false) {
			logger.error({ response: body, request: req }, 'Response error');
			
			result['ok'] = false;
			//result['retry'] = false;
		}
		
		return result;
	}
	
	_replaceKeyboardPlaceholders(kb) {
		kb.forEach((line) => {
			line.forEach((btn) => {
				if (btn['text'] && btn['text'].slice(0, 2) == '$$') {
					btn['text'] = compiler(btn['text'].slice(2), {});
				}
			});
		});
	}
	
	/**
	 * Send a message
	 */
	sendMessage(options, callback) {
		let chatId = options['chat'];<commit_msg>[telegram] 'bot was blocked' detection improved<commit_after>const request  = require('request');
const config   = require('../config');
const db       = require('../db');
const compiler = require('./compiler.js');
const logger   = require('bole')('tg');
const fs       = require('fs');

var token = config('telegram').token;

if (!token) {
	throw new Error('Missing token');
}

const BASE_URL = 'https://api.telegram.org/bot' + token;

const ENDPOINTS = {
	sendMessage: BASE_URL + '/sendMessage',
	sendPhoto: BASE_URL + '/sendPhoto',
	editMessage: BASE_URL + '/editMessageText',
	answerCallbackQuery: BASE_URL + '/answerCallbackQuery',
	sendChatAction: BASE_URL + '/sendChatAction',
	getFile: BASE_URL + '/getFile'
};

config['baseFileUrl'] = 'https://api.telegram.org/file/bot' + token;

class TelegramClient {
	constructor() {
		
	}
	
	/**
	 * Analyze Telegram response. Generates a "result" object
	 */
	_analyzeResponse(req, err, res, body) {
		var result = { ok: true };
		
		// Network error
		if (err) {
			var e = {
				request: req,
				error: {
					name: err.name,
					message: err.message,
					stack: err.stack,
					code: err.code
				}
			};
			
			logger.error(e, 'Network error');
			
			result['ok'] = false;
			//result['retry'] = true;
		}
		// Response code is not OK
		else if (res.statusCode != 200) {
			result['ok'] = false;
			//result['retry'] = false;
			
			// Retry the req. in case of Too Many Requests
			// or Telegram server error
			//if (res.statusCode.toString()[0] == '5' || res.statusCode == 429) {
			//	result['retry'] = true;
			//}
			
			if (body && typeof body === 'object') {
				var description = body['description'];
				
				var reasons = [
					// the bot was blocked by the user
					{ text: 'bot was blocked', status: -10 },
					// the user doesn't exist anymore
					{ text: 'deleted user', status: -20 },
					{ text: 'user is deleted', status: -20 },
					{ text: 'user is deactivated', status: -20 },
					// the group has been deleted
					{ text: 'group chat is deactivated', status: -30 },
					// the bot was removed from the (super)group
					{ text: 'bot was kicked from the', status: -40 },
					{ text: 'bot is not a member of the supergroup chat', status: -40 }
				];
				
				reasons.forEach((r) => {
					if (description.includes(r['text'])) {
						result['newStatus'] = r['status'];
					}
				});
				
				if (description.includes('migrated to a supergroup')) {
					result['migrate'] = body['parameters']['migrate_to_chat_id'];
				}
				
				if (description.includes('message is not modified')) {
					result['ignore'] = true;
				}
			}
			
			if (!result['newStatus'] && !result['migrate'] && !result['ignore']) {
				logger.error({ response: body, request: req }, 'Response error:', res.statusCode);
			}
		}
		// Response content not ok and for some reason statusCode is 200 OK
		else if (body['ok'] === false) {
			logger.error({ response: body, request: req }, 'Response error');
			
			result['ok'] = false;
			//result['retry'] = false;
		}
		
		return result;
	}
	
	_replaceKeyboardPlaceholders(kb) {
		kb.forEach((line) => {
			line.forEach((btn) => {
				if (btn['text'] && btn['text'].slice(0, 2) == '$$') {
					btn['text'] = compiler(btn['text'].slice(2), {});
				}
			});
		});
	}
	
	/**
	 * Send a message
	 */
	sendMessage(options, callback) {
		let chatId = options['chat'];
{'fraction_non_alphanumeric': 0.17663732657019246, 'fraction_numerical': 0.008354468148590184, 'mean_word_length': 2.8396334478808707, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7112567', 'n_tokens_mistral': 2663, 'n_tokens_neox': 2165, 'n_words': 584}