├── .env.example ├── .gitignore ├── .sonarcloud.properties ├── Dockerfile ├── LICENSE ├── LOG.md ├── README.md ├── bot ├── __init__.py ├── __main__.py ├── functions │ ├── __init__.py │ ├── backends │ │ ├── __init__.py │ │ └── add_your_functions_here.txt │ └── openai_front │ │ ├── __init__.py │ │ ├── here_functions_formatted_for_gpt.txt │ │ ├── phone_specs.py │ │ ├── weather.py │ │ └── web_search.py └── src │ ├── __init__.py │ ├── apis │ ├── __init__.py │ ├── duckduckgo.py │ ├── imagine.py │ ├── opengpt │ │ ├── __init__.py │ │ └── evagpt4.py │ ├── smart_gsm.py │ ├── stablehorde.py │ └── wttr.py │ ├── handlers │ ├── __init__.py │ ├── callbacks │ │ ├── imagine.py │ │ └── stablehorde.py │ ├── commands │ │ ├── __init__.py │ │ ├── api.py │ │ ├── cancel.py │ │ ├── chat_mode.py │ │ ├── help.py │ │ ├── img.py │ │ ├── imodel.py │ │ ├── iratio.py │ │ ├── istyle.py │ │ ├── lang.py │ │ ├── model.py │ │ ├── new.py │ │ ├── props.py │ │ ├── reset.py │ │ ├── retry.py │ │ ├── search.py │ │ ├── start.py │ │ └── status.py │ ├── document.py │ ├── error.py │ ├── menu.py │ ├── message.py │ ├── ocr_image.py │ ├── semaphore.py │ ├── timeout.py │ ├── url.py │ └── voice.py │ ├── start.py │ ├── tasks │ ├── __init__.py │ ├── apis_chat.py │ ├── apis_check_idler.py │ ├── apis_image.py │ └── cache.py │ └── utils │ ├── __init__.py │ ├── checks │ ├── __init__.py │ ├── c_bot_mentioned.py │ ├── c_callback.py │ ├── c_chat.py │ ├── c_lang.py │ ├── c_message.py │ ├── c_message_not_answered_yet.py │ └── c_parameters.py │ ├── config.py │ ├── constants.py │ ├── database.py │ ├── gen_utils │ ├── __init__.py │ ├── make_completion.py │ ├── make_image.py │ ├── make_transcription.py │ ├── middleware.py │ ├── openai │ │ ├── __init__.py │ │ ├── openai_completion.py │ │ ├── openai_functions.py │ │ └── openai_functions_extraction.py │ └── phase.py │ ├── misc.py │ ├── preprocess │ ├── __init__.py │ ├── count_tokens.py │ ├── make_messages.py │ ├── make_prompt.py │ ├── parse_headers.py │ ├── remove_words.py │ └── tokenizer.py │ └── proxies.py ├── config ├── api.example.json ├── chat_mode.example.json ├── model.example.json └── openai_completion_options.example.json ├── docker-compose.example.yml ├── docker-compose.no-mongodb.yml ├── docs ├── readme │ ├── ar.md │ ├── de.md │ ├── en.md │ ├── es.md │ ├── fr.md │ ├── it.md │ ├── jp.md │ ├── nl.md │ ├── pt.md │ ├── ru.md │ └── zh.md └── variables │ ├── ar.md │ ├── de.md │ ├── en.md │ ├── es.md │ ├── fr.md │ ├── it.md │ ├── jp.md │ ├── nl.md │ ├── pt.md │ ├── ru.md │ └── zh.md ├── locales ├── lang.ar.json ├── lang.de.json ├── lang.en.json ├── lang.es.json ├── lang.fr.json ├── lang.it.json ├── lang.jp.json ├── lang.nl.json ├── lang.pt.json ├── lang.ru.json ├── lang.zh.json └── props.json ├── requirements.txt └── static └── help_group_chat.mp4 /.env.example: -------------------------------------------------------------------------------- 1 | MONGODB_HOST=mongo 2 | MONGODB_USERNAME=root 3 | MONGODB_PASSWORD=GDT9MbJUTFHpyJyeS2JxzgkpYTjnrU8v 4 | # check https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables for more 5 | 6 | TELEGRAM_TOKEN=6101..... 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | 131 | # Custom 132 | config/api.yml 133 | config/chat_mode.yml 134 | config/model.yml 135 | config/openai_completion_options.yml 136 | bot/config_dev.py 137 | docker-compose.dev.yml 138 | 139 | docker-compose.yml 140 | todo.txt 141 | bot/apis/OpenGPTtt/ 142 | .vscode 143 | dummys/ 144 | mongodb/ 145 | bot/test.py 146 | event_log.txt 147 | 148 | proxies/ 149 | bot/src/utils/checks/proxies.py 150 | bot/src/utils/checks/c_parameters_old.py 151 | bot/src/apis/imaginepy/ 152 | bot/src/utils/database.py.ogog 153 | bot/src/utils/database.py.jsontemp 154 | bot/src/utils/database.py.bakeñ 155 | test.py 156 | -------------------------------------------------------------------------------- /.sonarcloud.properties: -------------------------------------------------------------------------------- 1 | sonar.python.version=3.11.3 -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.11.6-alpine3.18 2 | 3 | # Por alguna razón, si se elimina PYTHONUNBUFFERED, no se imprimen algunos mensajes de error o información relevante... 4 | ENV PYTHONUNBUFFERED=1 5 | 6 | WORKDIR / 7 | 8 | RUN mkdir -p /database 9 | 10 | COPY bot/ /bot 11 | COPY static/ /static 12 | COPY requirements.txt /requirements.txt 13 | COPY config/api.example.json config/api.json 14 | COPY config/chat_mode.example.json config/chat_mode.json 15 | COPY config/model.example.json config/model.json 16 | COPY locales/ /locales 17 | COPY config/openai_completion_options.example.json config/openai_completion_options.json 18 | 19 | # Instalar dependencias 20 | RUN apk update && \ 21 | apk add --no-cache --virtual .build-deps \ 22 | alpine-sdk \ 23 | python3-dev \ 24 | py3-pip && \ 25 | apk add --no-cache \ 26 | sox \ 27 | tesseract-ocr \ 28 | tesseract-ocr-data-spa \ 29 | tesseract-ocr-data-ara \ 30 | tesseract-ocr-data-eng \ 31 | tesseract-ocr-data-jpn \ 32 | tesseract-ocr-data-chi_sim \ 33 | tesseract-ocr-data-chi_tra \ 34 | tesseract-ocr-data-deu \ 35 | tesseract-ocr-data-fra \ 36 | tesseract-ocr-data-rus \ 37 | tesseract-ocr-data-por \ 38 | tesseract-ocr-data-ita \ 39 | tesseract-ocr-data-nld && \ 40 | pip3 install --no-cache-dir -r requirements.txt && \ 41 | apk del .build-deps && apk del rustup && \ 42 | rm -rf /var/cache/apk/* 43 | 44 | CMD ["python", "-m", "bot"] 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Karim Iskakov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LOG.md: -------------------------------------------------------------------------------- 1 | ## Cambios anteriores: 2 | - Migración de YAML a JSON. Ajusten sus archivos de configuracion. 3 | - Base de datos completamente local! Evitémonos de ejecutar un sistema gigantezco para administrar una base de datos de 1MB o menos :P (se activa con WITHOUT_MONGODB=True). 4 | - Llamadas a funciones agregado! Pueden desactivarlo con la variable FEATURE_FUNCTION_CALLS=True/False 5 | - Proxificacion de APIs exceptuando al bot, usen la variable API_TUNNEL=http://ip:puerto 6 | - sistema de tiempo de espera y reintento. 7 | - simplificación y mejora de las indicaciones. 8 | - optimización de los mensajes cuando se alcanza el límite de tokens. 9 | - utilizar el máximo de tokens posibles para completar / siempre por debajo del límite de tokens. 10 | - Nuevas variables: REQUEST_MAX_RETRIES y REQUEST_TIMEOUT, REQUEST_TIMEOUT es en segundos. 11 | - Reestructuración de código. 12 | - La generación de imágenes ahora pregunta si descargar o eliminar los documentos, tiempo de expiración por defecto: 5 minutos. 13 | - 3 comandos nuevos. /search, /status y /reset. 14 | - Los comandos /help y /start ahora llaman a la API de GPT para ser asistente en la ayuda del bot. 15 | - Optimizaciones 16 | - APICHECK fuera. muchos problemas 17 | - Modo de chat Karen y DAN agregados. funcionan bien con gpt-3/davinci 18 | - Sistema básico de caché. 19 | - 2 APIs nuevas, EvaGPT4 y Churchless 20 | - Mongo Async 21 | - Botones de Cancelar y Reintentar en los mensajes 22 | - Código del menu re hecho y añadido paginación. 23 | - Código de peticiones a APIs re hecho. 24 | - Mejor gestión de errores. 25 | - Se añadieron variables a docker-compose para habilitar o deshabilitar características del bot a elección del administrador. 26 | - Se corrigió el streaming de algunas APIs 27 | - *MultiLenguaje!*: 28 | - "es": Español 29 | - "ar": عربي 30 | - "en": English 31 | - "jp": 日本語 32 | - "zh": 中文 33 | - "de": Deutsch 34 | - "fr": Français 35 | - "ru": Русский 36 | - "pt": Português 37 | - "it": Italiano 38 | - "nl": Nederlands 39 | 40 | Establece el idioma por defecto del sistema en la variable AUTO_LANG 41 | Los lenguajes están *COMPLETAMENTE* traducidos... O eso creo. 42 | - *Lectura de imágenes con OCR* 43 | - Gracias a Tesseract! Se agregó todos los lenguajes disponibles para el bot. 44 | - Si deseas desactivar lenguajes antes de construir el contenedor, estarán en Dockerfile. 45 | - Se cambió el diálogo de usuarios, por el diálogo de chatID para mejor contexto grupal. 46 | - Añadido MongoDB compatible con CPUs antiguas. 47 | - Soporte de lectura de archivos de texto, PDF y de enlaces. 48 | - Se reemplazó el modo "👩‍🎨 Artista básico" con el comando /img. 49 | - Preguntar si iniciar nueva conversación si lleva tiempo sin chatear (TIMEOUT_ASK y DIALOG_TIMEOUT en docker-compose.yml) 50 | - Borrar historiales antiguos al usar /new. 51 | - Añadidas variables a docker-compose para limitar el tamaño de los audios, documentos, paginas de PDF y urls. 52 | - La transcripción de mensajes de voz ahora también funciona para archivos de audio. 53 | - Base en Minideb. 54 | - Se eliminó el seguimiento de tokens. 55 | - Preferencias de API por usuario! 56 | - Si la api actual del usuario no soporta voz o imagen, se usará una api predefinida. 57 | - El generador de imágenes envía las imágenes comprimidas y en formato sin comprimir (archivo) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [![es](https://img.shields.io/badge/L%C3%A9eme-es-blue)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/readme/es.md) 3 | [![en](https://img.shields.io/badge/ReadMe-en-red)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/readme/en.md) 4 | [![ar](https://img.shields.io/badge/اقرأ-عربي-green)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/readme/ar.md) 5 | [![zh](https://img.shields.io/badge/阅读-中文-yellow)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/readme/zh.md) 6 | [![jp](https://img.shields.io/badge/読む-日本語-orange)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/readme/jp.md) 7 | [![de](https://img.shields.io/badge/Lesen-de-brightgreen)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/readme/de.md) 8 | [![fr](https://img.shields.io/badge/Lire-fr-lightgrey)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/readme/fr.md) 9 | [![it](https://img.shields.io/badge/Leggi-it-blueviolet)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/readme/it.md) 10 | [![ru](https://img.shields.io/badge/Читать-русский-yellowgreen)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/readme/ru.md) 11 | [![pt](https://img.shields.io/badge/Leia-pt-critical)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/readme/pt.md) 12 | [![nl](https://img.shields.io/badge/Lees-nl-informational)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/readme/nl.md) 13 | -------------------------------------------------------------------------------- /bot/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/__init__.py -------------------------------------------------------------------------------- /bot/__main__.py: -------------------------------------------------------------------------------- 1 | from bot.src.utils.constants import logger 2 | from bot.src.start import run_bot 3 | 4 | if __name__ == "__main__": 5 | logger.info("🤖") 6 | run_bot() 7 | -------------------------------------------------------------------------------- /bot/functions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/functions/__init__.py -------------------------------------------------------------------------------- /bot/functions/backends/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/functions/backends/__init__.py -------------------------------------------------------------------------------- /bot/functions/backends/add_your_functions_here.txt: -------------------------------------------------------------------------------- 1 | ### ChatGPTG, https://gg.resisto.rodeo/yo/chatgpTG / https://github.com/soyelmismo/chatgpTG 2 | 3 | This is intended to be the main backend for your custom openai functions 4 | 5 | to keep everything clean and without much dirty content -------------------------------------------------------------------------------- /bot/functions/openai_front/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/functions/openai_front/__init__.py -------------------------------------------------------------------------------- /bot/functions/openai_front/here_functions_formatted_for_gpt.txt: -------------------------------------------------------------------------------- 1 | ### ChatGPTG, https://gg.resisto.rodeo/yo/chatgpTG / https://github.com/soyelmismo/chatgpTG 2 | 3 | 4 | from bot.src.utils.constants import ERRFUNC, FUNCNOARG # Default error messages 5 | from bot.src.utils.gen_utils.openai.openai_functions_extraction import openaifunc # Do not touch this 6 | 7 | 8 | from bot.functions.backends import my_module # Import your custom function here 9 | 10 | @openaifunc 11 | async def descriptive_function(self, important_arg: str, arguments that gpt will send, arg999: int) -> str: 12 | """ 13 | My general description for the function . 14 | 15 | Args: 16 | arg1 (str): receives something useful like a city or a text. 17 | 18 | Returns: 19 | str: the thing that will be returned to gpt 20 | """ 21 | 22 | if important_arg: #to verify if the most important argument is present 23 | try: 24 | return await my_module.init_function(self, important_arg) 25 | except Exception: return ERRFUNC 26 | else: return FUNCNOARG 27 | -------------------------------------------------------------------------------- /bot/functions/openai_front/phone_specs.py: -------------------------------------------------------------------------------- 1 | from bot.src.utils.constants import ERRFUNC, FUNCNOARG 2 | from bot.src.utils.gen_utils.openai.openai_functions_extraction import openaifunc 3 | 4 | from bot.src.apis import smart_gsm 5 | @openaifunc 6 | async def search_smartphone_info(self, model: str) -> str: 7 | """ 8 | Receives the device name and makes a search in the smart_gsm website returning all the device info. 9 | 10 | Args: 11 | model (str): only the device model, without extra text. 12 | 13 | Returns: 14 | str: all the device specifications to be tell to the user 15 | """ 16 | if model: 17 | try: 18 | return await smart_gsm.get_device(self, query = model) 19 | except Exception: return ERRFUNC 20 | else: return FUNCNOARG 21 | -------------------------------------------------------------------------------- /bot/functions/openai_front/weather.py: -------------------------------------------------------------------------------- 1 | from bot.src.utils.constants import ERRFUNC, FUNCNOARG 2 | from bot.src.utils.gen_utils.openai.openai_functions_extraction import openaifunc 3 | from bot.src.apis import wttr 4 | @openaifunc 5 | async def lookup_weather(self, location: str, unit: str) -> str: 6 | """ 7 | Search actual weather info. 8 | 9 | Args: 10 | location (str): the city. mandatory. 11 | unit: "C" or "F". mandatory, and depends of the city 12 | 13 | Returns: 14 | str: all the weather info to be tell to the user 15 | """ 16 | if location: 17 | try: 18 | return await wttr.getweather(location = location, unit = unit) 19 | except Exception: return ERRFUNC 20 | else: return FUNCNOARG 21 | -------------------------------------------------------------------------------- /bot/functions/openai_front/web_search.py: -------------------------------------------------------------------------------- 1 | from bot.src.utils.constants import ERRFUNC, FUNCNOARG 2 | from bot.src.utils.gen_utils.openai.openai_functions_extraction import openaifunc 3 | from bot.src.apis import duckduckgo 4 | @openaifunc 5 | async def search_on_internet(self, query: str, search_type: str, timelimit: str = None) -> str: 6 | """ 7 | Search information/recommendations and news on internet 8 | Reveives a search query to search information and recommendations on the web. talk freely about the results. 9 | 10 | Args: 11 | query (str): the text that will be searched 12 | search_type (str): use "text" or "news" depending of what the user has requested 13 | timelimit (str): use "d" if latest results from today, for other time limits: "w", "m", "y". Defaults to None. they are d(day), w(week), m(month), y(year). 14 | 15 | Returns: 16 | str: the search / news results to inform the user 17 | """ 18 | if query: 19 | try: 20 | return await duckduckgo.search(self, query = query, gptcall = True, timelimit = timelimit, type = search_type) 21 | except Exception: return ERRFUNC 22 | else: return FUNCNOARG -------------------------------------------------------------------------------- /bot/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/src/__init__.py -------------------------------------------------------------------------------- /bot/src/apis/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/src/apis/__init__.py -------------------------------------------------------------------------------- /bot/src/apis/duckduckgo.py: -------------------------------------------------------------------------------- 1 | from itertools import islice 2 | from duckduckgo_search import DDGS 3 | from bot.src.utils.config import pred_lang 4 | async def search(self=None, query=None, gptcall=None, timelimit: str = None, type='text'): 5 | try: 6 | if not query: return 7 | if not self.lang: self.lang=pred_lang 8 | resultados=[] 9 | with DDGS(proxies=self.proxies) as ddgs: 10 | if type == "text": 11 | fn = ddgs.text 12 | else: 13 | fn = ddgs.news 14 | ddgs_gen = fn(keywords=query, region=f'{self.lang}-{self.lang}', safesearch='Off', timelimit=timelimit) 15 | for r in islice(ddgs_gen, 10): resultados.append(r) 16 | formatted_backend = [] 17 | formatted_results = [] 18 | for resultado in resultados: 19 | title = resultado['title'] 20 | href = resultado['href'] if type == "text" else resultado['url'] 21 | body = resultado['body'] 22 | formatted_result = f"- [{title}]({href}): {body}" 23 | backend_result = f"[{title}]({href}): {body}" 24 | formatted_results.append(formatted_result) 25 | formatted_backend.append(backend_result) 26 | formatted_results_string = '\n\n'.join(formatted_results) 27 | formatted_results_backend = '\n\n'.join(formatted_backend) 28 | if gptcall == True: 29 | return formatted_results_backend 30 | else: 31 | return formatted_results_backend, formatted_results_string 32 | except Exception as e: raise ConnectionError(e) -------------------------------------------------------------------------------- /bot/src/apis/opengpt/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/src/apis/opengpt/__init__.py -------------------------------------------------------------------------------- /bot/src/apis/opengpt/evagpt4.py: -------------------------------------------------------------------------------- 1 | from aiohttp import ClientSession 2 | from ujson import loads, dumps, JSONDecodeError 3 | 4 | async def create(self): 5 | 6 | async with ClientSession() as session: 7 | async with session.post("https://ava-alpha-api.codelink.io/api/chat", 8 | headers={"content-type": "application/json"}, 9 | data=dumps(self.diccionario), proxy=self.proxies) as response: 10 | try: 11 | async for line in response.content: 12 | try: 13 | line_text = line.decode("utf-8").strip() 14 | 15 | data_json = loads(line_text[len("data:"):]) 16 | 17 | choices = data_json.get("choices", []) 18 | 19 | if not choices: 20 | continue 21 | 22 | for choice in choices: 23 | if choice.get("finish_reason") == "stop": 24 | break 25 | 26 | if "delta" in choice and "content" in choice.get("delta"): 27 | content = choice.get("delta", {}).get("content", "") 28 | yield "not_finished", content 29 | except (JSONDecodeError, IndexError, KeyError): 30 | continue 31 | except Exception as e: 32 | raise ConnectionError(f'{__name__}: {e}') 33 | -------------------------------------------------------------------------------- /bot/src/apis/smart_gsm.py: -------------------------------------------------------------------------------- 1 | from aiohttp import ClientSession 2 | from ujson import loads 3 | from bot.src.handlers.url import extract_from_url 4 | 5 | base = "https://www.smart-gsm.com/moviles" 6 | headers = { 7 | "Accept": "*/*", 8 | "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" 9 | } 10 | 11 | async def get_device(self, query: str = ""): 12 | 13 | url = f"{base}/autocomplete/{query}" 14 | 15 | async with ClientSession() as session: 16 | try: 17 | async with session.get(url, headers=headers, proxy=self.proxies) as resp: 18 | data = await resp.text() 19 | response_obj = loads(data) 20 | if not response_obj: return "Dile al usuario que falló la búsqueda o que posiblemente no exista ese modelo de telefono" 21 | 22 | permalink = response_obj[0].get("permalink") 23 | if not permalink: return "Dile al usuario que falló la búsqueda o que posiblemente no exista ese modelo de telefono" 24 | 25 | data = await extract_from_url(f"{base}/{permalink}") 26 | return data 27 | except Exception as e: raise ConnectionError(e) 28 | -------------------------------------------------------------------------------- /bot/src/apis/stablehorde.py: -------------------------------------------------------------------------------- 1 | import aiohttp 2 | import asyncio 3 | import io 4 | import uuid 5 | import secrets 6 | import base64 7 | 8 | api_base = 'https://stablehorde.net/api/v2' 9 | check_url = f'{api_base}/generate/check' 10 | status_url = f'{api_base}/generate/status' 11 | 12 | 13 | from bot.src.utils.config import apisproxy, n_images 14 | from bot.src.utils.constants import logger 15 | 16 | stablehorde_models = None 17 | 18 | class Models: 19 | def __init__(self, model_name): 20 | self.model_name = model_name 21 | 22 | @classmethod 23 | async def get_models(cls, proxy=None): 24 | url = f'{api_base}/status/models' 25 | 26 | async with aiohttp.ClientSession() as session: 27 | async with session.get(url, proxy=proxy) as response: 28 | data = await response.json() 29 | 30 | sorted_data = sorted(data, key=lambda x: x["count"], reverse=True) 31 | 32 | for model in sorted_data: 33 | model["name"] = f'{model["name"]} ({model["count"]})' 34 | 35 | image_models = [model["name"] for model in sorted_data if model["type"] == "image" and int(model["count"]) > 5] 36 | models = {index: cls(model_name) for index, model_name in enumerate(image_models)} 37 | 38 | return models 39 | 40 | async def setup_vars(): 41 | global stablehorde_models 42 | models_sh = await Models.get_models(proxy=apisproxy) 43 | stablehorde_models = {index: model_instance.model_name for index, model_instance in models_sh.items()} 44 | # Resto del código que utiliza stablehorde_models 45 | loop = asyncio.get_event_loop() 46 | loop.run_until_complete(setup_vars()) 47 | 48 | 49 | async def main(self, api_key, prompt: str = 'egg', model: str = 'Deliberate', 50 | seed = None, steps: int = 20, n_images: int = n_images): 51 | 52 | model = stablehorde_models.get(int(model)) 53 | model = model.split('(', 1)[0].strip() 54 | 55 | url = f'{api_base}/generate/async' 56 | 57 | headers = { 58 | "apikey": f'{api_key}', 59 | "Content-Type": "application/json", 60 | "Accept": "*/*" 61 | } 62 | 63 | payload = { 64 | "prompt": prompt, 65 | "params": { 66 | "steps": steps, 67 | "n": 1, 68 | "sampler_name": "k_euler", 69 | "width": 512, 70 | "height": 512, 71 | "cfg_scale": 7, 72 | "seed_variation": 1000, 73 | "seed": str(seed) if seed else "", 74 | "karras": True, 75 | "denoising_strength": 0.75, 76 | "tiling": False, 77 | "hires_fix": True, 78 | "clip_skip": 1, 79 | #"post_processing": [ 80 | # "GFPGAN", 81 | # "RealESRGAN_x4plus_anime_6B" 82 | #] 83 | }, 84 | "nsfw": True, 85 | "censor_nsfw": False, 86 | "trusted_workers": False, 87 | "models": [ 88 | model 89 | ], 90 | #"workers": [ 91 | #], 92 | "shared": False, 93 | #"slow_workers": False, 94 | "r2": False, 95 | "jobId": "", 96 | "index": 0, 97 | "gathered": False, 98 | "failed": False 99 | } 100 | 101 | try: 102 | async with aiohttp.ClientSession() as session: 103 | # Etapa 1: Recibir ID 104 | job_id = None 105 | try: 106 | while not job_id: 107 | async with session.post(url, headers=headers, json=payload, proxy=self.proxies) as response: 108 | data = await response.json() 109 | 110 | job_id = data.get('id', None) 111 | await asyncio.sleep(1) 112 | except Exception as e: logger.error(f'etapa1 > {e}') 113 | if not job_id: raise ValueError("No job ID") 114 | # Esperar hasta que el valor de "done" sea True 115 | done = False 116 | try: 117 | while not done: 118 | async with session.get(f'{check_url}/{job_id}', proxy=self.proxies) as response: 119 | data = await response.json() 120 | #estado = f'⏳ {data["wait_time"]}s\n ID: {job_id}' 121 | done = data['done'] 122 | await asyncio.sleep(2) # Esperar 1 segundo antes de volver a verificar 123 | except Exception as e: logger.error(f'etapa2 > {e}') 124 | # Obtener la URL de la imagen generada 125 | try: 126 | async with session.get(f'{status_url}/{job_id}', proxy=self.proxies) as response: 127 | data = await response.json() 128 | 129 | generations = data['generations'] 130 | except Exception as e: 131 | logger.error(f'etapa3> {e}') 132 | 133 | img_dict = {} 134 | 135 | for generation in generations: 136 | img = generation['img'] 137 | seed = generation['seed'] 138 | id = generation['id'] 139 | try: 140 | img_data = base64.b64decode(img) 141 | img_io = io.BytesIO(img_data) 142 | img_io.name = f"{seed} - {id}.png" 143 | img_dict[seed] = img_io 144 | except Exception as e: 145 | logger.error(f'Error fetching image: {e}') 146 | img_io_list = list(img_dict.values()) 147 | #asyncio.create_task(setup_vars()) 148 | return img_io_list, seed, model 149 | 150 | except Exception as e: logger.error(f'stablehorde.main > {e}') -------------------------------------------------------------------------------- /bot/src/apis/wttr.py: -------------------------------------------------------------------------------- 1 | from python_weather import METRIC, IMPERIAL, Client 2 | 3 | async def getweather(location: str, unit: str = "C"): 4 | if unit == "C": 5 | newwnit = METRIC 6 | else: 7 | newwnit = IMPERIAL 8 | info = "" 9 | 10 | # declare the client. the measuring unit used defaults to the metric system (celcius, km/h, etc.) 11 | try: 12 | async with Client(unit=newwnit) as client: 13 | # fetch a weather forecast from a city 14 | weather = await client.get(location=location) 15 | 16 | # returns the current day's forecast temperature (int) 17 | info += f"Current temperature: {weather.current.temperature}°{unit}" 18 | 19 | # get the weather forecast for a few days 20 | for forecast in weather.forecasts: 21 | info += f"\n{forecast.date:%A, %B %d, %Y}: {forecast.temperature}°{unit}" 22 | info += f"\nSunrise: {forecast.astronomy.sun_rise:%H:%M}" 23 | info += f"\nSunset: {forecast.astronomy.sun_set:%H:%M}" 24 | 25 | # hourly forecasts 26 | for hourly in forecast.hourly: 27 | info += f"\n{hourly.time:%I:%M %p}: {hourly.temperature}°{unit}, {hourly.description}" 28 | return info 29 | 30 | except Exception as e: raise ConnectionError(e) 31 | -------------------------------------------------------------------------------- /bot/src/handlers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/src/handlers/__init__.py -------------------------------------------------------------------------------- /bot/src/handlers/callbacks/imagine.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from bot.src.start import Update, CallbackContext 3 | from bot.src.handlers.menu import handle as hh, get as gg, refresh as rr 4 | from bot.src.utils.proxies import obtener_contextos as oc, config, db, imaginepy_ratios_cache, imaginepy_styles_cache, imaginepy_models_cache,ParseMode,errorpredlang,menusnotready 5 | from bot.src.utils.constants import constant_db_imaginepy_ratios, constant_db_imaginepy_styles, constant_db_imaginepy_models, logger 6 | 7 | async def handle(update: Update, context: CallbackContext): 8 | try: 9 | chat, _ = await oc(update) 10 | text, reply_markup = await gg(menu_type="imaginepy", update=update, context=context,chat=chat, page_index=0) 11 | await update.message.reply_text(text, reply_markup=reply_markup, parse_mode=ParseMode.HTML) 12 | except TypeError: logger.error(f'{__name__}: {errorpredlang}: {menusnotready}') 13 | async def callback(update: Update, context: CallbackContext): 14 | query, _, _, page_index, _ = await hh(update) 15 | await rr(query, update, context, page_index, menu_type="imaginepy") 16 | async def set(update: Update, context: CallbackContext): 17 | chat, _ = await oc(update) 18 | query, propsmenu, seleccion, page_index, _ = await hh(update) 19 | menu_type = await admin_selecciones(propsmenu, seleccion, chat) 20 | await rr(query, update, context, page_index, menu_type=menu_type, chat=chat) 21 | 22 | async def admin_selecciones(propsmenu, seleccion, chat): 23 | menu_type = "imaginepy" 24 | if menu_type == "imaginepy" and seleccion in config.props["imaginepy"]["available_options"]: menu_type=seleccion 25 | if propsmenu == "set_imaginepy_ratios": 26 | menu_type = "imaginepy_ratios" 27 | if seleccion != "paginillas": 28 | imaginepy_ratios_cache[chat.id] = (seleccion, datetime.now()) 29 | await db.set_chat_attribute(chat, f'{constant_db_imaginepy_ratios}', seleccion) 30 | elif propsmenu == "set_imaginepy_styles": 31 | menu_type = "imaginepy_styles" 32 | if seleccion != "paginillas": 33 | imaginepy_styles_cache[chat.id] = (seleccion, datetime.now()) 34 | await db.set_chat_attribute(chat, f'{constant_db_imaginepy_styles}', seleccion) 35 | elif propsmenu == "set_imaginepy_models": 36 | menu_type = "imaginepy_models" 37 | if seleccion != "paginillas": 38 | imaginepy_models_cache[chat.id] = (seleccion, datetime.now()) 39 | await db.set_chat_attribute(chat, f'{constant_db_imaginepy_models}', seleccion) 40 | return menu_type -------------------------------------------------------------------------------- /bot/src/handlers/callbacks/stablehorde.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from bot.src.start import Update, CallbackContext 3 | from bot.src.handlers.menu import handle as hh, get as gg, refresh as rr 4 | from bot.src.utils.proxies import obtener_contextos as oc, config, db, stablehorde_models_cache,ParseMode,errorpredlang,menusnotready 5 | from bot.src.utils.constants import constant_db_stablehorde_models, constant_db_image_api_styles, constant_db_imaginepy_models, logger, stablehorde_models 6 | 7 | async def handle(update: Update, context: CallbackContext): 8 | try: 9 | chat, _ = await oc(update) 10 | text, reply_markup = await gg(menu_type="stablehorde", update=update, context=context,chat=chat, page_index=0) 11 | await update.message.reply_text(text, reply_markup=reply_markup, parse_mode=ParseMode.HTML) 12 | except TypeError: logger.error(f'{__name__}: {errorpredlang}: {menusnotready}') 13 | async def callback(update: Update, context: CallbackContext): 14 | query, _, _, page_index, _ = await hh(update) 15 | await rr(query, update, context, page_index, menu_type="stablehorde") 16 | async def set(update: Update, context: CallbackContext): 17 | chat, _ = await oc(update) 18 | query, propsmenu, seleccion, page_index, _ = await hh(update) 19 | menu_type = await admin_selecciones(propsmenu, seleccion, chat) 20 | await rr(query, update, context, page_index, menu_type=menu_type, chat=chat) 21 | 22 | async def admin_selecciones(propsmenu, seleccion, chat): 23 | menu_type = "stablehorde" 24 | if menu_type == "stablehorde" and seleccion in config.props["stablehorde"]["available_options"]: menu_type=seleccion 25 | if propsmenu == "set_stablehorde_models": 26 | menu_type = "stablehorde_models" 27 | if seleccion != "paginillas": 28 | stablehorde_models_cache[chat.id] = (seleccion, datetime.now()) 29 | await db.set_chat_attribute(chat, f'{constant_db_stablehorde_models}', seleccion) 30 | elif propsmenu == "set_image_api_styles": 31 | menu_type = "image_api_styles" 32 | if seleccion != "paginillas": 33 | constant_db_image_api_styles[chat.id] = (seleccion, datetime.now()) 34 | await db.set_chat_attribute(chat, f'{constant_db_image_api_styles}', seleccion) 35 | return menu_type 36 | -------------------------------------------------------------------------------- /bot/src/handlers/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/src/handlers/commands/__init__.py -------------------------------------------------------------------------------- /bot/src/handlers/commands/api.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from bot.src.start import Update, CallbackContext 3 | from bot.src.utils.constants import constant_db_api, logger 4 | from bot.src.handlers.menu import handle as hh, get as gg, refresh as rr 5 | async def handle(update: Update, context: CallbackContext): 6 | from bot.src.utils.proxies import (obtener_contextos as oc,ParseMode,errorpredlang,menusnotready) 7 | try: 8 | chat, _ = await oc(update) 9 | text, reply_markup = await gg(menu_type="api", update=update, context=context, chat=chat, page_index=0) 10 | await update.message.reply_text(text, reply_markup=reply_markup, parse_mode=ParseMode.HTML) 11 | except Exception as e: logger.error(f'{__name__}: {errorpredlang}: {menusnotready} {e}') 12 | 13 | async def callback(update: Update, context: CallbackContext): 14 | query, _, _, page_index, _ = await hh(update) 15 | await rr(query, update, context, page_index, menu_type="api") 16 | 17 | async def set(update: Update, context: CallbackContext): 18 | from bot.src.utils.proxies import obtener_contextos as oc,api_cache,db 19 | from bot.src.tasks.apis_chat import vivas as apis_vivas 20 | chat, _ = await oc(update) 21 | query, _, seleccion, page_index, _ = await hh(update) 22 | menu_type="api" 23 | if seleccion in apis_vivas and (api_cache.get(chat.id) is None or api_cache.get(chat.id)[0] != seleccion): 24 | api_cache[chat.id] = (seleccion, datetime.now()) 25 | await db.set_chat_attribute(chat, f'{constant_db_api}', seleccion) 26 | await rr(query, update, context, page_index, menu_type=menu_type, chat=chat) -------------------------------------------------------------------------------- /bot/src/handlers/commands/cancel.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from bot.src.start import Update, CallbackContext 3 | from bot.src.handlers import semaphore as tasks 4 | async def handle(update: Update, context: CallbackContext): 5 | from bot.src.utils.proxies import ( 6 | obtener_contextos as oc, 7 | config, ParseMode, 8 | interaction_cache, db, chat_locks, chat_tasks 9 | ) 10 | chat, lang = await oc(update) 11 | lock = chat_locks.get(chat.id) 12 | if not lock and not lock.locked() or chat.id not in chat_tasks: 13 | text = config.lang[lang]["mensajes"]["nadacancelado"] 14 | await update.effective_chat.send_message(text, reply_to_message_id=update.effective_message.message_id, parse_mode=ParseMode.HTML) 15 | else: 16 | await update.effective_chat.send_message(f'{config.lang[lang]["mensajes"]["cancelado"]}', reply_to_message_id=update.effective_message.message_id, parse_mode=ParseMode.HTML) 17 | task = chat_tasks.get(chat.id) 18 | if task is not None: 19 | task.cancel() 20 | await tasks.releasemaphore(chat) 21 | interaction_cache[chat.id] = ("visto", datetime.now()) 22 | await db.set_chat_attribute(chat, "last_interaction", datetime.now()) -------------------------------------------------------------------------------- /bot/src/handlers/commands/chat_mode.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from bot.src.start import Update, CallbackContext 3 | from bot.src.handlers.menu import handle as hh, get as gg, refresh as rr 4 | from bot.src.utils.constants import constant_db_chat_mode, logger 5 | async def handle(update: Update, context: CallbackContext): 6 | from bot.src.utils.proxies import (obtener_contextos as oc,ParseMode,errorpredlang,menusnotready) 7 | try: 8 | chat, _ = await oc(update) 9 | text, reply_markup = await gg(menu_type="chat_mode", update=update, context=context, chat=chat, page_index=0) 10 | await update.message.reply_text(text, reply_markup=reply_markup, parse_mode=ParseMode.HTML) 11 | except Exception as e: logger.error(f'{__name__}: {errorpredlang}: {menusnotready} {e}') 12 | async def callback(update: Update, context: CallbackContext): 13 | query, _, _, page_index, _ = await hh(update) 14 | await rr(query, update, context, page_index, menu_type="chat_mode") 15 | async def set(update: Update, context: CallbackContext): 16 | from bot.src.utils.proxies import (obtener_contextos as oc,chat_mode_cache,db,config,ParseMode) 17 | chat, lang = await oc(update) 18 | query, _, seleccion, page_index, _ = await hh(update) 19 | menu_type="chat_mode" 20 | if seleccion in config.chat_mode["available_chat_mode"] and (chat_mode_cache.get(chat.id) is None or chat_mode_cache.get(chat.id)[0] != seleccion): 21 | chat_mode_cache[chat.id] = (seleccion, datetime.now()) 22 | await db.set_chat_attribute(chat, f'{constant_db_chat_mode}', seleccion) 23 | await update.effective_chat.send_message(f"{config.chat_mode['info'][seleccion]['welcome_message'][lang]}", parse_mode=ParseMode.HTML) 24 | await rr(query, update, context, page_index, menu_type=menu_type, chat=chat) -------------------------------------------------------------------------------- /bot/src/handlers/commands/help.py: -------------------------------------------------------------------------------- 1 | from bot.src.start import Update, CallbackContext 2 | 3 | HELPMESSAGE = """You are a chatbot, your name is {botname}. 4 | First, you will introduce the chatbot, you will welcome the user and talk about: 5 | Commands: 6 | /new: Start a new dialogue. it will delete the previous bot "memory" 7 | /img: Generate images based on user input. user usage is "/img anything you can imagine" or select the image api to use with only /img. actual is {selected_image_api} 8 | /retry: Regenerate the bot's last response. 9 | /chat_mode: Select conversation mode. the actual chat mode selected is {selected_chat_mode} 10 | /api: Show APIs. selected api is {selected_api} 11 | /model: Show APIs model configuration. the selected model for the api is {selected_model} 12 | /status: Show the bot configuration like chat_mode, api and model selected. 13 | /search: Browse the internet and get a bot explanation of the results. 14 | /reset: Restart the configuration like chat_mode, api and model to defaults. 15 | /lang: View available languages. 16 | 17 | Some features: 18 | 🎨 User can make the bot generate prompts for image generation with /chat_mode and looking for generate images 🖼️ chat mode 19 | 👥 Show to the user how to add the bot to a group with /helpgroupchat 20 | 🎤 User can send voice messages instead of text. 21 | 📖 User can send documents or links to analyze them with the bot! 22 | 🖼️ User can send photos to extract the text from them. 23 | 🔎 User can browse the Internet by using the /search command. 24 | 25 | all the previous information you will need to explain to the user in a specific language, completely translated. 26 | you will be pleasant and attentive, you will not miss any detail, remember to use line breaks. if the user asks about something about the bot, you will answer with pleasure 27 | the language to explain as a native is: {language}.""" 28 | 29 | async def handle(update: Update, context: CallbackContext): 30 | from bot.src.utils.proxies import config, obtener_contextos as oc, parametros 31 | chat, lang = await oc(update) 32 | mododechat_actual, api_actual, modelo_actual, image_api_actual, _, _, _ = await parametros(chat, lang, update) 33 | from bot.src.handlers import message 34 | mensaje_ayuda=HELPMESSAGE.format(botname=f'{context.bot.username}', selected_chat_mode=f'{config.chat_mode["info"][mododechat_actual]["name"][lang]}', 35 | selected_api=f'{config.api["info"][api_actual]["name"]}', selected_image_api=f'{config.api["info"][image_api_actual]["name"]}', 36 | selected_model=f'{config.model["info"][modelo_actual]["name"]}', 37 | language=f'{config.lang[lang]["info"]["name"]}') 38 | await message.handle(chat, lang, update, context, _message=mensaje_ayuda) 39 | 40 | async def group(update: Update, context: CallbackContext): 41 | from bot.src.utils.proxies import config, ParseMode, obtener_contextos as oc 42 | _, lang = await oc(update) 43 | text = config.lang[lang]["mensajes"]["ayuda_grupos"].format(bot_username="@" + context.bot.username) 44 | await update.message.reply_text(text, parse_mode=ParseMode.HTML) 45 | await update.message.reply_video(config.help_group_chat_video_path) -------------------------------------------------------------------------------- /bot/src/handlers/commands/imodel.py: -------------------------------------------------------------------------------- 1 | from bot.src.handlers.menu import get 2 | from bot.src.utils.proxies import ParseMode, Update, CallbackContext, obtener_contextos as oc, parametros 3 | async def stablehorde(update: Update, context: CallbackContext): 4 | chat, lang = await oc(update) 5 | _, _, _, checked_image_api, _, _, _ = await parametros(chat, lang, update) 6 | if checked_image_api == "stablehorde": 7 | text, reply_markup = await get(menu_type="stablehorde_models", update=update, context=context,chat=chat, page_index=0) 8 | await update.effective_message.reply_text(text, reply_markup=reply_markup, parse_mode=ParseMode.HTML) -------------------------------------------------------------------------------- /bot/src/handlers/commands/iratio.py: -------------------------------------------------------------------------------- 1 | from bot.src.handlers.menu import get 2 | from bot.src.utils.proxies import ParseMode, Update, CallbackContext, obtener_contextos as oc, parametros 3 | async def imagine(update: Update, context: CallbackContext): 4 | chat, lang = await oc(update) 5 | _, _, _, checked_image_api, _, _, _ = await parametros(chat, lang, update) 6 | if checked_image_api == "imaginepy": 7 | text, reply_markup = await get(menu_type="imaginepy_ratios", update=update, context=context,chat=chat, page_index=0) 8 | await update.effective_message.reply_text(text, reply_markup=reply_markup, parse_mode=ParseMode.HTML) -------------------------------------------------------------------------------- /bot/src/handlers/commands/istyle.py: -------------------------------------------------------------------------------- 1 | from bot.src.handlers.menu import get 2 | from bot.src.utils.proxies import ParseMode, Update, CallbackContext, obtener_contextos as oc, parametros 3 | async def imagine(update: Update, context: CallbackContext): 4 | chat, lang = await oc(update) 5 | _, _, _, checked_image_api, _, _, _= await parametros(chat, lang, update) 6 | if checked_image_api == "imaginepy": 7 | text, reply_markup = await get(menu_type="imaginepy_styles", update=update, context=context,chat=chat, page_index=0) 8 | await update.effective_message.reply_text(text, reply_markup=reply_markup, parse_mode=ParseMode.HTML) 9 | 10 | async def image_style(update: Update, context: CallbackContext): 11 | chat, _ = await oc(update) 12 | text, reply_markup = await get(menu_type="image_api_styles", update=update, context=context,chat=chat, page_index=0) 13 | await update.effective_message.reply_text(text, reply_markup=reply_markup, parse_mode=ParseMode.HTML) 14 | -------------------------------------------------------------------------------- /bot/src/handlers/commands/lang.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from bot.src.start import Update, CallbackContext 3 | from bot.src.utils.constants import logger 4 | from bot.src.handlers.menu import handle as hh, get as gg, refresh as rr 5 | async def handle(update: Update, context: CallbackContext): 6 | from bot.src.utils.proxies import (obtener_contextos as oc,ParseMode,errorpredlang,menusnotready) 7 | try: 8 | chat, _ = await oc(update) 9 | text, reply_markup = await gg(menu_type="lang", update=update, context=context, chat=chat, page_index=0) 10 | await update.message.reply_text(text, reply_markup=reply_markup, parse_mode=ParseMode.HTML) 11 | except Exception as e: logger.error(f'{__name__}: {errorpredlang}: {menusnotready} {e}') 12 | async def callback(update: Update, context: CallbackContext): 13 | query, _, _, page_index, _ = await hh(update) 14 | await rr(query, update, context, page_index, menu_type="lang") 15 | async def set(update: Update, context: CallbackContext): 16 | from bot.src.utils.proxies import obtener_contextos as oc,lang_cache, config 17 | chat, _ = await oc(update) 18 | query, _, seleccion, page_index, _ = await hh(update) 19 | menu_type="lang" 20 | if seleccion in config.available_lang and (lang_cache.get(chat.id) is None or lang_cache.get(chat.id)[0] != seleccion): 21 | await cambiar_idioma(None, chat, seleccion) 22 | await rr(query, update, context, page_index, menu_type=menu_type, chat=chat) 23 | 24 | async def cambiar_idioma(update, chat, lang): 25 | from bot.src.utils.proxies import (lang_cache,db,config) 26 | from bot.src.utils.constants import constant_db_lang 27 | if lang_cache.get(chat.id) is None or lang_cache.get(chat.id)[0] != lang: 28 | await db.set_chat_attribute(chat, f'{constant_db_lang}', lang) 29 | lang_cache[chat.id] = (lang, datetime.now()) 30 | if update: 31 | await update.effective_chat.send_message(f'{config.lang[lang]["info"]["bienvenida"]}') -------------------------------------------------------------------------------- /bot/src/handlers/commands/model.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from bot.src.start import Update, CallbackContext 3 | from bot.src.handlers.menu import handle as hh, get as gg, refresh as rr 4 | from bot.src.utils.constants import constant_db_model, logger 5 | 6 | async def handle(update: Update, context: CallbackContext): 7 | from bot.src.utils.proxies import (obtener_contextos as oc,ParseMode,errorpredlang,menusnotready) 8 | try: 9 | chat, _ = await oc(update) 10 | text, reply_markup = await gg(menu_type="model", update=update, context=context,chat=chat, page_index=0) 11 | await update.message.reply_text(text, reply_markup=reply_markup, parse_mode=ParseMode.HTML) 12 | except Exception as e: logger.error(f'{__name__}: {errorpredlang}: {menusnotready} {e}') 13 | async def callback(update: Update, context: CallbackContext): 14 | query, _, _, page_index, _ = await hh(update) 15 | await rr(query, update, context, page_index, menu_type="model") 16 | async def set(update: Update, context: CallbackContext): 17 | from bot.src.utils.proxies import obtener_contextos as oc,model_cache,db, config 18 | chat, _ = await oc(update) 19 | query, _, seleccion, page_index, _ = await hh(update) 20 | menu_type="model" 21 | if seleccion in config.model["available_model"] and (model_cache.get(chat.id) is None or model_cache.get(chat.id)[0] != seleccion): 22 | model_cache[chat.id] = (seleccion, datetime.now()) 23 | await db.set_chat_attribute(chat, f'{constant_db_model}', seleccion) 24 | await rr(query, update, context, page_index, menu_type=menu_type, chat=chat) -------------------------------------------------------------------------------- /bot/src/handlers/commands/new.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from bot.src.start import Update, CallbackContext 3 | from bot.src.handlers import semaphore as tasks 4 | from bot.src.utils.constants import logger 5 | async def handle(update: Update, context: CallbackContext, msgid=None): 6 | from bot.src.utils.proxies import ( 7 | obtener_contextos as oc, debe_continuar, parametros, 8 | config, ParseMode, 9 | interaction_cache, db, errorpredlang 10 | ) 11 | try: 12 | chat, lang = await oc(update) 13 | if not await debe_continuar(chat, lang, update, context): return 14 | mododechat_actual, _, _, _, _, _, _ = await parametros(chat, lang, update) 15 | await db.new_dialog(chat) 16 | await db.delete_all_dialogs_except_current(chat) 17 | #Bienvenido! 18 | await update.effective_chat.send_message(f"{config.chat_mode['info'][mododechat_actual]['welcome_message'][lang]}", parse_mode=ParseMode.HTML) if not msgid else None 19 | interaction_cache[chat.id] = ("visto", datetime.now()) 20 | await db.set_chat_attribute(chat, "last_interaction", datetime.now()) 21 | except Exception as e: logger.error(f'{__name__}: {errorpredlang}: {e}') 22 | finally: await tasks.releasemaphore(chat=chat) -------------------------------------------------------------------------------- /bot/src/handlers/commands/props.py: -------------------------------------------------------------------------------- 1 | from bot.src.start import Update, CallbackContext 2 | from bot.src.handlers.menu import handle as hh, get as gg, refresh as rr 3 | from bot.src.utils.checks.c_callback import check as is_this_shit_callback 4 | from bot.src.utils.proxies import obtener_contextos as oc, config, errorpredlang, menusnotready, ParseMode 5 | from bot.src.utils.constants import logger 6 | async def handle(update: Update, context: CallbackContext): 7 | try: 8 | chat, _ = await oc(update) 9 | text, reply_markup = await gg(menu_type="props", update=update, context=context, chat=chat, page_index=0) 10 | await context.bot.send_message(chat_id=chat.id,text=text,reply_markup=reply_markup,parse_mode=ParseMode.HTML) 11 | 12 | except Exception as e: logger.error(f'{__name__}: {errorpredlang}: {menusnotready} {e}') 13 | async def callback(update: Update, context: CallbackContext): 14 | query, _, _, page_index, _ = await hh(update) 15 | await rr(query, update, context, page_index, menu_type="props") 16 | async def set(update: Update, context: CallbackContext): 17 | chat, _ = await oc(update) 18 | query, _, seleccion, _, is_from_callback = await hh(update) 19 | menu_type = await admin_selecciones(update, context, seleccion, is_from_callback) 20 | await rr(query=query, update=update, context=context, page_index=0, menu_type=menu_type, chat=chat) 21 | 22 | async def admin_selecciones(update, context, seleccion, is_from_callback): 23 | menu_type = seleccion # Inicializamos menu_type con el valor de seleccion 24 | from_callback = await is_this_shit_callback(is_from_callback) 25 | if seleccion == "paginillas": 26 | if from_callback: 27 | if from_callback in ["stablehorde_models"]: menu_type = "stablehorde" 28 | elif from_callback in ["image_api_styles", "stablehorde"]: menu_type = "image_api" 29 | elif from_callback in config.props["available_props"]: menu_type = "props" 30 | else: menu_type = "props" # Actualizamos menu_ 31 | elif seleccion == "reset": 32 | from .reset import handle 33 | await handle(update, context, yey=True) 34 | menu_type = "props" # Actualizamos menu_ 35 | return menu_type -------------------------------------------------------------------------------- /bot/src/handlers/commands/reset.py: -------------------------------------------------------------------------------- 1 | from bot.src.start import Update, CallbackContext 2 | async def handle(update: Update, context: CallbackContext, yey=None): 3 | from bot.src.utils.proxies import obtener_contextos as oc, db, ParseMode 4 | chat, _ = await oc(update) 5 | await db.reset_chat_attribute(chat) 6 | if not yey: 7 | await update.effective_chat.send_message("Yey", parse_mode=ParseMode.HTML) -------------------------------------------------------------------------------- /bot/src/handlers/commands/retry.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from bot.src.start import Update, CallbackContext 3 | from bot.src.handlers import semaphore as tasks 4 | async def handle(update: Update, context: CallbackContext): 5 | from bot.src.utils.proxies import (config, obtener_contextos as oc, debe_continuar, db, interaction_cache) 6 | chat, lang = await oc(update) 7 | if not await debe_continuar(chat, lang, update, context): return 8 | dialog_messages = await db.get_dialog_messages(chat, dialog_id=None) 9 | if len(dialog_messages) == 0: 10 | await send_no_retry(update, chat, config, lang) 11 | return 12 | last_dialog_message = dialog_messages.pop() 13 | await db.set_dialog_messages(chat, dialog_messages, dialog_id=None) # last message was removed from the context 14 | interaction_cache[chat.id] = ("visto", datetime.now()) 15 | await db.set_chat_attribute(chat, "last_interaction", datetime.now()) 16 | await tasks.releasemaphore(chat=chat) 17 | _message = last_dialog_message.get("user", None) 18 | if not _message: 19 | await send_no_retry(update, chat, config, lang) 20 | return 21 | from bot.src.handlers.message import handle as messend 22 | await messend(chat, lang, update, context, _message) 23 | 24 | async def send_no_retry(update, chat, config, lang): 25 | await tasks.releasemaphore(chat=chat) 26 | text = config.lang[lang]["mensajes"]["no_retry_mensaje"] 27 | await update.effective_chat.send_message(text) -------------------------------------------------------------------------------- /bot/src/handlers/commands/search.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from bot.src.start import Update, CallbackContext 3 | from bot.src.utils.gen_utils.phase import ChatGPT 4 | from bot.src.handlers.error import mini_handle as handle_errors 5 | async def handle(chat, lang, update, context, _message=None): 6 | try: 7 | from bot.src.handlers import semaphore as tasks 8 | from bot.src.utils.proxies import (db,interaction_cache,config,telegram,ParseMode,ChatAction) 9 | chattype = update.callback_query.message if update.callback_query else update.message 10 | if _message: query = _message 11 | else: 12 | if not context.args: 13 | await update.effective_chat.send_message(f'{config.lang[lang]["mensajes"]["genimagen_noargs"]}', parse_mode=ParseMode.HTML) 14 | await tasks.releasemaphore(chat=chat) 15 | return 16 | else: query = ' '.join(context.args) 17 | if query == None: 18 | await update.effective_chat.send_message(f'{config.lang[lang]["mensajes"]["genimagen_notext"]}', parse_mode=ParseMode.HTML) 19 | await tasks.releasemaphore(chat=chat) 20 | return 21 | try: 22 | await tasks.releasemaphore(chat=chat) 23 | await update.effective_chat.send_action(ChatAction.TYPING) 24 | insta = await ChatGPT.create(chat, lang) 25 | formatted_results_backend, formatted_results_string = await insta.busqueduck(query.replace("-", " ")) 26 | await chattype.chat.send_action(ChatAction.TYPING) 27 | from bot.src.utils.misc import clean_text, update_dialog_messages, send_large_message 28 | formatted_results_backend, _, advertencia = await clean_text(doc=formatted_results_backend, chat=chat) 29 | resultadosbot="""{resultados}\n\n parameters[Now you have access to the Internet thanks to the previous searches,you will talk deeply about the search results in general,do not repeat the same search results text and structure,do not write urls,you need to write in the language: {language}]""" 30 | new_dialog_message = {"search": resultadosbot.format(resultados=f'{formatted_results_backend}', language=f'{config.lang[lang]["info"]["name"]}'), "date": datetime.now()} 31 | await update_dialog_messages(chat, new_dialog_message) 32 | if advertencia==True: 33 | formatted_results_string = f'{config.lang[lang]["metagen"]["advertencia"]}: {config.lang[lang]["errores"]["advertencia_tokens_excedidos"]}\n\n{formatted_results_string}' 34 | await send_large_message(formatted_results_string, update) 35 | interaction_cache[chat.id] = ("visto", datetime.now()) 36 | await db.set_chat_attribute(chat, "last_interaction", datetime.now()) 37 | except telegram.error.BadRequest: 38 | text = f'{config.lang[lang]["errores"]["genimagen_badrequest"]}' 39 | await update.effective_chat.send_message(text, parse_mode=ParseMode.HTML) 40 | finally: 41 | await tasks.releasemaphore(chat=chat) 42 | except Exception as e: 43 | raise RuntimeError(f'search_handle > {e}') 44 | async def wrapper(update: Update, context: CallbackContext, _message=None): 45 | try: 46 | from bot.src.handlers import semaphore as tasks 47 | from bot.src.utils.proxies import (debe_continuar,obtener_contextos as oc, parametros, bb) 48 | chat, lang = await oc(update) 49 | await parametros(chat, lang, update) 50 | if not await debe_continuar(chat, lang, update, context, bypassmention=True): return 51 | task = bb(handle(chat, lang, update, context, _message)) 52 | await tasks.handle(chat, task) 53 | except Exception as e: 54 | await handle_errors(f'search_wrapper > {e}', lang, chat) 55 | finally: 56 | await tasks.releasemaphore(chat=chat) -------------------------------------------------------------------------------- /bot/src/handlers/commands/start.py: -------------------------------------------------------------------------------- 1 | from bot.src.start import Update, CallbackContext 2 | welcomessage = """You are a chatbot, your name is {botname}. 3 | First, you will introduce the chatbot, you will welcome the user and last you will tell the user to use the /help command if help is needed 4 | you will need to explain to the user in a specific language, completely translated. 5 | the language to explain as a native is: {language}.""" 6 | 7 | async def handle(update: Update, context: CallbackContext): 8 | from bot.src.utils.proxies import config, obtener_contextos as oc, parametros 9 | chat, lang = await oc(update) 10 | await parametros(chat, lang, update) 11 | from bot.src.handlers.message import handle as messend 12 | await messend(chat, lang, update, context, _message=welcomessage.format(botname=f'{context.bot.username}', language=f'{config.lang[lang]["info"]["name"]}')) -------------------------------------------------------------------------------- /bot/src/handlers/commands/status.py: -------------------------------------------------------------------------------- 1 | from bot.src.start import Update, CallbackContext 2 | from bot.src.utils.constants import constant_db_tokens, Style, stablehorde_models 3 | async def handle(update: Update, context: CallbackContext, paraprops=None): 4 | try: 5 | from bot.src.utils.proxies import obtener_contextos as oc, parametros, db, config 6 | chat, lang = await oc(update) 7 | mododechat_actual, api_actual, modelo_actual, checked_image_api, checked_imaginepy_styles, _, checked_imaginepy_models = await parametros(chat, lang, update) 8 | tokens_actual = await db.get_dialog_attribute(chat, f'{constant_db_tokens}') 9 | 10 | api=config.lang[lang]["metagen"]["api"] 11 | nombreapi=config.api["info"][api_actual]["name"] 12 | apimagen=config.lang[lang]["metagen"]["image_api"] 13 | apimagenestilo=config.lang[lang]["metagen"]["imaginepy_styles"] 14 | nombreapimagen=config.api["info"][checked_image_api]["name"] 15 | imaginestyle=config.lang[lang]["metagen"]["imaginepy_actual_style"] 16 | imaginemodel=config.lang[lang]["metagen"]["imaginepy_actual_model"] 17 | modelo=config.lang[lang]["metagen"]["modelo"] 18 | nombremodelo=config.model["info"][modelo_actual]["name"] 19 | tokensmax=config.lang[lang]["metagen"]["tokensmax"] 20 | modeltokens=config.model["info"][modelo_actual]["max_tokens"] 21 | if config.api["info"][api_actual].get("api_max_tokens"): 22 | modeltokens = config.api["info"][api_actual]["api_max_tokens"] 23 | chatmode=config.lang[lang]["metagen"]["chatmode"] 24 | nombrechatmode=config.chat_mode["info"][mododechat_actual]["name"][lang] 25 | tokens=config.lang[lang]["metagen"]["tokens"] 26 | textoprimer="""🔌 {api}: {nombreapi}\n🧠 {modelo}: {nombremodelo}\n💬 {chatmode}: {nombrechatmode}\n💰 {tokens}: {tokens_actual} / {modeltokens}\n\n🌅 {apimagen}: {apimageactual}\n🎨 {apimagenestilo}: {imagineactual}""" 27 | 28 | text = f'{textoprimer.format(imaginemodel=imaginemodel, checked_imaginepy_models=checked_imaginepy_models, api=api, nombreapi=nombreapi,modelo=modelo,nombremodelo=nombremodelo, tokensmax=tokensmax,modeltokens=modeltokens,chatmode=chatmode, nombrechatmode=nombrechatmode,tokens=tokens, tokens_actual=tokens_actual,apimagen=apimagen, apimageactual=nombreapimagen,apimagenestilo=apimagenestilo,imaginestyle=imaginestyle, imagineactual=Style[checked_imaginepy_styles].value[1])}' 29 | if checked_image_api =="stablehorde": text += f'\n🪡 {modelo}: {stablehorde_models.get(int(checked_imaginepy_models), "Error")}' 30 | 31 | if paraprops: return text 32 | await update.effective_chat.send_message(text) 33 | except Exception as e: 34 | raise ValueError(f' {e}>') 35 | -------------------------------------------------------------------------------- /bot/src/handlers/document.py: -------------------------------------------------------------------------------- 1 | from bot.src.start import Update, CallbackContext 2 | from datetime import datetime 3 | from . import semaphore as tasks 4 | from tempfile import TemporaryDirectory 5 | from pathlib import Path 6 | from bot.src.utils.misc import clean_text, update_dialog_messages 7 | from bot.src.utils.proxies import (ChatAction, ParseMode, config, interaction_cache, db) 8 | 9 | async def handle(chat, lang, update, context): 10 | try: 11 | document = update.message.document 12 | file_size_mb = document.file_size / (1024 * 1024) 13 | if file_size_mb <= config.file_max_size: 14 | await update.effective_chat.send_action(ChatAction.TYPING) 15 | with TemporaryDirectory() as tmp_dir: 16 | tmp_dir = Path(tmp_dir) 17 | ext = document.file_name.split(".")[-1] 18 | doc_path = tmp_dir / Path(document.file_name) 19 | # download 20 | doc_file = await context.bot.get_file(document.file_id) 21 | await doc_file.download_to_drive(doc_path) 22 | doc = await process_document(update, doc_path, ext, chat, lang) 23 | text = f'{config.lang[lang]["mensajes"]["document_anotado_ask"]}' 24 | if doc[2]==True: 25 | text = f'{config.lang[lang]["metagen"]["advertencia"]}: {config.lang[lang]["errores"]["advertencia_tokens_excedidos"]}\n\n{text}' 26 | 27 | new_dialog_message = {"documento": f"{document.file_name} -> content: {doc[0]}", "date": datetime.now()} 28 | await update_dialog_messages(chat, new_dialog_message) 29 | 30 | interaction_cache[chat.id] = ("visto", datetime.now()) 31 | await db.set_chat_attribute(chat, "last_interaction", datetime.now()) 32 | else: 33 | text = config.lang[lang]["errores"]["document_size_limit"].replace("{file_size_mb}", f"{file_size_mb:.2f}").replace("{file_max_size}", str(config.file_max_size)) 34 | except Exception as e: 35 | text = f'{config.lang[lang]["errores"]["error"]}: {e}' 36 | finally: 37 | await tasks.releasemaphore(chat=chat) 38 | await update.message.reply_text(text, parse_mode=ParseMode.HTML) 39 | 40 | async def process_document(update, doc_path, ext, chat, lang): 41 | if "pdf" in ext: 42 | doc = await process_pdf(update, doc_path, lang) 43 | else: 44 | with open(doc_path, 'r') as f: 45 | doc = f.read() 46 | return await clean_text(doc, chat) 47 | 48 | async def process_pdf(update, doc_path, lang): 49 | pdf_file = open(doc_path, 'rb') 50 | from PyPDF2 import PdfReader 51 | read_pdf = PdfReader(pdf_file) 52 | doc = '' 53 | lim = int(config.pdf_page_lim) 54 | paginas = int(len(read_pdf.pages)) 55 | if int(paginas) > int(lim): 56 | await update.message.reply_text(f'{config.lang[lang]["errores"]["pdf_pages_limit"].format(paginas=(paginas - lim), pdf_page_lim=int(lim))}', parse_mode=ParseMode.HTML) 57 | paginas = int(lim) 58 | for i in range(paginas): 59 | text = read_pdf.pages[i].extract_text() 60 | text = text.replace(".\n", "|n_parraf|") 61 | paras = text.split("|n_parraf|") 62 | parafo_count = 1 63 | for para in paras: 64 | if len(para) > 3: 65 | doc += f'{config.lang[lang]["metagen"]["paginas"]}{i+1}_{config.lang[lang]["metagen"]["parrafos"]}{parafo_count}: {para}\n\n' 66 | parafo_count += 1 67 | return doc 68 | 69 | async def wrapper(update: Update, context: CallbackContext): 70 | from bot.src.utils.proxies import (debe_continuar,obtener_contextos as oc, parametros, bb) 71 | chat, lang = await oc(update) 72 | await parametros(chat, lang, update) 73 | if not await debe_continuar(chat, lang, update, context): return 74 | task = bb(handle(chat, lang, update, context)) 75 | await tasks.handle(chat, task) -------------------------------------------------------------------------------- /bot/src/handlers/error.py: -------------------------------------------------------------------------------- 1 | import telegram 2 | from telegram import Update 3 | from telegram.ext import CallbackContext 4 | from json import dumps 5 | from html import escape 6 | from traceback import format_exception 7 | from bot.src.utils.proxies import config, ParseMode, errorpredlang 8 | from bot.src.utils.constants import logger 9 | async def handle(update: Update, context: CallbackContext) -> None: 10 | try: 11 | # Log the error with traceback 12 | logger.error(f'{__name__}: {config.lang[config.pred_lang]["errores"]["handler_excepcion"]}:', exc_info=context.error) 13 | 14 | # Collect error message and traceback 15 | tb_list = format_exception(None, context.error, context.error.__traceback__) 16 | tb_string = "".join(tb_list) 17 | update_str = dumps(update.to_dict(), indent=2, ensure_ascii=False) 18 | message = ( 19 | f'{config.lang[config.pred_lang]["errores"]["handler_excepcion"]}:\n' 20 | f'
update = {escape(update_str)}
\n\n' 21 | f'
{escape(tb_string)}
' 22 | ) 23 | 24 | # Send error message 25 | await update.effective_chat.send_message(message, parse_mode='HTML') 26 | except Exception as e: 27 | # Handle errors that may occur during error handling 28 | e = f'{config.lang[config.pred_lang]["errores"]["handler_error_handler"]}: {e}' 29 | finally: 30 | await send_error_msg(e) 31 | 32 | 33 | async def mini_handle(e, lang, chat, update=None): 34 | from bot.src.handlers import semaphore 35 | if "Request has inappropriate content!" in str(e) or "Your request was rejected as a result of our safety system." in str(e): 36 | text = f'{config.lang[lang]["errores"]["genimagen_rejected"]}' 37 | else: 38 | text = f'{config.lang[lang]["errores"]["genimagen_other"]}' 39 | if update: 40 | await update.effective_chat.send_message(text, parse_mode=ParseMode.HTML, reply_to_message_id=update.effective_message.message_id) 41 | await semaphore.releasemaphore(chat=chat) 42 | await send_error_msg(e) 43 | 44 | async def send_error_msg(e): 45 | logger.error(f'{__name__}: {errorpredlang}: {e}') -------------------------------------------------------------------------------- /bot/src/handlers/ocr_image.py: -------------------------------------------------------------------------------- 1 | from bot.src.start import Update, CallbackContext 2 | from datetime import datetime 3 | from pathlib import Path 4 | from tempfile import TemporaryDirectory 5 | from . import semaphore as tasks 6 | from ..utils.misc import clean_text, update_dialog_messages 7 | async def handle(chat, lang, update, context): 8 | from bot.src.utils.proxies import ( 9 | ChatAction, ParseMode, config, 10 | interaction_cache, db 11 | ) 12 | image = update.message.photo[-1] 13 | from PIL import Image 14 | from pytesseract import image_to_string 15 | try: 16 | with TemporaryDirectory() as tmp_dir: 17 | await update.effective_chat.send_action(ChatAction.TYPING) 18 | tmp_dir = Path(tmp_dir) 19 | img_path = tmp_dir / Path("ocrimagen.jpg") 20 | image_file = await context.bot.get_file(image.file_id) 21 | await image_file.download_to_drive(img_path) 22 | imagen = Image.open(str(img_path)) 23 | doc = image_to_string(imagen, timeout=50, lang='spa+ara+eng+jpn+chi+deu+fra+rus+por+ita+nld', config='--psm 3') 24 | interaction_cache[chat.id] = ("visto", datetime.now()) 25 | await db.set_chat_attribute(chat, "last_interaction", datetime.now()) 26 | if len(doc) <= 1: 27 | text = f'{config.lang[lang]["errores"]["error"]}: {config.lang[lang]["errores"]["ocr_no_extract"]}' 28 | else: 29 | text = config.lang[lang]["mensajes"]["image_ocr_ask"].format(ocresult=doc) 30 | doc, _, advertencia = await clean_text(doc, chat) 31 | if advertencia==True: 32 | text = f'{config.lang[lang]["metagen"]["advertencia"]}: {config.lang[lang]["errores"]["advertencia_tokens_excedidos"]}\n\n{text}' 33 | new_dialog_message = {"user": f'{config.lang[lang]["metagen"]["transcripcion_imagen"]}: "{doc}"', "date": datetime.now()} 34 | await update_dialog_messages(chat, new_dialog_message) 35 | except RuntimeError: 36 | text = f'{config.lang[lang]["errores"]["error"]}: {config.lang[lang]["errores"]["tiempoagotado"]}' 37 | await update.message.reply_text(f'{text}', parse_mode=ParseMode.MARKDOWN) 38 | await tasks.releasemaphore(chat=chat) 39 | async def wrapper(update: Update, context: CallbackContext): 40 | from bot.src.utils.proxies import (debe_continuar,obtener_contextos as oc, parametros, bb) 41 | if not update.effective_message.photo: return 42 | chat, lang = await oc(update) 43 | await parametros(chat, lang, update) 44 | if not await debe_continuar(chat, lang, update, context): return 45 | task = bb(handle(chat, lang, update, context)) 46 | await tasks.handle(chat, task) 47 | 48 | -------------------------------------------------------------------------------- /bot/src/handlers/semaphore.py: -------------------------------------------------------------------------------- 1 | from bot.src.utils.proxies import chat_locks, chat_tasks, asyncio 2 | from bot.src.utils.constants import logger 3 | async def handle(chat, task): 4 | async with chat_locks[chat.id]: 5 | chat_tasks[chat.id] = task 6 | try: 7 | await acquiresemaphore(chat=chat) 8 | await task 9 | except asyncio.CancelledError: 10 | task.cancel() 11 | except Exception as e: 12 | if "access local variable 'answer' where" in str(e): None 13 | else: logger.error(f"{__name__}: Error: {e}") 14 | finally: 15 | await releasemaphore(chat) 16 | chat_tasks.pop(chat.id, None) 17 | 18 | async def acquiresemaphore(chat): 19 | lock = chat_locks.get(chat.id) 20 | lock = asyncio.Lock() if lock is None else lock 21 | chat_locks[chat.id] = lock 22 | await lock.acquire() 23 | async def releasemaphore(chat): 24 | lock = chat_locks.get(chat.id) 25 | lock.release() if lock and lock.locked() else None -------------------------------------------------------------------------------- /bot/src/handlers/timeout.py: -------------------------------------------------------------------------------- 1 | from bot.src.start import Update, CallbackContext 2 | 3 | from telegram import ( 4 | InlineKeyboardButton, 5 | InlineKeyboardMarkup, 6 | ) 7 | from datetime import datetime 8 | from . import semaphore as tasks 9 | from bot.src.utils.misc import update_dialog_messages 10 | from bot.src.utils.constants import logger 11 | from .commands import new, retry 12 | from . import message 13 | async def ask(chat, lang, update: Update, _message): 14 | from bot.src.utils.proxies import (config) 15 | try: 16 | keyboard = [[ 17 | InlineKeyboardButton("✅", callback_data="new_dialog|true"), 18 | InlineKeyboardButton("❎", callback_data="new_dialog|false"), 19 | ]] 20 | reply_markup = InlineKeyboardMarkup(keyboard) 21 | 22 | new_dialog_message = {"user": _message, "date": datetime.now()} 23 | await update_dialog_messages(chat, new_dialog_message) 24 | 25 | await update.effective_chat.send_message(f'{config.lang[lang]["mensajes"]["timeout_ask"]}', reply_markup=reply_markup) 26 | except Exception as e: 27 | logger.error(f'Timeout.ask > {e}') 28 | 29 | async def answer(update: Update, context: CallbackContext): 30 | from bot.src.utils.proxies import (obtener_contextos as oc,db,config) 31 | try: 32 | chat, lang = await oc(update) 33 | query = update.callback_query 34 | await query.answer() 35 | new_dialog = query.data.split("|")[1] 36 | dialog_messages = await db.get_dialog_messages(chat, dialog_id=None) 37 | await tasks.releasemaphore(chat=chat) 38 | if len(dialog_messages) == 0: 39 | await update.effective_chat.send_message(f'{config.lang[lang]["mensajes"]["timeout_nodialog"]}') 40 | await new.handle(update, context) 41 | return 42 | elif 'bot' in dialog_messages[-1]: # already answered, do nothing 43 | return 44 | await query.message.delete() 45 | if new_dialog == "true": 46 | last_dialog_message = dialog_messages.pop() 47 | await new.handle(update, context) 48 | await message.handle(chat, lang, update, context, _message=last_dialog_message["user"]) 49 | elif new_dialog == "false": await retry.handle(update, context) 50 | except Exception as e: 51 | logger.error(f'Timeout.answer > {e}') -------------------------------------------------------------------------------- /bot/src/handlers/url.py: -------------------------------------------------------------------------------- 1 | from bot.src.utils.misc import clean_text, update_dialog_messages 2 | from datetime import datetime 3 | headers = { 4 | "User-Agent": "Mozilla/5.0 (Android 13; Mobile; rv:109.0) Gecko/113.0 Firefox/113.0" 5 | } 6 | 7 | async def extract_from_url(url: str) -> str: 8 | from bot.src.utils.proxies import config 9 | from aiohttp import ClientSession 10 | from html2text import HTML2Text 11 | 12 | async with ClientSession() as session: 13 | async with session.get(url, headers=headers, allow_redirects=True, proxy=config.apisproxy) as response: 14 | response.raise_for_status() 15 | content_length = int(response.headers.get('Content-Length', 0)) 16 | if content_length > config.url_max_size * (1024 * 1024): 17 | raise ValueError("lenghtexceed") 18 | html_content = await response.text() 19 | 20 | text_maker = HTML2Text() 21 | text_maker.ignore_links = True 22 | text_maker.ignore_images = True 23 | text_maker.single_line_break = True 24 | doc = str(text_maker.handle(html_content)) 25 | return doc 26 | 27 | async def handle(chat, lang, update, urls): 28 | from bot.src.utils.proxies import config, ChatAction, interaction_cache, db 29 | textomensaje="" 30 | for url in urls: 31 | await update.effective_chat.send_action(ChatAction.TYPING) 32 | try: 33 | textomensaje = None 34 | if not config.url_ask_before_send: 35 | textomensaje = f'{config.lang[lang]["mensajes"]["url_anotado_ask"]}' 36 | doc = await extract_from_url(url) 37 | doc, _, advertencia = await clean_text(doc, chat) 38 | if advertencia==True: 39 | textomensaje = f'{config.lang[lang]["metagen"]["advertencia"]}: {config.lang[lang]["errores"]["advertencia_tokens_excedidos"]}\n\n{textomensaje if textomensaje else ""}' 40 | new_dialog_message = {"url": f"{url} -> content: {doc}", "date": datetime.now()} 41 | await update_dialog_messages(chat, new_dialog_message) 42 | except ValueError as e: 43 | if "lenghtexceed" in str(e): 44 | textomensaje = f'{config.lang[lang]["errores"]["url_size_limit"]}: {e}' 45 | else: textomensaje = f'{config.lang[lang]["errores"]["error"]}: {e}' 46 | interaction_cache[chat.id] = ("visto", datetime.now()) 47 | await db.set_chat_attribute(chat, "last_interaction", datetime.now()) 48 | return textomensaje 49 | async def wrapper(raw_msg): 50 | urls = [] 51 | for entity in raw_msg.entities: 52 | if entity.type == 'url': 53 | url_add = raw_msg.text[entity.offset:entity.offset+entity.length] 54 | if "http://" in url_add or "https://" in url_add: 55 | urls.append(raw_msg.text[entity.offset:entity.offset+entity.length]) 56 | return urls 57 | -------------------------------------------------------------------------------- /bot/src/handlers/voice.py: -------------------------------------------------------------------------------- 1 | from subprocess import call 2 | from datetime import datetime 3 | from bot.src.start import Update, CallbackContext 4 | from tempfile import TemporaryDirectory 5 | from pathlib import Path 6 | from bot.src.utils.gen_utils.phase import ChatGPT 7 | from bot.src.utils.constants import logger 8 | async def handle(chat, lang, update, context): 9 | if update.message.voice: audio = update.message.voice 10 | elif update.message.audio: audio = update.message.audio 11 | else: return 12 | from . import semaphore as tasks 13 | from bot.src.utils.proxies import (db,interaction_cache,config,ChatAction,errorpredlang) 14 | # Procesar sea voz o audio 15 | file_size_mb = audio.file_size / (1024 * 1024) 16 | transcribed_text = None 17 | if file_size_mb <= config.audio_max_size: 18 | try: 19 | await update.effective_chat.send_action(ChatAction.TYPING) 20 | with TemporaryDirectory() as tmp_dir: 21 | # Descargar y convertir a MP3 22 | tmp_dir = Path(tmp_dir) 23 | 24 | doc_path = tmp_dir / Path("tempaudio" + audio.mime_type.split("/")[1]) 25 | 26 | # download 27 | voice_file = await context.bot.get_file(audio.file_id) 28 | await voice_file.download_to_drive(doc_path) 29 | 30 | # convert to mp3 31 | mp3_file_path = tmp_dir / "voice.mp3" 32 | call(f"sox {doc_path} -C 64 -r 16000 -q {mp3_file_path} > /dev/null 2>&1", shell=True) 33 | 34 | # Transcribir 35 | with open(mp3_file_path, "rb") as f: 36 | await tasks.releasemaphore(chat=chat) 37 | insta = await ChatGPT.create(chat) 38 | transcribed_text = await insta.transcribe(f) 39 | 40 | # Enviar respuesta 41 | text = f"🎤 {transcribed_text}" 42 | interaction_cache[chat.id] = ("visto", datetime.now()) 43 | await db.set_chat_attribute(chat, "last_interaction", datetime.now()) 44 | except Exception as e: 45 | logger.error(f'{__name__}: {errorpredlang}: {e}') 46 | await tasks.releasemaphore(chat=chat) 47 | else: 48 | text = f'{config.lang[lang]["errores"]["audio_size_limit"].format(audio_max_size=config.audio_max_size)}' 49 | from bot.src.utils.misc import send_large_message 50 | await send_large_message(text, update) 51 | await tasks.releasemaphore(chat=chat) 52 | if transcribed_text: 53 | from . import message 54 | await message.handle(chat, lang, update, context, _message=transcribed_text) 55 | async def wrapper(update: Update, context: CallbackContext): 56 | from bot.src.utils.proxies import (debe_continuar,obtener_contextos as oc, bb) 57 | chat, lang = await oc(update) 58 | if not await debe_continuar(chat, lang, update, context, bypassmention=True): return 59 | task = bb(handle(chat, lang, update, context)) 60 | from . import semaphore as tasks 61 | await tasks.handle(chat, task) 62 | -------------------------------------------------------------------------------- /bot/src/tasks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/src/tasks/__init__.py -------------------------------------------------------------------------------- /bot/src/tasks/apis_chat.py: -------------------------------------------------------------------------------- 1 | from types import SimpleNamespace 2 | from bot.src.utils import config 3 | from bot.src.utils.gen_utils.make_completion import _make_api_call 4 | from bot.src.utils.preprocess.make_messages import handle as mms 5 | from bot.src.utils.preprocess.make_prompt import handle as mpm 6 | from bot.src.utils.constants import logger 7 | 8 | vivas = config.api["available_api"] 9 | malas = [] 10 | temp_malas = [] 11 | temp_vivas = [] 12 | 13 | async def checar_api(nombre_api): 14 | global temp_malas 15 | pseudo_self = SimpleNamespace() 16 | pseudo_self.api = nombre_api 17 | pseudo_self.lang = "en" 18 | pseudo_self.model = config.api["info"][nombre_api]["available_model"][0] 19 | pseudo_self.proxies = config.apisproxy 20 | pseudo_self.diccionario = {} 21 | pseudo_self.diccionario.clear() 22 | pseudo_self.diccionario.update(config.completion_options) 23 | pseudo_self.diccionario["stream"] = config.usar_streaming 24 | pseudo_self.diccionario["max_tokens"] = 800 25 | _message = "say pong" 26 | chat_mode = "nada" 27 | pseudo_self.chat_mode = "nada" 28 | messages, prompt = (await mms(self=pseudo_self, _message=_message, chat_mode=chat_mode), None) if pseudo_self.model not in config.model["text_completions"] else (None, await mpm(self=pseudo_self, _message="say pong", chat_mode=chat_mode)) 29 | kwargs = { 30 | "prompt": prompt, 31 | "messages": messages, 32 | "_message": _message 33 | } 34 | respuesta = "" 35 | try: 36 | rep = _make_api_call(pseudo_self, **kwargs) 37 | await rep.asend(None) 38 | async for _, answer in rep: 39 | respuesta += answer 40 | if respuesta: 41 | return respuesta 42 | return ["No"] 43 | except Exception as e: 44 | logger.error(f'{config.lang[config.pred_lang]["metagen"]["api"]}: {nombre_api} ❌') 45 | temp_malas.append(nombre_api) 46 | 47 | async def checar_respuesta(nombre_api, respuesta): 48 | global temp_vivas 49 | global temp_malas 50 | if isinstance(respuesta, str) and "pong" in respuesta.lower(): 51 | temp_vivas.append(nombre_api) 52 | else: 53 | temp_malas.append(nombre_api) 54 | 55 | async def task(): 56 | from bot.src.utils.proxies import sleep, asyncio 57 | global vivas 58 | global malas 59 | global temp_vivas 60 | global temp_malas 61 | test=False 62 | while True: 63 | from bot.src.tasks.apis_check_idler import variable_minutes 64 | logger.info("🔍🔌🌐🔄") 65 | try: 66 | temp_vivas = [] 67 | temp_malas = [] 68 | if test != True: 69 | for nombre_api in vivas: 70 | respuesta = await checar_api(nombre_api) 71 | await checar_respuesta(nombre_api, respuesta) 72 | temp_vivas = set(temp_vivas) 73 | temp_malas = set(temp_malas) 74 | vivas = set(vivas) 75 | else: 76 | temp_vivas = vivas 77 | if temp_vivas != vivas: 78 | from bot.src.utils.misc import api_check_text_maker 79 | outp = await api_check_text_maker(type="chat", vivas=vivas, temp_vivas=temp_vivas, temp_malas=temp_malas) 80 | logger.info(outp) 81 | else: 82 | logger.info("CHAT_APIS ✅") 83 | vivas = list(temp_vivas) 84 | malas = list(temp_malas) 85 | except asyncio.CancelledError: 86 | break 87 | await sleep(variable_minutes * 60) 88 | -------------------------------------------------------------------------------- /bot/src/tasks/apis_check_idler.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from datetime import datetime 3 | from bot.src.utils.constants import logger 4 | from bot.src.utils.config import apischeck_minutes as constant_minutes 5 | 6 | variable_minutes = constant_minutes 7 | 8 | async def task(): 9 | global variable_minutes 10 | msg = None 11 | while True: 12 | try: 13 | from bot.src.utils.config import apischeck_minutes as variable_minutes 14 | from bot.src.utils.proxies import last_apis_interaction 15 | if (datetime.now() - last_apis_interaction).seconds > (constant_minutes * 60) - 9: 16 | if not msg: 17 | logger.info("IDLER ON") 18 | msg = True 19 | variable_minutes = 60 20 | else: 21 | if msg: 22 | logger.info("IDLER OFF") 23 | msg = None 24 | variable_minutes = constant_minutes 25 | except asyncio.CancelledError: 26 | break 27 | await asyncio.sleep(10) -------------------------------------------------------------------------------- /bot/src/tasks/apis_image.py: -------------------------------------------------------------------------------- 1 | import secrets 2 | from types import SimpleNamespace 3 | from bot.src.utils import config 4 | from bot.src.utils.gen_utils.make_image import gen as imagen 5 | from bot.src.utils.constants import logger 6 | from bot.src.apis.stablehorde import Models 7 | 8 | img_vivas = config.api["available_image_api"] 9 | img_malas = [] 10 | img_temp_malas = [] 11 | img_temp_vivas = [] 12 | 13 | async def checar_api(nombre_api): 14 | global img_temp_malas 15 | pseudo_self = SimpleNamespace() 16 | pseudo_self.proxies = config.apisproxy 17 | try: 18 | if nombre_api == "stablehorde": 19 | from bot.src.utils.constants import stablehorde_models, models_sh 20 | models_sh = Models.get_models(proxy = pseudo_self.proxies) 21 | stablehorde_models = {index: model_instance.model_name for index, model_instance in models_sh.items()} 22 | model = "stable_diffusion" 23 | else: model = None 24 | image_urls, _ = await imagen(pseudo_self, "a beautiful EGG", nombre_api, "NO_STYLE", None, model, None, None) 25 | if image_urls: 26 | img_temp_vivas.append(nombre_api) 27 | else: 28 | img_temp_malas.append(nombre_api) 29 | except Exception as e: 30 | logger.error(f'{config.lang[config.pred_lang]["metagen"]["image_api"]}: {nombre_api} {e} ❌') 31 | img_temp_malas.append(nombre_api) 32 | 33 | async def task(): 34 | from bot.src.utils.proxies import sleep, asyncio 35 | global img_vivas 36 | global img_malas 37 | global img_temp_vivas 38 | global img_temp_malas 39 | test=False 40 | while True: 41 | from bot.src.tasks.apis_check_idler import variable_minutes 42 | try: 43 | img_temp_vivas = [] 44 | img_temp_malas = [] 45 | if test != True: 46 | for nombre_api in img_vivas: 47 | await checar_api(nombre_api) 48 | img_temp_vivas = set(img_temp_vivas) 49 | img_temp_malas = set(img_temp_malas) 50 | img_vivas = set(img_vivas) 51 | else: 52 | img_temp_vivas = img_vivas 53 | if img_temp_vivas != img_vivas: 54 | from bot.src.utils.misc import api_check_text_maker 55 | outp = await api_check_text_maker(type="img", vivas=img_vivas, temp_vivas=img_temp_vivas, temp_malas=img_temp_malas) 56 | logger.info(outp) 57 | else: 58 | logger.info("IMAGE_APIS ✅") 59 | img_vivas = list(img_temp_vivas) 60 | img_malas = list(img_temp_malas) 61 | except asyncio.CancelledError: 62 | break 63 | await sleep(variable_minutes * 60) 64 | -------------------------------------------------------------------------------- /bot/src/tasks/cache.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | async def delete_expired_items(cache): 4 | for key, value in list(cache.items()): 5 | if datetime.now() > value[1]: 6 | del cache[key] 7 | async def handle_cache(cache): 8 | if cache is not None and isinstance(cache, dict): 9 | await delete_expired_items(cache) 10 | async def task(): 11 | from bot.src.utils.proxies import cache_index, lang_cache, chat_mode_cache, api_cache, model_cache, menu_cache, interaction_cache, image_api_cache, imaginepy_ratios_cache, imaginepy_styles_cache, imaginepy_models_cache, sleep, asyncio 12 | while True: 13 | try: 14 | for cache in cache_index: 15 | await handle_cache(cache) 16 | except asyncio.CancelledError: 17 | break 18 | await sleep(60 * 60) -------------------------------------------------------------------------------- /bot/src/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/src/utils/__init__.py -------------------------------------------------------------------------------- /bot/src/utils/checks/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/src/utils/checks/__init__.py -------------------------------------------------------------------------------- /bot/src/utils/checks/c_bot_mentioned.py: -------------------------------------------------------------------------------- 1 | from bot.src.start import Update, CallbackContext 2 | 3 | async def check(update, context): 4 | message=update.message 5 | try: 6 | return (True if message.chat.type == "private" 7 | or message.text is not None and ("@" + context.bot.username) in message.text 8 | or message.reply_to_message and message.reply_to_message.from_user.id == context.bot.id 9 | else False) 10 | except AttributeError: 11 | return True -------------------------------------------------------------------------------- /bot/src/utils/checks/c_callback.py: -------------------------------------------------------------------------------- 1 | async def check(is_from_callback=None): 2 | if is_from_callback != None: 3 | return is_from_callback 4 | return None -------------------------------------------------------------------------------- /bot/src/utils/checks/c_chat.py: -------------------------------------------------------------------------------- 1 | from bot.src.start import Update 2 | 3 | async def check(update): 4 | chat = update.callback_query.message.chat if update.callback_query else update.effective_chat 5 | return chat -------------------------------------------------------------------------------- /bot/src/utils/checks/c_lang.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from bot.src.utils.constants import constant_db_lang 3 | async def check(update, chat=None): 4 | if not chat: 5 | from bot.src.utils.checks import c_chat 6 | chat = await c_chat.check(update) 7 | from bot.src.utils.proxies import lang_cache, db, config 8 | if lang_cache.get(chat.id) is not None: 9 | lang = lang_cache[chat.id][0] 10 | elif await db.chat_exists(chat): 11 | lang = await db.get_chat_attribute(chat, constant_db_lang) 12 | elif update.effective_user.language_code in config.available_lang: 13 | lang = update.effective_user.language_code 14 | else: 15 | lang = str(config.pred_lang) 16 | lang_cache[chat.id] = (lang, datetime.now()) 17 | return lang -------------------------------------------------------------------------------- /bot/src/utils/checks/c_message.py: -------------------------------------------------------------------------------- 1 | async def check(update, _message=None): 2 | raw_msg = _message or update.effective_message 3 | if not isinstance(raw_msg, str): 4 | _message = raw_msg.text if raw_msg.text else raw_msg.reply_to_message.text 5 | return raw_msg, _message -------------------------------------------------------------------------------- /bot/src/utils/checks/c_message_not_answered_yet.py: -------------------------------------------------------------------------------- 1 | async def check(chat, lang, update): 2 | from bot.src.utils.proxies import chat_locks, config, ParseMode 3 | lock = chat_locks.get(chat.id) 4 | if lock and lock.locked(): 5 | text = f'{config.lang[lang]["mensajes"]["mensaje_semaforo"]}' 6 | # Extracted nested conditional into an independent statement 7 | if update.callback_query: 8 | msgid = update.callback_query.message.message_id 9 | elif update.message: 10 | msgid = update.message.message_id 11 | else: 12 | msgid = update.effective_message.message_id 13 | await update.effective_chat.send_message(text, reply_to_message_id=msgid, parse_mode=ParseMode.HTML) 14 | return True 15 | else: 16 | return False -------------------------------------------------------------------------------- /bot/src/utils/checks/c_parameters.py: -------------------------------------------------------------------------------- 1 | from secrets import randbelow 2 | from datetime import datetime 3 | from bot.src.utils.constants import (logger, constant_db_model, constant_db_chat_mode, constant_db_api, 4 | constant_db_image_api, constant_db_image_api_styles, image_api_styles, constant_db_imaginepy_ratios, 5 | constant_db_imaginepy_styles, imaginepy_ratios, 6 | imaginepy_styles, imaginepy_models, constant_db_imaginepy_models, constant_db_stablehorde_models, stablehorde_models) 7 | 8 | async def check_attribute(chat, available, cache, db_attribute, update, error_message, atributos, stablehorde_workaround = None): 9 | try: 10 | from bot.src.utils.proxies import db 11 | current = cache[chat.id][0] if chat.id in cache else atributos[db_attribute] 12 | aviso = None 13 | if stablehorde_workaround: 14 | currente = available.get(int(current), None) 15 | if not currente: 16 | aviso = True 17 | else: 18 | if current not in available: 19 | aviso = True 20 | 21 | if aviso: 22 | current = available[randbelow(len(available))] 23 | cache[chat.id] = (current, datetime.now()) 24 | await db.set_chat_attribute(chat, db_attribute, current) 25 | await update.effective_chat.send_message(error_message.format(new=current)) 26 | 27 | if cache.get(chat.id) is None or cache.get(chat.id)[0] != current: 28 | cache[chat.id] = (current, datetime.now()) 29 | return current 30 | except Exception as e: 31 | logger.error(f' {available} | {cache} | {db_attribute} <-- {e}') 32 | 33 | async def check(chat, lang, update): 34 | from bot.src.tasks.apis_chat import vivas as apis_vivas 35 | from bot.src.tasks.apis_image import img_vivas 36 | from bot.src.utils.proxies import db, chat_mode_cache, api_cache, model_cache, image_api_cache, image_api_styles_cache, config, imaginepy_ratios_cache, imaginepy_styles_cache, imaginepy_models_cache, stablehorde_models_cache 37 | db_attributes = [ 38 | constant_db_chat_mode, 39 | constant_db_api, 40 | constant_db_image_api, 41 | constant_db_model, 42 | constant_db_image_api_styles, 43 | constant_db_stablehorde_models 44 | ] 45 | atributos = await db.get_chat_attributes_dict(chat, db_attributes) 46 | checked_chat_mode = await check_attribute( 47 | chat, 48 | config.chat_mode["available_chat_mode"], 49 | chat_mode_cache, 50 | constant_db_chat_mode, 51 | update, 52 | config.lang[lang]["errores"]["reset_chat_mode"], 53 | atributos 54 | ) 55 | checked_api = await check_attribute( 56 | chat, 57 | apis_vivas, 58 | api_cache, 59 | constant_db_api, 60 | update, 61 | config.lang[lang]["errores"]["reset_api"], 62 | atributos 63 | ) 64 | checked_image_api = await check_attribute( 65 | chat, 66 | img_vivas, 67 | image_api_cache, 68 | constant_db_image_api, 69 | update, 70 | config.lang[lang]["errores"]["reset_api"], 71 | atributos 72 | ) 73 | checked_model = await check_attribute( 74 | chat, 75 | config.api["info"][checked_api]["available_model"], 76 | model_cache, 77 | constant_db_model, 78 | update, 79 | config.lang[lang]["errores"]["reset_model"], 80 | atributos 81 | ) 82 | checked_image_styles = await check_attribute( 83 | chat, 84 | image_api_styles, 85 | image_api_styles_cache, 86 | constant_db_image_api_styles, 87 | update, 88 | config.lang[lang]["errores"]["reset_image_styles"], 89 | atributos 90 | ) 91 | checked_stablehorde_models = await check_attribute( 92 | chat, 93 | stablehorde_models, 94 | stablehorde_models_cache, 95 | constant_db_stablehorde_models, 96 | update, 97 | config.lang[lang]["errores"]["reset_imaginepy_models"], 98 | atributos, 99 | stablehorde_workaround = True 100 | ) 101 | return checked_chat_mode, checked_api, checked_model, checked_image_api, checked_image_styles, None, checked_stablehorde_models 102 | 103 | async def useless_atm(chat, lang, update): 104 | from bot.src.utils.proxies import config, imaginepy_ratios_cache, imaginepy_styles_cache, imaginepy_models_cache 105 | checked_imaginepy_styles = await check_attribute( 106 | chat, 107 | imaginepy_styles, 108 | imaginepy_styles_cache, 109 | constant_db_imaginepy_styles, 110 | update, 111 | config.lang[lang]["errores"]["reset_imaginepy_styles"] 112 | ) 113 | checked_imaginepy_ratios = await check_attribute( 114 | chat, 115 | imaginepy_ratios, 116 | imaginepy_ratios_cache, 117 | constant_db_imaginepy_ratios, 118 | update, 119 | config.lang[lang]["errores"]["reset_imaginepy_ratios"] 120 | ) 121 | checked_imaginepy_models = await check_attribute( 122 | chat, 123 | imaginepy_models, 124 | imaginepy_models_cache, 125 | constant_db_imaginepy_models, 126 | update, 127 | config.lang[lang]["errores"]["reset_imaginepy_models"] 128 | ) 129 | return checked_imaginepy_styles, checked_imaginepy_ratios, checked_imaginepy_models -------------------------------------------------------------------------------- /bot/src/utils/config.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | from json import load 4 | from dotenv import load_dotenv 5 | load_dotenv() 6 | 7 | # parse environment variables 8 | env = {key: os.getenv(key).split(',') if os.getenv(key) else [] for key in os.environ} 9 | telegram_token = env.get('TELEGRAM_TOKEN', [])[0] 10 | itemspage = int(env.get('MAX_ITEMS_PER_PAGE', [10])[0]) 11 | columnpage = int(env.get('MAX_COLUMNS_PER_PAGE', [2])[0]) 12 | 13 | user_whitelist = env.get('USER_WHITELIST', []) 14 | json_database = bool(env.get('WITHOUT_MONGODB', ['False'])[0].lower() == 'true') 15 | dialog_timeout = int(env.get('DIALOG_TIMEOUT', [7200])[0]) 16 | n_images = int(env.get('OUTPUT_IMAGES', [4])[0]) 17 | if json_database != True: 18 | mongus = env.get("MONGODB_HOST", ['mongo'])[0] 19 | if "mongodb.net" in mongus: 20 | MONGODB_PROTO = "mongodb+srv" 21 | else: 22 | MONGODB_PROTO = "mongodb" 23 | mongodb_uri = f"{MONGODB_PROTO}://{env.get('MONGODB_USERNAME', ['root'])[0]}:{env.get('MONGODB_PASSWORD', ['MMWjHEHT8zd3FMR5KPd7eu6MKV2ndpUd'])[0]}@{mongus}/?retryWrites=true&w=majority" 24 | 25 | disable_apis_checkers = bool(env.get('DISABLE_APIS_CHECK', ['True'])[0].lower() == 'true') 26 | apischeck_minutes = int(env.get('APIS_CHECK_MINUTES', [10])[0]) 27 | url_ask_before_send = bool(env.get('URL_DIRECT_RESPONSE', ['True'])[0].lower() == 'true') 28 | usar_streaming = bool(env.get('STREAM_ANSWERS', ['True'])[0].lower() == 'true') 29 | usar_funciones = bool(env.get('FEATURE_FUNCTION_CALLS', ['True'])[0].lower() == 'true') 30 | timeout_ask = bool(env.get('TIMEOUT_ASK', ['True'])[0].lower() == 'true') 31 | switch_voice = bool(env.get('FEATURE_TRANSCRIPTION', ['True'])[0].lower() == 'true') 32 | switch_ocr = bool(env.get('FEATURE_IMAGE_READ', ['True'])[0].lower() == 'true') 33 | switch_docs = bool(env.get('FEATURE_DOCUMENT_READ', ['True'])[0].lower() == 'true') 34 | switch_imgs = bool(env.get('FEATURE_IMAGE_GENERATION', ['True'])[0].lower() == 'true') 35 | switch_search = bool(env.get('FEATURE_BROWSING', ['True'])[0].lower() == 'true') 36 | switch_urls = bool(env.get('FEATURE_URL_READ', ['True'])[0].lower() == 'true') 37 | audio_max_size = int(env.get('AUDIO_MAX_MB', [20])[0]) 38 | generatedimagexpiration = int(env.get('GENERATED_IMAGE_EXPIRATION_MINUTES', ['5'])[0]) 39 | file_max_size = int(env.get('DOC_MAX_MB', [10])[0]) 40 | url_max_size = int(env.get('URL_MAX_MB', [5])[0]) 41 | 42 | max_retries = int(env.get('REQUEST_MAX_RETRIES', [3])[0]) 43 | 44 | request_timeout = int(env.get('REQUEST_TIMEOUT', [10])[0]) 45 | pdf_page_lim = int(env.get('PDF_PAGE_LIMIT', [25])[0]) 46 | pred_lang = str(env.get('AUTO_LANG', ['en'])[0]) 47 | 48 | custom_imaginepy_url = env.get('IMAGINE_URL', [None])[0] 49 | 50 | proxy_raw = env.get('API_TUNNEL', [None])[0] 51 | apisproxy = {proxy_raw.split("://")[0] + "://": proxy_raw} if proxy_raw is not None else None 52 | if apisproxy: 53 | apisproxy = next(iter(apisproxy.values())) 54 | 55 | basepath = Path(__file__).resolve().parents[3] 56 | # set config paths 57 | config_dir = basepath / "config" 58 | # load config files 59 | 60 | #language 61 | # Obtener la lista de archivos en la carpeta 62 | archivos = os.listdir(basepath / "locales") 63 | # Filtrar los archivos que tienen el formato .json 64 | archivos_idiomas = [archivo for archivo in archivos if archivo.endswith(".json") and archivo != "props.json"] 65 | # Extraer el código de idioma de cada archivo y generar la lista 66 | available_lang = [archivo.split(".")[1] for archivo in archivos_idiomas] 67 | 68 | especificacionlang = "El bot debe responder a todos los mensajes exclusivamente en idioma {language}" 69 | lang = {} 70 | 71 | for locale in available_lang: 72 | with open(basepath / f"locales/lang.{locale}.json", "r", encoding="utf-8") as infile: 73 | lang[locale] = load(infile) 74 | 75 | # apis 76 | with open(config_dir / "api.json", 'r', encoding="utf-8") as f: 77 | api = load(f) 78 | 79 | # chat_modes 80 | with open(config_dir / "chat_mode.json", 'r', encoding="utf-8") as f: 81 | chat_mode = load(f) 82 | 83 | # models 84 | with open(config_dir / "model.json", 'r', encoding="utf-8") as f: 85 | model = load(f) 86 | 87 | #completion_options 88 | with open(config_dir / "openai_completion_options.json", 'r', encoding="utf-8") as f: 89 | completion_options = load(f) 90 | 91 | #props 92 | with open(basepath / "locales/props.json", 'r', encoding="utf-8") as f: 93 | props = load(f) 94 | 95 | # set file pathsfrom 96 | help_group_chat_video_path = basepath / "static" / "help_group_chat.mp4" 97 | -------------------------------------------------------------------------------- /bot/src/utils/constants.py: -------------------------------------------------------------------------------- 1 | import logging 2 | logger = logging.getLogger('ChatGPTG') 3 | logger.setLevel(logging.INFO) 4 | 5 | handler = logging.StreamHandler() 6 | formatter = logging.Formatter('%(name)s | %(levelname)s > %(message)s') 7 | handler.setFormatter(formatter) 8 | logger.addHandler(handler) 9 | 10 | 11 | constant_db_model = "current_model" 12 | constant_db_chat_mode = "current_chat_mode" 13 | constant_db_image_api = "current_image_api" 14 | constant_db_image_api_styles = "current_image_api_style" 15 | constant_db_imaginepy_styles = "current_imaginepy_style" 16 | constant_db_imaginepy_ratios = "current_imaginepy_ratio" 17 | constant_db_imaginepy_models = "current_imaginepy_model" 18 | constant_db_stablehorde_models = "current_stablehorde_model" 19 | 20 | constant_db_api = "current_api" 21 | constant_db_lang = "current_lang" 22 | constant_db_tokens = "current_max_tokens" 23 | continue_key = "Renounce€Countless€Unrivaled2€Banter" 24 | 25 | from bot.src.apis.imagine import image_api_styles, Style 26 | 27 | #imaginepy_styles = [style.name for style in Style] 28 | #imaginepy_ratios = [ratio.name for ratio in Ratio] 29 | #imaginepy_models = [model.name for model in Model] 30 | imaginepy_styles = None 31 | imaginepy_ratios = None 32 | imaginepy_models = None 33 | 34 | from bot.src.apis.stablehorde import stablehorde_models 35 | 36 | ERRFUNC = "Error retrieving function." 37 | FUNCNOARG = "No se encontraron argumentos de busqueda. por favor pidele al usuario qué quiere buscar." 38 | -------------------------------------------------------------------------------- /bot/src/utils/gen_utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/src/utils/gen_utils/__init__.py -------------------------------------------------------------------------------- /bot/src/utils/gen_utils/make_completion.py: -------------------------------------------------------------------------------- 1 | from bot.src.utils import config 2 | import asyncio 3 | import aiohttp 4 | from .openai.openai_completion import _openai 5 | 6 | async def _make_api_call(self, **kwargs): 7 | self.answer = "" 8 | request_timeout = config.request_timeout 9 | if config.usar_streaming == False: 10 | request_timeout = request_timeout * 5 11 | api_function = api_functions.get(self.api, _openai) 12 | for attempt in range(1, (config.max_retries) + 1): 13 | try: 14 | # Crea un iterador asincrónico 15 | api_iterator = api_function(self, **kwargs).__aiter__() 16 | 17 | # Espera el primer paquete con un tiempo de espera 18 | first_packet = await asyncio.wait_for(api_iterator.__anext__(), timeout=request_timeout) 19 | 20 | # Si el primer paquete se recibe con éxito, continúa con el resto de la respuesta 21 | yield first_packet 22 | async for status, self.answer in api_iterator: 23 | yield status, self.answer 24 | break # Si la llamada a la API fue exitosa, salimos del bucle 25 | except (aiohttp.client_exceptions.ClientConnectionError, asyncio.exceptions.TimeoutError, asyncio.TimeoutError): None 26 | except Exception as e: 27 | if attempt < config.max_retries: await asyncio.sleep(2) 28 | else: # Si hemos alcanzado el máximo número de reintentos, lanzamos la excepción 29 | #yield "error", f'{config.lang[self.lang]["errores"]["reintentos_alcanzados"].format(reintentos=config.max_retries)}' 30 | raise ConnectionError(f'_make_api_call. {config.lang[config.pred_lang]["errores"]["reintentos_alcanzados"].format(reintentos=config.max_retries)}: {e}') 31 | 32 | async def _generic_create(self, **kwargs): 33 | try: 34 | if self.api == "evagpt4": 35 | self.diccionario["messages"] = kwargs["messages"] 36 | from bot.src.apis.opengpt.evagpt4 import create 37 | 38 | async for _, content in create(self): 39 | self.answer += content 40 | yield "not_finished", self.answer 41 | 42 | except Exception as e: 43 | raise ConnectionError(f"_generic_create {self.api}: {e}") 44 | 45 | api_functions = { 46 | "evagpt4": _generic_create, 47 | } 48 | -------------------------------------------------------------------------------- /bot/src/utils/gen_utils/make_image.py: -------------------------------------------------------------------------------- 1 | async def gen(self, prompt, model, current_api, style, ratio, seed=None, negative=None): 2 | try: 3 | from bot.src.utils.proxies import config 4 | 5 | from bot.src.utils.constants import Style 6 | prompt=f'{prompt + Style[style].value[3]}' 7 | 8 | from bot.src.apis import stablehorde 9 | api_key = config.api["info"][current_api].get("key", None) 10 | if current_api == "stablehorde": 11 | if isinstance(negative, str): 12 | prompt += f" ### {negative}" 13 | image, seed, model = await stablehorde.main(self, api_key, prompt=prompt, model=model, seed=seed) 14 | return image, seed, model 15 | import openai 16 | if self.proxies is not None: 17 | openai.proxy = {f'{config.proxy_raw.split("://")[0]}': f'{config.proxy_raw}'} 18 | openai.api_key = api_key 19 | openai.api_base = config.api["info"][current_api]["url"] 20 | r = await openai.Image.acreate(prompt=prompt, n=config.n_images, size="1024x1024") 21 | image_urls = [item.url for item in r.data] 22 | return image_urls, None, None 23 | except Exception as e: 24 | raise RuntimeError(f'make_image.gen > {e}') -------------------------------------------------------------------------------- /bot/src/utils/gen_utils/make_transcription.py: -------------------------------------------------------------------------------- 1 | async def write(self, audio_file): 2 | from bot.src.utils import config 3 | import secrets 4 | import openai 5 | if self.api not in config.api["available_transcript"]: 6 | index = secrets.randbelow(len(config.api["available_transcript"])) 7 | self.api = config.api["available_transcript"][index] 8 | openai.api_key = config.api["info"][self.api]["key"] 9 | openai.api_base = config.api["info"][self.api]["url"] 10 | if self.proxies is not None: 11 | openai.proxy = {f'{config.proxy_raw.split("://")[0]}': f'{config.proxy_raw}'} 12 | r = await openai.Audio.atranscribe("whisper-1", audio_file) 13 | return r["text"] -------------------------------------------------------------------------------- /bot/src/utils/gen_utils/middleware.py: -------------------------------------------------------------------------------- 1 | from aiohttp import ClientSession 2 | 3 | headers = { 4 | "Accept": "*/*", 5 | "User-Agent": "GPTG" 6 | } 7 | async def get_ip(self): 8 | url = "https://mip.resisto.rodeo" # Reemplaza con tu dominio o dirección IP 9 | async with ClientSession() as session: 10 | async with session.get(url, headers=headers, proxy=self.proxies) as response: 11 | ip = await response.text() 12 | ip = ip.strip() # Elimina espacios en blanco alrededor de la IP 13 | return ip 14 | 15 | async def resetip(self): 16 | from bot.src.utils.config import api 17 | if not api["info"][self.api].get("resetip"): 18 | return None 19 | 20 | global apisdict 21 | 22 | new_ip = await get_ip(self) 23 | 24 | if not apisdict.get(self.api): 25 | apisdict[self.api] = {"ip": None} 26 | if not apisdict.get(self.api).get("ip") or apisdict.get(self.api).get("ip") != new_ip: 27 | if await process_request(self, api): 28 | apisdict[self.api]["ip"] = new_ip 29 | print(apisdict) 30 | return True 31 | 32 | return None 33 | 34 | async def process_request(self, api): 35 | url = str(api["info"][self.api].get("resetip")) 36 | 37 | async with ClientSession() as session: 38 | try: 39 | async with session.post(url, headers={"Authorization": "Bearer " + str(api["info"].get(self.api, {}).get("key", ""))}, proxy=self.proxies) as response: 40 | call = await response.text() 41 | except Exception as e: 42 | print(f'Error {__name__}: {e}') 43 | return None 44 | return call 45 | 46 | apisdict = {} -------------------------------------------------------------------------------- /bot/src/utils/gen_utils/openai/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/src/utils/gen_utils/openai/__init__.py -------------------------------------------------------------------------------- /bot/src/utils/gen_utils/openai/openai_functions.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/src/utils/gen_utils/openai/openai_functions.py -------------------------------------------------------------------------------- /bot/src/utils/gen_utils/openai/openai_functions_extraction.py: -------------------------------------------------------------------------------- 1 | import os 2 | import importlib 3 | 4 | from docstring_parser import parse 5 | import inspect 6 | import functools 7 | from typing import Callable 8 | 9 | openai_functions = [] 10 | 11 | def import_functions_from_directory(directory, module_prefix): 12 | function_map = {} 13 | for root, _, files in os.walk(directory): 14 | for file in files: 15 | if file.endswith(".py") and not file.startswith("__"): 16 | module_path = os.path.join(root, file).replace("\\", "/") 17 | relative_module_path = os.path.relpath(module_path, directory).replace(".py", "") 18 | import_path = f"{module_prefix}.{relative_module_path.replace('/', '.')}" 19 | module = importlib.import_module(import_path) 20 | 21 | for function_name, function_obj in inspect.getmembers(module, inspect.isfunction): 22 | function_map[function_name] = function_obj 23 | 24 | return function_map 25 | 26 | def _get_metadata(function_map): 27 | metadata = [] 28 | for function_name, function_obj in function_map.items(): 29 | if hasattr(function_obj, "_openai_metadata"): 30 | metadata.append(function_obj._openai_metadata) 31 | return metadata 32 | 33 | def get_openai_funcs(return_function_objects = None): 34 | function_map = import_functions_from_directory("bot/functions/openai_front", "bot.functions.openai_front") 35 | 36 | if return_function_objects: 37 | return function_map 38 | else: 39 | return _get_metadata(function_map) 40 | 41 | type_mapping = { 42 | "int": "integer", 43 | "float": "number", 44 | "str": "string", 45 | "bool": "boolean", 46 | "list": "array", 47 | "tuple": "array", 48 | "dict": "object", 49 | "None": "null", 50 | } 51 | 52 | def extract_function_info(func: Callable) -> dict: 53 | parsed_docstring = parse(func.__doc__) 54 | params = inspect.signature(func).parameters 55 | 56 | properties = {} 57 | required_params = [] 58 | for k, v in params.items(): 59 | if k == "self": 60 | continue 61 | 62 | param_type = type_mapping.get(v.annotation.__name__, "string") if v.annotation != inspect.Parameter.empty else "string" 63 | param_description = "" 64 | 65 | default_value_exists = v.default != inspect.Parameter.empty 66 | 67 | for param_doc in parsed_docstring.params: 68 | if param_doc.arg_name == k: 69 | param_description = param_doc.description 70 | break 71 | 72 | properties[k] = { 73 | "type": param_type, 74 | "description": param_description, 75 | } 76 | 77 | if not default_value_exists: 78 | required_params.append(k) 79 | 80 | spec = { 81 | "name": func.__name__, 82 | "description": parsed_docstring.short_description, 83 | "parameters": { 84 | "type": "object", 85 | "properties": properties, 86 | "required": required_params, 87 | }, 88 | } 89 | 90 | return spec 91 | 92 | def openaifunc(func: Callable) -> Callable: 93 | @functools.wraps(func) 94 | def wrapper(*args, **kwargs): 95 | return func(*args, **kwargs) 96 | 97 | spec = extract_function_info(func) 98 | wrapper._openai_metadata = spec 99 | 100 | return wrapper 101 | -------------------------------------------------------------------------------- /bot/src/utils/misc.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from .constants import constant_db_model, constant_db_tokens 3 | from bot.src.utils.preprocess import tokenizer 4 | 5 | async def send_large_message(text, update): 6 | from .proxies import ParseMode 7 | if len(text) <= 4096: 8 | await update.effective_chat.send_message(f'{text}', reply_to_message_id=update.effective_message.message_id, disable_web_page_preview=True, parse_mode=ParseMode.MARKDOWN) 9 | else: 10 | # Divide el mensaje en partes más pequeñas 11 | message_parts = [text[i:i+4096] for i in range(0, len(text), 4096)] 12 | for part in message_parts: 13 | await update.effective_chat.send_message(f'{part}', reply_to_message_id=update.effective_message.message_id, disable_web_page_preview=True, parse_mode=ParseMode.MARKDOWN) 14 | 15 | async def clean_text(doc, chat): 16 | max_tokens = await ver_modelo_get_tokens(chat) 17 | doc, tokencount, advertencia = await tokenizer.handle(input_data=doc, max_tokens=max_tokens) 18 | return doc, tokencount, advertencia 19 | 20 | async def update_dialog_messages(chat, new_dialog_message=None): 21 | from .proxies import db 22 | dialog_messages = await db.get_dialog_messages(chat, dialog_id=None) 23 | max_tokens = await ver_modelo_get_tokens(chat) 24 | if new_dialog_message is not None: dialog_messages += [new_dialog_message] 25 | dialog_messages, tokencount, advertencia = await tokenizer.handle(input_data=dialog_messages, max_tokens=max_tokens) 26 | await db.set_dialog_messages( 27 | chat, 28 | dialog_messages, 29 | dialog_id=None 30 | ) 31 | await db.set_dialog_attribute(chat, f'{constant_db_tokens}', int(tokencount)) 32 | return advertencia, dialog_messages, int(tokencount) 33 | 34 | async def ver_modelo_get_tokens(chat=None, model=None, api=None): 35 | try: 36 | from .proxies import db, model_cache 37 | if not model: 38 | model = model_cache[chat.id][0] if model_cache.get(chat.id) else await db.get_chat_attribute(chat, f'{constant_db_model}') 39 | model_cache[chat.id] = (model, datetime.now()) 40 | 41 | from bot.src.utils.config import model as modelist, api as apilist 42 | if api and apilist["info"][api].get("api_max_tokens"): 43 | return int(apilist["info"][api]["api_max_tokens"]) 44 | 45 | return int(modelist["info"][model]["max_tokens"]) 46 | except Exception as e: raise ValueError(f' {e}') 47 | 48 | async def api_check_text_maker(type: str = None, vivas: set = None, temp_vivas: set = None, temp_malas: set = None): 49 | from bot.src.utils import config 50 | if type == "img": 51 | init = config.lang[config.pred_lang]["metagen"]["image_api"] 52 | elif type == "chat": 53 | init = config.lang[config.pred_lang]["metagen"]["api"] 54 | 55 | check = config.lang[config.pred_lang]["apicheck"]["inicio"] 56 | totales = f'{config.lang[config.pred_lang]["apicheck"]["connection"]}: {len(temp_vivas)}, {config.lang[config.pred_lang]["apicheck"]["bad"]}: {len(temp_malas)}, {config.lang[config.pred_lang]["apicheck"]["total"]}: {len(vivas)}' 57 | tex_vivas = "" 58 | tex_malas = "" 59 | text = """{init}: {check}\n\n{totales}""" 60 | if temp_vivas: 61 | tex_vivas = f'{config.lang[config.pred_lang]["apicheck"]["working"]}: {temp_vivas}' 62 | text += "\n{vivas}" 63 | if temp_malas: 64 | tex_malas = f'{config.lang[config.pred_lang]["apicheck"]["dead"]}: {temp_malas}' 65 | text += "\n{malas}" 66 | return text.format(init=init, check=check, totales=totales, vivas=tex_vivas, malas=tex_malas) 67 | -------------------------------------------------------------------------------- /bot/src/utils/preprocess/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/bot/src/utils/preprocess/__init__.py -------------------------------------------------------------------------------- /bot/src/utils/preprocess/count_tokens.py: -------------------------------------------------------------------------------- 1 | from bot.src.utils import config 2 | from bot.src.utils.proxies import db, chat_mode_cache, model_cache, lang_cache, api_cache 3 | from bot.src.utils.constants import constant_db_tokens, constant_db_chat_mode, constant_db_model, constant_db_lang, constant_db_api 4 | from bot.src.utils.misc import ver_modelo_get_tokens, tokenizer 5 | 6 | async def putos_tokens(chat, _message): 7 | try: 8 | if chat.id in chat_mode_cache and chat.id in model_cache and chat.id in api_cache and chat.id in lang_cache: 9 | chat_mode = chat_mode_cache.get(chat.id)[0] 10 | current_model = model_cache[chat.id][0] 11 | current_api = api_cache[chat.id][0] 12 | language = lang_cache[chat.id][0] 13 | else: 14 | db_args = [constant_db_chat_mode, constant_db_model, constant_db_api, constant_db_lang] 15 | db_call = await db.get_chat_attributes_dict(chat, db_args) 16 | 17 | chat_mode = db_call[constant_db_chat_mode] 18 | current_model = db_call[constant_db_model] 19 | current_api = db_call[constant_db_api] 20 | language = db_call[constant_db_lang] 21 | 22 | max_tokens = await ver_modelo_get_tokens(None, model=current_model, api=current_api) 23 | 24 | dialog_messages = await db.get_dialog_messages(chat, dialog_id=None) 25 | data, dialogos_tokens = await reconteo_tokens(chat, dialog_messages, max_tokens) 26 | 27 | language = config.lang[language]["info"]["name"] 28 | especificacionlang = config.especificacionlang.format(language=language) 29 | prompter = config.chat_mode["info"][chat_mode]["prompt_start"].format(language=language) 30 | injectprompt = """{especificarlang}\n\n{elprompt}\n\n{especificarlang}\n\n{_message}""" 31 | pre_tokens = injectprompt.format(especificarlang=especificacionlang, elprompt=prompter, _message=_message) 32 | _, mensaje_tokens = await reconteo_tokens(chat, pre_tokens, max_tokens) 33 | 34 | await db.set_dialog_attribute(chat, f'{constant_db_tokens}', dialogos_tokens + mensaje_tokens) 35 | completion_tokens = int(max_tokens - dialogos_tokens - mensaje_tokens - (dialogos_tokens * 0.15) - 300) 36 | while completion_tokens < 0: 37 | if len(data) > 0: 38 | data.pop(0) 39 | data, dialogos_tokens = await reconteo_tokens(chat, data, max_tokens) 40 | completion_tokens = int(max_tokens - dialogos_tokens - mensaje_tokens - (dialogos_tokens * 0.15) - 300) 41 | return data, completion_tokens, chat_mode 42 | except Exception as e: 43 | raise ValueError(f' {e}') 44 | 45 | async def reconteo_tokens(chat, input_data, max_tokens): 46 | data, dialogos_tokens, _ = await tokenizer.handle(input_data, max_tokens) 47 | if isinstance(data, list): 48 | await db.set_dialog_messages( 49 | chat, 50 | data, 51 | dialog_id=None 52 | ) 53 | return data, dialogos_tokens 54 | -------------------------------------------------------------------------------- /bot/src/utils/preprocess/make_messages.py: -------------------------------------------------------------------------------- 1 | from bot.src.utils import config 2 | from bot.src.utils.constants import continue_key 3 | 4 | def append_resources_messages(self, messages, dialog_messages): 5 | documento_texts = [] 6 | url_texts = [] 7 | search_texts = [] 8 | for dialog_message in dialog_messages: 9 | documento, url, search = process_resources_message(dialog_message) 10 | documento_texts, url_texts, search_texts = append_resources_texts(documento, url, search, documento_texts, url_texts, search_texts, lang=self.lang) 11 | if documento_texts or url_texts or search_texts: 12 | messages.append({ 13 | "role": "system", 14 | "content": f'{str(documento_texts) if documento_texts else ""}\n{str(url_texts) if url_texts else ""}\n{str(search_texts) if search_texts else ""}\n: {config.lang[self.lang]["metagen"]["contexto"]}' 15 | }) 16 | return messages 17 | def process_resources_message(dialog_message): 18 | documento = dialog_message.get("documento", "") 19 | url = dialog_message.get("url", "") 20 | search = dialog_message.get("search", "") 21 | return documento, url, search 22 | def append_resources_texts(documento, url, search, documento_texts, url_texts, search_texts, lang): 23 | if len(documento) > 1: 24 | documento_texts.append(f"'{config.lang[lang]['metagen']['documentos']}': {documento}") 25 | if len(url) > 1: 26 | url_texts.append(f"'{config.lang[lang]['metagen']['paginas']}': {url}") 27 | if len(search) > 1: 28 | search_texts.append(f"'{config.lang[lang]['metagen']['busquedaweb']}': {search}") 29 | return documento_texts, url_texts, search_texts 30 | 31 | def append_user_bot_messages(messages, dialog_messages): 32 | for dialog_message in dialog_messages: 33 | user = dialog_message.get("user", "") 34 | bot = dialog_message.get("bot", "") 35 | if len(user) >= 2: 36 | messages.append({"role": "user", "content": user}) 37 | if len(bot) >= 2: 38 | messages.append({"role": "assistant", "content": bot}) 39 | return messages 40 | 41 | def append_chat_mode(self, chat_mode, messages): 42 | language = config.lang[self.lang]["info"]["name"] 43 | if chat_mode in ["imagen", "translate"]: 44 | messages.append({"role": "system", "content": f'{config.chat_mode["info"][chat_mode]["prompt_start"].format(language=language)}'}) 45 | elif chat_mode != "nada": 46 | especificacionlang = config.especificacionlang.format(language=language) 47 | prompter = config.chat_mode["info"][chat_mode]["prompt_start"].format(language=language) 48 | injectprompt = """{especificarlang}\n\n{elprompt}\n\n{especificarlang}\n\n""" 49 | messages.append({"role": "system", "content": injectprompt.format(especificarlang=especificacionlang, elprompt=prompter)}) 50 | return messages 51 | 52 | def continue_or_append_latest_message(_message, messages): 53 | if _message == continue_key: 54 | _message = "" 55 | messages.append({"role": "user", "content": "continue from previous point"}) 56 | #last_assistant_message_index = next((index for index, message in reversed(list(enumerate(messages))) if message["role"] == "assistant"), -1) 57 | #if last_assistant_message_index != -1: 58 | #content = messages[last_assistant_message_index]["content"] 59 | #if content.endswith("."): messages[last_assistant_message_index]["content"] = content[:-2] 60 | else: 61 | messages.append({"role": "user", "content": _message}) 62 | return messages 63 | 64 | def append_functions(messages, dialog_messages): 65 | for dialog_message in dialog_messages: 66 | name = dialog_message.get('function') 67 | content = dialog_message.get('func_cont') 68 | if name: 69 | messages.append({ 70 | "role": 'function', 71 | "name": name, 72 | "content": content, 73 | }) 74 | return messages 75 | 76 | async def handle(self, _message="", dialog_messages=[], chat_mode="nada"): 77 | try: 78 | messages = [] 79 | messages = append_chat_mode(self, chat_mode, messages) 80 | messages = append_resources_messages(self, messages, dialog_messages) 81 | messages = append_functions(messages, dialog_messages) 82 | messages = append_user_bot_messages(messages, dialog_messages) 83 | messages = continue_or_append_latest_message(_message, messages) 84 | messages = [message for message in messages if message["content"]] 85 | return messages 86 | except Exception as e: 87 | e = f'_generate_prompt_messages: {e}' 88 | raise ValueError(e) 89 | -------------------------------------------------------------------------------- /bot/src/utils/preprocess/make_prompt.py: -------------------------------------------------------------------------------- 1 | from bot.src.utils import config 2 | from bot.src.utils.constants import continue_key 3 | 4 | def get_resources_texts(dialog_messages, key): 5 | texts = [] 6 | for dialog_message in dialog_messages: 7 | if len(dialog_message.get(key, "")) >= 5: 8 | texts = dialog_message.get(key, "").strip() 9 | if texts: 10 | return "\n".join(texts) 11 | return "" 12 | def append_resources_texts(self, documento_texts, url_texts, search_texts, prompt): 13 | resources = "" 14 | if documento_texts: 15 | resources += f'{config.lang[self.lang]["metagen"]["documentos"]}: {documento_texts}\n\n' 16 | if url_texts: 17 | resources += f'{config.lang[self.lang]["metagen"]["urls"]}: {url_texts}\n\n' 18 | if search_texts: 19 | resources += f'{config.lang[self.lang]["metagen"]["busquedaweb"]}: {search_texts}\n\n' 20 | if len(resources) > 4: 21 | prompt += resources 22 | prompt += f'^{config.lang[self.lang]["metagen"]["mensaje"]}: {prompt}][{config.lang[self.lang]["metagen"]["contexto"]}^\n\n' 23 | return prompt 24 | 25 | def get_prompt_lines(dialog_messages, chat_mode, lang): 26 | prompt_lines = [] 27 | for dialog_message in dialog_messages: 28 | user_text = dialog_message.get("user", "").strip() 29 | if user_text: 30 | if chat_mode != "nada": 31 | prompt_lines.append(f'{config.lang[lang]["metagen"]["usuario"]}: {user_text}\n\n') 32 | else: 33 | prompt_lines.append(f' {user_text}') 34 | bot_text = dialog_message.get("bot", "").strip() 35 | if bot_text: 36 | if chat_mode != "nada": 37 | prompt_lines.append(f'{config.chat_mode["info"][chat_mode]["name"][lang]}: {bot_text}\n\n') 38 | else: 39 | prompt_lines.append(f' {bot_text}') 40 | return "".join(prompt_lines) 41 | 42 | def get_injectprompt(language, prompter): 43 | especificacionlang = config.especificacionlang.format(language=language) 44 | injectprompt = """{especificarlang}\n\n{elprompt}\n\n{especificarlang}\n\n""" 45 | return injectprompt.format(especificarlang=especificacionlang, elprompt=prompter) 46 | 47 | def append_chat_mode(self, chat_mode): 48 | language = config.lang[self.lang]["info"]["name"] 49 | if chat_mode in ["imagen", "translate"]: 50 | return f'{config.chat_mode["info"][chat_mode]["prompt_start"].format(language=language)}' 51 | elif chat_mode != "nada": 52 | prompter = config.chat_mode["info"][chat_mode]["prompt_start"].format(language=language) 53 | if chat_mode != "translate": 54 | return get_injectprompt(language, prompter) 55 | else: 56 | return prompter 57 | return "" 58 | 59 | def continue_or_append_latest_message(self, _message, prompt, chat_mode): 60 | if _message == continue_key: 61 | _message = "" 62 | #if prompt.endswith(".") or prompt.endswith("?"): 63 | #prompt = prompt[:-1] 64 | prompt = f'{prompt} ' 65 | else: 66 | if chat_mode != "nada": 67 | prompt += f'\n\n{config.lang[self.lang]["metagen"]["usuario"]}: {_message}' 68 | prompt += f'\n\n{config.chat_mode["info"][chat_mode]["name"][self.lang]}:' 69 | else: 70 | prompt += f' {_message}' 71 | return prompt 72 | 73 | async def handle(self, _message="", dialog_messages=[], chat_mode="nada"): 74 | try: 75 | prompt = "" 76 | documento_texts = "" 77 | url_texts = "" 78 | search_texts = "" 79 | documento_texts = get_resources_texts(dialog_messages, "documento") 80 | url_texts = get_resources_texts(dialog_messages, "url") 81 | search_texts = get_resources_texts(dialog_messages, "search") 82 | prompt = append_resources_texts(self, documento_texts, url_texts, search_texts, prompt) 83 | prompt += append_chat_mode(self, chat_mode) 84 | if chat_mode != "nada": 85 | prompt += f'{config.lang[self.lang]["metagen"]["log"]}:\n\n' 86 | prompt += get_prompt_lines(dialog_messages, chat_mode, lang=self.lang) 87 | prompt = continue_or_append_latest_message(self, _message, prompt, chat_mode) 88 | return prompt 89 | except Exception as e: 90 | e = f'_generate_prompt: {e}' 91 | raise ValueError(e) -------------------------------------------------------------------------------- /bot/src/utils/preprocess/parse_headers.py: -------------------------------------------------------------------------------- 1 | from ujson import loads, JSONDecodeError 2 | 3 | def try_parse_json(value): 4 | try: 5 | return loads(value) 6 | except (JSONDecodeError, TypeError): 7 | return value 8 | 9 | def parse_values_to_json(headers_dict): 10 | for key, value in headers_dict.items(): 11 | headers_dict[key] = try_parse_json(value) 12 | return headers_dict -------------------------------------------------------------------------------- /bot/src/utils/preprocess/remove_words.py: -------------------------------------------------------------------------------- 1 | from bot.src.utils import config 2 | from bot.src.utils.constants import logger 3 | from langdetect import detect_langs 4 | from nltk import download, set_proxy 5 | if config.proxy_raw is not None: 6 | logger.info(f"Proxy: {config.proxy_raw}") 7 | set_proxy(config.proxy_raw) 8 | from nltk.corpus import stopwords 9 | from nltk.tokenize import word_tokenize 10 | download('stopwords', quiet=True) 11 | download('punkt', quiet=True) 12 | 13 | languages_map={"ar": "arabic","bg": "bulgarian","ca": "catalan","cz": "czech","da": "danish","nl": "dutch","en": "english","fi": "finnish","fr": "french","de": "german","hi": "hindi","hu": "hungarian","id": "indonesian","it": "italian","nb": "norwegian","pl": "polish","pt": "portuguese","ro": "romanian","ru": "russian","sk": "slovak","es": "spanish","sv": "swedish","tr": "turkish","uk": "ukrainian","vi": "vietnamese"} 14 | 15 | async def deteccion(texto): 16 | try: 17 | if isinstance(texto, list): return await procesar_lista_multilingue(texto) 18 | elif isinstance(texto, str): 19 | texto, _ = await procesar_texto_normal(texto) 20 | return texto 21 | except Exception as e: 22 | logger.error(f"{__name__}: Detección no detectó instancia, detectó {e}") 23 | 24 | async def procesar_lista_multilingue(lista): 25 | resultados = [] 26 | idioma = None 27 | for item in lista: 28 | if isinstance(item, dict): 29 | new_item, idioma = await procesar_item(item, idioma) 30 | resultados.append(new_item) 31 | return resultados 32 | async def procesar_item(item, idioma): 33 | new_item = {} 34 | for key, value in item.items(): 35 | try: 36 | if key in ["user", "bot", "func_cont", "search", "url", "documento"]: new_item[key], idioma = await procesar_texto(value, idioma) 37 | else: new_item[key] = value 38 | except KeyError: 39 | # Manejo de error por valor inexistente 40 | continue 41 | return new_item, idioma 42 | async def procesar_texto(value, idioma): 43 | if not idioma: 44 | processed_text, idioma = await procesar_texto_normal(value) 45 | return processed_text, idioma 46 | else: return await procesar_texto_normal(value, idioma, lock=True), idioma 47 | async def procesar_texto_normal(texto, idioma=None, lock=None): 48 | textofiltrr=None 49 | if texto: 50 | if not idioma: idioma = detect_langs(texto)[0].lang 51 | textofiltrr = await filtrar_palabras_irrelevantes(texto, idioma) 52 | if textofiltrr: 53 | if lock: return "".join(textofiltrr) 54 | else: return "".join(textofiltrr), idioma 55 | else: 56 | logger.error(f"{__name__}: No se detectó ningún idioma en el texto.") 57 | 58 | 59 | cached_stopwords = {} 60 | 61 | async def filtrar_palabras_irrelevantes(texto, idioma): 62 | import re 63 | texto = re.sub(r"[^a-zA-Z0-9\s]", '', texto) 64 | texto = re.sub(r'[\n\r]+', ' ', texto) 65 | texto = re.sub(r' {2,}', ' ', texto) 66 | texto = texto.strip() 67 | if idioma in cached_stopwords: palabras_irrelevantes = cached_stopwords[idioma] 68 | elif languages_map.get(idioma) in stopwords.fileids(): 69 | palabras_irrelevantes = set(stopwords.words(languages_map[idioma])) 70 | cached_stopwords[idioma] = palabras_irrelevantes 71 | else: return texto 72 | palabras = word_tokenize(texto) 73 | palabras_filtradas = [palabra for palabra in palabras if palabra.lower() not in palabras_irrelevantes] 74 | return " ".join(palabras_filtradas) 75 | 76 | async def handle(texto): 77 | resultado = await deteccion(texto) 78 | return resultado -------------------------------------------------------------------------------- /bot/src/utils/preprocess/tokenizer.py: -------------------------------------------------------------------------------- 1 | from tiktoken import get_encoding 2 | import bot.src.utils.preprocess.remove_words as remove_words 3 | from typing import List, Dict, Any, Tuple 4 | 5 | encoding = get_encoding("cl100k_base") 6 | 7 | async def handle(input_data: str | List[Dict[str, Any]], max_tokens: int) -> str | List[Dict] | Tuple[int, bool]: 8 | max_tokens = int(max_tokens) 9 | try: 10 | if isinstance(input_data, str): 11 | tokens = encoding.encode(input_data) 12 | advertencia=None 13 | if len(tokens) > max_tokens: 14 | input_data = await remove_words.handle(texto=input_data) 15 | tokens = encoding.encode(input_data) 16 | if len(tokens) > max_tokens: 17 | buffer_tokens = 500 18 | start_index = len(tokens) - (max_tokens - buffer_tokens) 19 | tokens = tokens[start_index:] 20 | advertencia = True 21 | out_tokens = int(len(tokens)) 22 | return str(encoding.decode(tokens)), out_tokens, bool(advertencia) 23 | elif isinstance(input_data, list): 24 | output_data, total_tokens, advertencia = await process_input_data(input_data, max_tokens) 25 | return list(output_data), int(total_tokens), bool(advertencia) 26 | except Exception as e: 27 | raise ValueError("tokenizer", {e}) 28 | 29 | keys = ["user", "bot", "func_cont", "url", "documento", "search"] 30 | 31 | async def process_input_data(input_data, max_tokens): 32 | output_data = [] 33 | total_tokens = 0 34 | advertencia = None 35 | for message in input_data: 36 | new_message, tokens_in_message = await process_message(message, max_tokens) 37 | 38 | while total_tokens + tokens_in_message > max_tokens: 39 | if len(output_data) == 0: 40 | break 41 | removed_message = output_data.pop(0) # Elimina el mensaje más antiguo 42 | removed_tokens = sum(len(encoding.encode(removed_message[key])) for key in keys if removed_message.get(key)) 43 | total_tokens -= removed_tokens 44 | advertencia = True 45 | 46 | if total_tokens + tokens_in_message > max_tokens: 47 | break 48 | 49 | output_data.append(new_message) 50 | total_tokens += tokens_in_message 51 | 52 | return output_data, total_tokens, advertencia 53 | 54 | async def process_message(message, max_tokens): 55 | total_tokens = 0 56 | new_message = {} 57 | 58 | for key, value in message.items(): 59 | if key in keys: 60 | content = str(value) 61 | tokens = encoding.encode(content) 62 | content_tokens = len(tokens) 63 | if total_tokens + content_tokens > max_tokens: 64 | new_content = await remove_words.handle(texto=content) 65 | new_tokens = encoding.encode(new_content) 66 | content_tokens = len(new_tokens) 67 | else: 68 | new_content = content 69 | new_message[key] = str(new_content) 70 | total_tokens += (content_tokens + 3) 71 | else: 72 | new_message[key] = value 73 | 74 | return new_message, total_tokens 75 | 76 | 77 | async def pre_message(input_data: str) -> int: 78 | return len(encoding.encode(input_data)) 79 | -------------------------------------------------------------------------------- /bot/src/utils/proxies.py: -------------------------------------------------------------------------------- 1 | from bot.src.utils.constants import logger 2 | import asyncio 3 | from bot.src.utils import config, database 4 | import telegram 5 | from telegram import Update 6 | from telegram.ext import CallbackContext 7 | from telegram.constants import ParseMode, ChatAction 8 | import re 9 | import datetime 10 | db = database.Database() 11 | bb = asyncio.create_task 12 | bcs = asyncio.ensure_future 13 | loop = asyncio.get_event_loop() 14 | sleep = asyncio.sleep 15 | chat_locks = {} 16 | chat_tasks = {} 17 | 18 | last_apis_interaction = datetime.datetime.now() 19 | 20 | #cache testing 21 | cache_index = ["lang_cache", "chat_mode_cache", "api_cache", "model_cache", 22 | "menu_cache", "interaction_cache", "image_api_cache", "image_api_styles_cache", 23 | "image_styles_cache", "stablehorde_models_cache"] 24 | lang_cache = {} 25 | chat_mode_cache = {} 26 | api_cache = {} 27 | image_api_cache = {} 28 | image_api_styles_cache = {} 29 | image_styles_cache = {} 30 | imaginepy_ratios_cache = {} 31 | imaginepy_styles_cache = {} 32 | imaginepy_models_cache = {} 33 | stablehorde_models_cache = {} 34 | model_cache = {} 35 | menu_cache = {} 36 | interaction_cache = {} 37 | 38 | user_names = {} 39 | 40 | msg_no_mod = "Message is not modified" 41 | 42 | #contexts and checkers 43 | async def obtener_contextos(update, chat=None, lang=None): 44 | from bot.src.utils.checks import c_chat, c_lang 45 | chat = await c_chat.check(update) if not chat else chat 46 | lang = await c_lang.check(update, chat) if not lang else lang 47 | if not await db.chat_exists(chat): 48 | await db.add_chat(chat, lang) 49 | await db.new_dialog(chat) 50 | from bot.src.handlers.commands.lang import cambiar_idioma 51 | await cambiar_idioma(update, chat, lang) 52 | if chat.id not in chat_locks: chat_locks[chat.id] = asyncio.Semaphore(1) 53 | return chat, lang 54 | 55 | async def debe_continuar(chat, lang, update, context, bypassmention=None): 56 | from bot.src.utils.checks import c_bot_mentioned, c_message_not_answered_yet 57 | if not bypassmention and not await c_bot_mentioned.check(update, context): return False 58 | if await c_message_not_answered_yet.check(chat, lang, update): return False 59 | return True 60 | async def parametros(chat, lang, update): 61 | from bot.src.utils.checks import c_parameters 62 | checked_chat_mode, checked_api, checked_model, checked_image_api, checked_image_styles, checked_imaginepy_ratios, checked_imaginepy_models = await c_parameters.check(chat, lang, update) 63 | return checked_chat_mode, checked_api, checked_model, checked_image_api, checked_image_styles, checked_imaginepy_ratios, checked_imaginepy_models 64 | 65 | errorpredlang = config.lang[config.pred_lang]["errores"]["error"] 66 | menusnotready = config.lang[config.pred_lang]["errores"]["menu_modes_not_ready_yet"] -------------------------------------------------------------------------------- /config/api.example.json: -------------------------------------------------------------------------------- 1 | { 2 | "available_api": [ 3 | "openai", 4 | "evagpt4", 5 | "churchless" 6 | ], 7 | "available_image_api": [ 8 | "stablehorde", 9 | "openai" 10 | ], 11 | "available_transcript": [ 12 | "openai" 13 | ], 14 | "info": { 15 | "openai": { 16 | "name": "OpenAI", 17 | "description": { 18 | "es": "La API oficial.", 19 | "ar": "API الرسمية.", 20 | "en": "The official API.", 21 | "jp": "公式API。", 22 | "zh": "官方API。", 23 | "de": "Die offizielle API.", 24 | "fr": "L'API officielle.", 25 | "ru": "Официальный API.", 26 | "pt": "A API oficial.", 27 | "it": "L'API ufficiale.", 28 | "nl": "De officiële API." 29 | }, 30 | "url": "https://api.openai.com/v1", 31 | "key": "sk-666", 32 | "available_model": [ 33 | "gpt-3.5-turbo", 34 | "gpt-4", 35 | "text-davinci-003", 36 | "curie", 37 | "babbage", 38 | "ada" 39 | ] 40 | }, 41 | "evagpt4": { 42 | "name": "Eva Agent", 43 | "description": { 44 | "es": "es un servicio que ofrece integración de chatgpt para sitios web tanto para gpt3.5-turbo como para gpt-4.", 45 | "ar": "هو خدمة تقدم تكامل ChatGPT للمواقع على حد سواء لـ GPT3.5-Turbo و GPT-4.", 46 | "en": "is a service offering chatgpt integration for websites for both gpt3.5-turbo and gpt-4.", 47 | "jp": "は、gpt3.5-turboとgpt-4の両方に対応したウェブサイト向けのchatgpt統合サービスです。", 48 | "zh": "是一项为网站提供ChatGPT集成的服务,支持gpt3.5-turbo和gpt-4。", 49 | "de": "ist ein Service, der ChatGPT-Integrationen für Websites für gpt3.5-turbo und gpt-4 anbietet.", 50 | "fr": "est un service offrant une intégration ChatGPT pour les sites web, tant pour gpt3.5-turbo que pour gpt-4.", 51 | "ru": "это сервис, предлагающий интеграцию ChatGPT для веб-сайтов как для gpt3.5-turbo, так и для gpt-4.", 52 | "pt": "é um serviço que oferece integração do ChatGPT para websites tanto para gpt3.5-turbo como para gpt-4.", 53 | "it": "è un servizio che offre l'integrazione di ChatGPT per siti web sia per gpt3.5-turbo che per gpt-4.", 54 | "nl": "is een service die chatgpt-integratie aanbiedt voor websites voor zowel gpt3.5-turbo als gpt-4." 55 | }, 56 | "url": "end", 57 | "key": "end", 58 | "available_model": [ 59 | "gpt-3.5-turbo", 60 | "gpt-4" 61 | ] 62 | }, 63 | "churchless": { 64 | "thanks so much!": "https://github.com/acheong08", 65 | "name": "Churchless", 66 | "description": { 67 | "es": "es un acceso directo a ChatGPT que ofrece privacidad.", 68 | "ar": "هو وصول مباشر إلى ChatGPT يوفر الخصوصية.", 69 | "en": "is a direct access to ChatGPT offering privacy.", 70 | "jp": "プライバシーを提供するChatGPTへの直接アクセスです。", 71 | "zh": "是一个直接访问ChatGPT并提供隐私的服务。", 72 | "de": "ist ein direkter Zugang zu ChatGPT mit Datenschutz.", 73 | "fr": "est un accès direct à ChatGPT offrant une confidentialité.", 74 | "ru": "представляет собой прямой доступ к ChatGPT с обеспечением конфиденциальности.", 75 | "pt": "é um acesso direto ao ChatGPT oferecendo privacidade.", 76 | "it": "è un accesso diretto a ChatGPT che offre privacy.", 77 | "nl": "is een directe toegang tot ChatGPT die privacy biedt." 78 | }, 79 | "url": "https://free.churchless.tech/v1", 80 | "key": "MyDiscord", 81 | "api_max_tokens": "8192", 82 | "available_model": [ 83 | "gpt-3.5-turbo" 84 | ] 85 | }, 86 | "stablehorde": { 87 | "name": "StableHorde", 88 | "description": { 89 | "es": "Convierte palabras en arte con diferentes estilos y ajustes creativos en una biblioteca en constante crecimiento.", 90 | "ar": "حوّل الكلمات إلى فن مع أنماط وإعدادات إبداعية مختلفة في مكتبة متزايدة باستمرار.", 91 | "en": "Turn words into art with different styles and creative adjustments in a constantly growing library.", 92 | "jp": "常に成長するライブラリで、さまざまなスタイルやクリエイティブな調整で単語をアートに変換します。", 93 | "zh": "在不断增长的库中,使用不同的风格和创意调整将单词转化为艺术。", 94 | "de": "Verwandeln Sie Worte mit verschiedenen Stilen und kreativen Anpassungen in einer ständig wachsenden Bibliothek in Kunst.", 95 | "fr": "Transformez des mots en art avec différents styles et ajustements créatifs dans une bibliothèque en constante croissance.", 96 | "ru": "Превращайте слова в искусство с различными стилями и творческими настройками в постоянно растущей библиотеке.", 97 | "pt": "Transforme palavras em arte com diferentes estilos e ajustes criativos em uma biblioteca em constante crescimento.", 98 | "it": "Trasforma le parole in arte con diversi stili e regolazioni creative in una biblioteca in costante crescita.", 99 | "nl": "Verander woorden in kunst met verschillende stijlen en creatieve aanpassingen in een voortdurend groeiende bibliotheek." 100 | }, 101 | "key": "0000000000" 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /config/openai_completion_options.example.json: -------------------------------------------------------------------------------- 1 | { 2 | "temperature": 1, 3 | "top_p": 0.5, 4 | "frequency_penalty": 0, 5 | "presence_penalty": 0 6 | } -------------------------------------------------------------------------------- /docker-compose.example.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | mongo: 5 | container_name: mongo 6 | image: mongo:4.4.18 7 | restart: always 8 | environment: 9 | - MONGO_INITDB_ROOT_USERNAME=root 10 | - MONGO_INITDB_ROOT_PASSWORD=GDT9MbJUTFHpyJyeS2JxzgkpYTjnrU8v 11 | command: mongod --port ${MONGODB_PORT:-27017} 12 | ports: 13 | - 27017 14 | 15 | chatgptg: 16 | container_name: chatgptg 17 | stdin_open: true 18 | tty: true 19 | command: python3 -m bot 20 | restart: always 21 | build: 22 | context: . 23 | dockerfile: Dockerfile 24 | environment: 25 | # check https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables for more 26 | - MONGODB_HOST=mongo 27 | - MONGODB_USERNAME=root 28 | - MONGODB_PASSWORD=GDT9MbJUTFHpyJyeS2JxzgkpYTjnrU8v 29 | 30 | - TELEGRAM_TOKEN=6101..... 31 | # volumes: 32 | # - /route/my_config_dir:/config:ro 33 | # - /route/my_code_dir:/bot:ro 34 | # - /route/my_database_dir:/database:rw 35 | -------------------------------------------------------------------------------- /docker-compose.no-mongodb.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | chatgptg: 5 | container_name: chatgptg 6 | stdin_open: true 7 | tty: true 8 | command: python3 -m bot 9 | restart: always 10 | build: 11 | context: . 12 | dockerfile: Dockerfile 13 | environment: 14 | # check https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables for more 15 | - WITHOUT_MONGODB=True 16 | - TELEGRAM_TOKEN=6101..... 17 | # volumes: 18 | # - /route/my_config_dir:/config:ro 19 | # - /route/my_code_dir:/bot:ro 20 | # - /route/my_database_dir:/database:rw 21 | -------------------------------------------------------------------------------- /docs/readme/ar.md: -------------------------------------------------------------------------------- 1 | - الروبوت: https://t.me/chismegptbpt 2 | 3 | [![ar](https://img.shields.io/badge/المتغيرات-ar-red)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables/ar.md) 4 | 5 | ## الأوامر: 6 | - /new - بدء حوار جديد. 7 | - /img - إنشاء صور. 8 | - /retry - إعادة إنشاء آخر رد من الروبوت. 9 | - /chat_mode - تحديد وضع المحادثة. 10 | - /model - عرض نماذج الذكاء الاصطناعي. 11 | - /api - عرض واجهات برمجة التطبيقات. 12 | - /lang - عرض اللغات المتاحة. 13 | - /status - عرض الإعدادات الحالية: النموذج، وضع المحادثة، واجهة برمجة التطبيقات. 14 | - /reset - إعادة تعيين الإعدادات إلى القيم الافتراضية. 15 | - /search - البحث على الإنترنت 16 | - /help – عرض هذه الرسالة مرة أخرى. 17 | 18 | ## الميزات: 19 | - استدعاء الوظائف! (الوصلات المتصلة مباشرة بـ GPT، نماذج شهر يونيو>). 20 | - قاعدة بيانات JSON محلية. 21 | - قابلية التعديل والتخصيص بشكل كبير. 22 | - اجعل GPT يستخدم الإنترنت باستخدام /search! 23 | - أرسل ملف نصي أو PDF أو عنوان URL وسيتمكن الروبوت من تحليلها! 24 | - أضف بروكسيات عكسية لـ OpenAI ونماذجها المقابلة بقدر ما تريد! 25 | - متعدد اللغات. 26 | - قراءة نص الصور. 27 | - نص الصوت. 28 | 29 | # مهم: 30 | - يجب أن تتبع واجهات برمجة التطبيقات المخصصة نفس هيكل OpenAI، أي "https://domain.dom/v1/..." 31 | 32 | ## الإعداد 33 | 1. احصل على مفتاحك من [OpenAI API](https://openai.com/api/) 34 | 35 | 2. احصل على رمز الروبوت الخاص بك من [@BotFather](https://t.me/BotFather) 36 | 37 | 3. قم بتعديل `config/api.example.json` لتكوين مفتاح API الخاص بك أو إضافة واجهات برمجة تطبيقات مخصصة 38 | 39 | 4. أضف رمز Telegram الخاص بك، وقاعدة بيانات Mongo، وقم بتعديل متغيرات أخرى في 'docker-compose.example.yml' وقم بإعادة تسمية `docker-compose.example.yml` إلى `docker-compose.yml` 40 | 41 | 5. 🔥 قم بالوصول إلى الدليل من خلال الطرفية و**قم بتشغيل**: 42 | ```bash 43 | docker-compose up --build 44 | ``` 45 | # سجل النجوم 46 | 47 | Star History Chart 48 | 49 | ## المراجع 50 | 1. المصدر: Karfly/chatgpt_telegram_bot -------------------------------------------------------------------------------- /docs/readme/de.md: -------------------------------------------------------------------------------- 1 | - Bot: https://t.me/chismegptbpt 2 | 3 | [![de](https://img.shields.io/badge/Variablen-de-blue)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables/de.md) 4 | 5 | ## Befehle: 6 | - /new - Starten Sie einen neuen Dialog. 7 | - /img - Generieren Sie Bilder. 8 | - /retry - Generieren Sie die letzte Antwort des Bots erneut. 9 | - /chat_mode - Wählen Sie den Chat-Modus aus. 10 | - /model - Zeigen Sie KI-Modelle an. 11 | - /api - Zeigen Sie APIs an. 12 | - /lang - Verfügbar Sprachen anzeigen. 13 | - /status - Aktuelle Konfiguration anzeigen: Modell, Chat-Modus und API. 14 | - /reset - Setzen Sie die Konfiguration auf die Standardeinstellungen zurück. 15 | - /search - Suche im Internet 16 | - /help - Zeigen Sie diese Nachricht erneut an. 17 | 18 | ## Eigenschaften: 19 | - Aufruf von Funktionen! (Plugins direkt mit GPT verbunden, Modelle ab Juni>). 20 | - Lokale JSON-Datenbank. 21 | - Sehr modular und anpassbar. 22 | - Lassen Sie GPT mit /search auf das Internet zugreifen! 23 | - Senden Sie eine Textdatei, PDF oder URL, und der Bot kann sie analysieren! 24 | - Fügen Sie Reverse-Proxies von OpenAI und ihren entsprechenden Modellen hinzu, so viele Sie möchten! 25 | - Mehrsprachig. 26 | - Liest den Text von Bildern. 27 | - Transkribiert Audios. 28 | 29 | # Wichtig: 30 | - Benutzerdefinierte APIs müssen der gleichen Struktur wie OpenAI folgen, d.h. "https://domain.dom/v1/..." 31 | 32 | ## Einrichtung 33 | 1. Holen Sie sich Ihren Schlüssel von [OpenAI API](https://openai.com/api/) 34 | 35 | 2. Holen Sie sich Ihren Telegramm-Bot-Token von [@BotFather](https://t.me/BotFather) 36 | 37 | 3. Bearbeiten Sie `config/api.example.json`, um Ihren API-Schlüssel zu konfigurieren oder benutzerdefinierte APIs hinzuzufügen 38 | 39 | 4. Fügen Sie Ihren Telegramm-Token, Ihre MongoDB-Datenbank hinzu und ändern Sie andere Variablen in 'docker-compose.example.yml' und benennen Sie `docker-compose.example.yml` in `docker-compose.yml` um 40 | 41 | 5. 🔥 Gehen Sie über das Terminal zum Verzeichnis und **führen Sie** aus: 42 | ```bash 43 | docker-compose up --build 44 | ``` 45 | # Sterneverlauf 46 | 47 | Star History Chart 48 | 49 | ## Referenzen 50 | 1. Ursprung: Karfly/chatgpt_telegram_bot -------------------------------------------------------------------------------- /docs/readme/en.md: -------------------------------------------------------------------------------- 1 | - Bot: https://t.me/chismegptbpt 2 | 3 | [![en](https://img.shields.io/badge/Variables-en-brightgreen)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables/en.md) 4 | 5 | ## Commands: 6 | - /new - Start a new dialogue. 7 | - /img - Generate images. 8 | - /retry - Regenerate the bot's last response. 9 | - /chat_mode - Select the chat mode. 10 | - /model - Show AI models. 11 | - /api - Show APIs. 12 | - /lang - View available languages. 13 | - /status - View current configuration: Model, Chat mode, and API. 14 | - /reset - Reset configuration to default values. 15 | - /search - Search on the internet. 16 | - /help - Show this message again. 17 | 18 | ## Features: 19 | - Function calls! (plugins connected directly to GPT, June models>). 20 | - Local JSON database. 21 | - Highly modular and customizable. 22 | - Make GPT access the internet using /search! 23 | - Send a text file, PDF, or URL and the bot will analyze them! 24 | - Add reverse proxies from OpenAI and their respective models as much as you want! 25 | - Multi-language. 26 | - Read text from images. 27 | - Transcribe audios. 28 | 29 | # Important: 30 | - Custom APIs must follow the same structure as OpenAI, i.e., "https://domain.dom/v1/..." 31 | 32 | ## Setup 33 | 1. Get your [OpenAI API](https://openai.com/api/) key. 34 | 35 | 2. Get your Telegram bot token from [@BotFather](https://t.me/BotFather). 36 | 37 | 3. Edit `config/api.example.json` to configure your API key or add custom APIs. 38 | 39 | 4. Add your Telegram token, MongoDB database, modify other variables in 'docker-compose.example.yml', and rename `docker-compose.example.yml` to `docker-compose.yml`. 40 | 41 | 5. 🔥 Access the directory from the terminal and **run**: 42 | ```bash 43 | docker-compose up --build 44 | ``` 45 | # Star History 46 | 47 | Star History Chart 48 | 49 | ## References 50 | 1. Original: Karfly/chatgpt_telegram_bot -------------------------------------------------------------------------------- /docs/readme/es.md: -------------------------------------------------------------------------------- 1 | - Bot: https://t.me/chismegptbpt 2 | 3 | [![es](https://img.shields.io/badge/Variables-es-yellow)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables/es.md) 4 | 5 | ## Comandos: 6 | - /new - Iniciar nuevo diálogo. 7 | - /img - Generar imagenes. 8 | - /retry - Regenera la última respuesta del bot. 9 | - /chat_mode - Seleccionar el modo de conversación. 10 | - /model - Mostrar modelos IA. 11 | - /api - Mostrar APIs. 12 | - /lang - Ver idiomas disponibles. 13 | - /status - Ver la configuracion actual: Modelo, Modo de chat y API. 14 | - /reset - Reestablece la configuración a valores predeterminados. 15 | - /search - Busqueda en internet 16 | - /help – Mostrar este mensaje de nuevo. 17 | 18 | ## Características: 19 | - Llamada a funciones! (plugins conectados directamente a GPT, modelos del mes de Junio>). 20 | - Base de datos JSON local. 21 | - Muy modular y personalizable. 22 | - Haz que GPT acceda a Internet usando /search! 23 | - Envía un archivo de texto, PDF o URL y el bot los podrá analizar! 24 | - Añade proxies reversos de OpenAI y sus respectivos modelos cuanto quieras! 25 | - Multi lenguaje. 26 | - Lee el texto de imágenes. 27 | - Transcribe audios. 28 | 29 | # Importante: 30 | - Las API personalizadas deben seguir la misma estructura de OpenAI, es decir, el "https://dominio.dom/v1/..." 31 | 32 | ## Setup 33 | 1. Obtén tu clave de [OpenAI API](https://openai.com/api/) 34 | 35 | 2. Obtén tu token de bot de Telegram de [@BotFather](https://t.me/BotFather) 36 | 37 | 3. Edita `config/api.example.json` para configurar tu API-KEY o añadir apis personalizadas 38 | 39 | 4. Añade tu token de telegram, base de datos Mongo, modifica otras variables en 'docker-compose.example.yml' y renombra `docker-compose.example.yml` a `docker-compose.yml` 40 | 41 | 5. 🔥 Accede al directorio desde la terminal y **ejecuta**: 42 | ```bash 43 | docker-compose up --build 44 | ``` 45 | # Historial de estrellas 46 | 47 | Star History Chart 48 | 49 | ## Referencias 50 | 1. Origen: Karfly/chatgpt_telegram_bot 51 | -------------------------------------------------------------------------------- /docs/readme/fr.md: -------------------------------------------------------------------------------- 1 | - Bot: https://t.me/chismegptbpt 2 | 3 | [![fr](https://img.shields.io/badge/Variables-fr-brightgreen)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables/fr.md) 4 | 5 | ## Commandes: 6 | - /new - Démarrer une nouvelle conversation. 7 | - /img - Générer des images. 8 | - /retry - Régénère la dernière réponse du bot. 9 | - /chat_mode - Sélectionner le mode de conversation. 10 | - /model - Afficher les modèles d'IA. 11 | - /api - Afficher les APIs. 12 | - /lang - Voir les langues disponibles. 13 | - /status - Voir la configuration actuelle : Modèle, Mode de conversation et API. 14 | - /reset - Rétablir la configuration par défaut. 15 | - /search - Recherche sur Internet. 16 | - /help - Afficher ce message à nouveau. 17 | 18 | ## Caractéristiques: 19 | - Appel de fonctions ! (plugins connectés directement à GPT, modèles de juin>). 20 | - Base de données JSON locale. 21 | - Très modulaire et personnalisable. 22 | - Permet à GPT d'accéder à Internet en utilisant /search ! 23 | - Envoyez un fichier texte, PDF ou une URL et le bot pourra les analyser ! 24 | - Ajoutez des proxies inverses d'OpenAI et leurs modèles respectifs autant que vous le souhaitez ! 25 | - Multilingue. 26 | - Lit le texte des images. 27 | - Transcrit les fichiers audio. 28 | 29 | # Important: 30 | - Les APIs personnalisées doivent suivre la même structure qu'OpenAI, c'est-à-dire "https://domaine.dom/v1/..." 31 | 32 | ## Configuration 33 | 1. Obtenez votre clé d'API [OpenAI](https://openai.com/api/) 34 | 35 | 2. Obtenez votre jeton de bot Telegram auprès de [@BotFather](https://t.me/BotFather) 36 | 37 | 3. Modifiez `config/api.example.json` pour configurer votre API-KEY ou ajouter des APIs personnalisées 38 | 39 | 4. Ajoutez votre jeton Telegram, votre base de données Mongo, modifiez d'autres variables dans 'docker-compose.example.yml' et renommez `docker-compose.example.yml` en `docker-compose.yml` 40 | 41 | 5. 🔥 Accédez au répertoire depuis le terminal et **exécutez** : 42 | ```bash 43 | docker-compose up --build 44 | ``` 45 | # Historique des étoiles 46 | 47 | Star History Chart 48 | 49 | ## Références 50 | 1. Source : Karfly/chatgpt_telegram_bot -------------------------------------------------------------------------------- /docs/readme/it.md: -------------------------------------------------------------------------------- 1 | - Bot: https://t.me/chismegptbpt 2 | 3 | [![it](https://img.shields.io/badge/Variabili-it-yellow)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables/it.md) 4 | 5 | ## Comandi: 6 | - /new - Avvia una nuova conversazione. 7 | - /img - Genera immagini. 8 | - /retry - Rigenera l'ultima risposta del bot. 9 | - /chat_mode - Seleziona la modalità di conversazione. 10 | - /model - Mostra i modelli di IA disponibili. 11 | - /api - Mostra le API disponibili. 12 | - /lang - Visualizza le lingue disponibili. 13 | - /status - Visualizza la configurazione attuale: Modello, Modalità di chat e API. 14 | - /reset - Ripristina la configurazione ai valori predefiniti. 15 | - /search - Ricerca su Internet. 16 | - /help - Mostra nuovamente questo messaggio. 17 | 18 | ## Caratteristiche: 19 | - Chiamata a funzioni! (plugin collegati direttamente a GPT, modelli di giugno>). 20 | - Database JSON locale. 21 | - Estremamente modulare e personalizzabile. 22 | - Permette a GPT di accedere a Internet utilizzando /search! 23 | - Invia un file di testo, PDF o URL e il bot sarà in grado di analizzarlo! 24 | - Aggiungi proxy inversi di OpenAI e relativi modelli a volontà! 25 | - Multilingue. 26 | - Legge il testo dalle immagini. 27 | - Trascrive gli audio. 28 | 29 | # Importante: 30 | - Le API personalizzate devono seguire la stessa struttura di OpenAI, cioè "https://dominio.dom/v1/..." 31 | 32 | ## Configurazione 33 | 1. Ottieni la tua chiave API da [OpenAI API](https://openai.com/api/) 34 | 35 | 2. Ottieni il token del tuo bot Telegram da [@BotFather](https://t.me/BotFather) 36 | 37 | 3. Modifica `config/api.example.json` per configurare la tua API-KEY o aggiungere API personalizzate 38 | 39 | 4. Aggiungi il tuo token Telegram, il database Mongo, modifica altre variabili in 'docker-compose.example.yml' e rinomina `docker-compose.example.yml` in `docker-compose.yml` 40 | 41 | 5. 🔥 Accedi alla directory tramite terminale ed **esegui**: 42 | ```bash 43 | docker-compose up --build 44 | ``` 45 | # Cronologia delle stelle 46 | 47 | Star History Chart 48 | 49 | ## Riferimenti 50 | 1. Origine: Karfly/chatgpt_telegram_bot -------------------------------------------------------------------------------- /docs/readme/jp.md: -------------------------------------------------------------------------------- 1 | - ボット:https://t.me/chismegptbpt 2 | 3 | [![jp](https://img.shields.io/badge/変数-jp-blueviolet)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables/jp.md) 4 | 5 | ## コマンド: 6 | - /new - 新しい対話を開始します。 7 | - /img - 画像を生成します。 8 | - /retry - ボットの最後の応答を再生成します。 9 | - /chat_mode - チャットモードを選択します。 10 | - /model - AIモデルを表示します。 11 | - /api - APIを表示します。 12 | - /lang - 利用可能な言語を表示します。 13 | - /status - 現在の設定を表示します:モデル、チャットモード、API。 14 | - /reset - 設定をデフォルト値にリセットします。 15 | - /search - インターネットで検索します。 16 | - /help - このメッセージを再表示します。 17 | 18 | ## 特徴: 19 | - 関数の呼び出し!(直接GPTに接続されたプラグイン、6月のモデル>)。 20 | - ローカルのJSONデータベース。 21 | - 非常にモジュラーでカスタマイズ可能。 22 | - /searchを使用してGPTがインターネットにアクセスできるようにします! 23 | - テキストファイル、PDF、またはURLを送信して、ボットがそれらを分析できます! 24 | - 必要に応じてOpenAIの逆プロキシとそれに対応するモデルを追加できます! 25 | - マルチ言語対応。 26 | - 画像のテキストを読み取ります。 27 | - 音声を転写します。 28 | 29 | # 重要: 30 | - カスタムAPIは、OpenAIと同じ構造に従う必要があります。つまり、「https://dominio.dom/v1/...」です。 31 | 32 | ## セットアップ 33 | 1. [OpenAI API](https://openai.com/api/)からAPIキーを取得します。 34 | 35 | 2. Telegramのボットトークンを[@BotFather](https://t.me/BotFather)から取得します。 36 | 37 | 3. `config/api.example.json`を編集してAPIキーを設定するか、カスタムAPIを追加します。 38 | 39 | 4. Telegramのトークン、Mongoデータベース、その他の変数を`docker-compose.example.yml`で変更し、`docker-compose.example.yml`を`docker-compose.yml`に名前を変更します。 40 | 41 | 5. 🔥 ターミナルからディレクトリにアクセスし、**実行**します: 42 | ```bash 43 | docker-compose up --build 44 | ``` 45 | # スターの履歴 46 | 47 | Star History Chart 48 | 49 | ## 参考文献 50 | 1. 元のソースコード:Karfly/chatgpt_telegram_bot -------------------------------------------------------------------------------- /docs/readme/nl.md: -------------------------------------------------------------------------------- 1 | - Bot: https://t.me/chismegptbpt 2 | 3 | [![nl](https://img.shields.io/badge/Variabelen-nl-red)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables/nl.md) 4 | 5 | ## Opdrachten: 6 | - /new - Start een nieuw gesprek. 7 | - /img - Genereer afbeeldingen. 8 | - /retry - Genereer het laatste antwoord opnieuw. 9 | - /chat_mode - Selecteer de gespreksmodus. 10 | - /model - Toon AI-modellen. 11 | - /api - Toon API's. 12 | - /lang - Bekijk beschikbare talen. 13 | - /status - Bekijk de huidige configuratie: Model, Chatmodus en API. 14 | - /reset - Herstel de instellingen naar de standaardwaarden. 15 | - /search - Zoek op internet. 16 | - /help - Toon dit bericht opnieuw. 17 | 18 | ## Kenmerken: 19 | - Functieoproepen! (plugins direct verbonden met GPT, modellen van juni>). 20 | - Lokale JSON-database. 21 | - Zeer modulair en aanpasbaar. 22 | - Laat GPT toegang krijgen tot internet met /search! 23 | - Stuur een tekstbestand, PDF of URL en de bot kan ze analyseren! 24 | - Voeg zoveel omgekeerde proxies van OpenAI toe als je wilt! 25 | - Meertalig. 26 | - Lees tekst van afbeeldingen. 27 | - Transcribeer audio. 28 | 29 | # Belangrijk: 30 | - Aangepaste API's moeten dezelfde structuur volgen als OpenAI, dwz "https://domain.dom/v1/..." 31 | 32 | ## Installatie 33 | 1. Verkrijg uw [OpenAI API-sleutel](https://openai.com/api/) 34 | 35 | 2. Verkrijg uw Telegram-bot-token van [@BotFather](https://t.me/BotFather) 36 | 37 | 3. Bewerk `config/api.example.json` om uw API-KEY te configureren of aangepaste API's toe te voegen 38 | 39 | 4. Voeg uw Telegram-token toe, MongoDB-database, wijzig andere variabelen in 'docker-compose.example.yml' en hernoem `docker-compose.example.yml` naar `docker-compose.yml` 40 | 41 | 5. 🔥 Ga naar de map in de terminal en **voer uit**: 42 | ```bash 43 | docker-compose up --build 44 | ``` 45 | # Stergeschiedenis 46 | 47 | Star History Chart 48 | 49 | ## Referenties 50 | 1. Oorsprong: Karfly/chatgpt_telegram_bot -------------------------------------------------------------------------------- /docs/readme/pt.md: -------------------------------------------------------------------------------- 1 | - Bot: https://t.me/chismegptbpt 2 | 3 | [![pt](https://img.shields.io/badge/Variáveis-pt-brightgreen)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables/pt.md) 4 | 5 | ## Comandos: 6 | - /new - Iniciar novo diálogo. 7 | - /img - Gerar imagens. 8 | - /retry - Regenerar a última resposta do bot. 9 | - /chat_mode - Selecionar o modo de conversação. 10 | - /model - Mostrar modelos de IA. 11 | - /api - Mostrar APIs. 12 | - /lang - Ver idiomas disponíveis. 13 | - /status - Ver a configuração atual: Modelo, Modo de chat e API. 14 | - /reset - Restaurar a configuração para os valores padrão. 15 | - /search - Pesquisar na internet. 16 | - /help - Mostrar esta mensagem novamente. 17 | 18 | ## Características: 19 | - Chamada de funções! (plugins conectados diretamente ao GPT, modelos de junho>). 20 | - Banco de dados JSON local. 21 | - Muito modular e personalizável. 22 | - Faça o GPT acessar a internet usando /search! 23 | - Envie um arquivo de texto, PDF ou URL e o bot poderá analisá-los! 24 | - Adicione proxies reversos da OpenAI e seus respectivos modelos quantas vezes quiser! 25 | - Multilíngue. 26 | - Leia o texto de imagens. 27 | - Transcreva áudios. 28 | 29 | # Importante: 30 | - As APIs personalizadas devem seguir a mesma estrutura da OpenAI, ou seja, "https://dominio.dom/v1/..." 31 | 32 | ## Configuração 33 | 1. Obtenha sua chave da [OpenAI API](https://openai.com/api/) 34 | 35 | 2. Obtenha o token do seu bot do Telegram com [@BotFather](https://t.me/BotFather) 36 | 37 | 3. Edite `config/api.example.json` para configurar sua API-KEY ou adicionar APIs personalizadas 38 | 39 | 4. Adicione seu token do Telegram, banco de dados Mongo, modifique outras variáveis no arquivo 'docker-compose.example.yml' e renomeie `docker-compose.example.yml` para `docker-compose.yml` 40 | 41 | 5. 🔥 Acesse o diretório pelo terminal e **execute**: 42 | ```bash 43 | docker-compose up --build 44 | ``` 45 | # Histórico de estrelas 46 | 47 | Star History Chart 48 | 49 | ## Referências 50 | 1. Origem: Karfly/chatgpt_telegram_bot -------------------------------------------------------------------------------- /docs/readme/ru.md: -------------------------------------------------------------------------------- 1 | - Бот: https://t.me/chismegptbpt 2 | 3 | [![ru](https://img.shields.io/badge/Переменные-ru-blue)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables/ru.md) 4 | 5 | ## Команды: 6 | - /new - Начать новый диалог. 7 | - /img - Создать изображения. 8 | - /retry - Повторить последний ответ бота. 9 | - /chat_mode - Выбрать режим разговора. 10 | - /model - Показать модели ИИ. 11 | - /api - Показать API. 12 | - /lang - Показать доступные языки. 13 | - /status - Показать текущую конфигурацию: Модель, Режим чата и API. 14 | - /reset - Сбросить настройки на значения по умолчанию. 15 | - /search - Поиск в интернете. 16 | - /help - Показать это сообщение снова. 17 | 18 | ## Особенности: 19 | - Вызов функций! (плагины, прямо подключенные к GPT, модели за июнь>). 20 | - Локальная база данных JSON. 21 | - Очень модульный и настраиваемый. 22 | - Позволяет GPT получать доступ к Интернету с помощью /search! 23 | - Отправляйте текстовые файлы, PDF или URL, и бот сможет их проанализировать! 24 | - Добавляйте обратные прокси от OpenAI и соответствующие модели сколько угодно! 25 | - Мультиязычность. 26 | - Чтение текста с изображений. 27 | - Транскрибация аудио. 28 | 29 | # Важно: 30 | - Пользовательские API должны иметь ту же структуру, что и OpenAI, то есть "https://domain.dom/v1/..." 31 | 32 | ## Установка 33 | 1. Получите свой ключ [OpenAI API](https://openai.com/api/) 34 | 35 | 2. Получите токен вашего бота в Telegram от [@BotFather](https://t.me/BotFather) 36 | 37 | 3. Отредактируйте `config/api.example.json`, чтобы настроить ваш API-KEY или добавить пользовательские API 38 | 39 | 4. Добавьте ваш токен Telegram, базу данных Mongo, измените другие переменные в 'docker-compose.example.yml' и переименуйте `docker-compose.example.yml` в `docker-compose.yml` 40 | 41 | 5. 🔥 Зайдите в каталог через терминал и **выполните**: 42 | ```bash 43 | docker-compose up --build 44 | ``` 45 | # История звезд 46 | 47 | Star History Chart 48 | 49 | ## Ссылки 50 | 1. Источник: Karfly/chatgpt_telegram_bot -------------------------------------------------------------------------------- /docs/readme/zh.md: -------------------------------------------------------------------------------- 1 | - 机器人:https://t.me/chismegptbpt 2 | 3 | [![zh](https://img.shields.io/badge/变量-zh-orange)](https://gg.resisto.rodeo/yo/chatgpTG/src/branch/main/docs/variables/zh.md) 4 | 5 | ## 命令: 6 | - /new - 开始新对话。 7 | - /img - 生成图片。 8 | - /retry - 重新生成上一次机器人的回答。 9 | - /chat_mode - 选择对话模式。 10 | - /model - 显示AI模型。 11 | - /api - 显示API。 12 | - /lang - 查看可用语言。 13 | - /status - 查看当前配置:模型、对话模式和API。 14 | - /reset - 将配置恢复为默认值。 15 | - /search - 在互联网上搜索。 16 | - /help - 再次显示此消息。 17 | 18 | ## 特点: 19 | - 调用函数!(直接连接到GPT的插件,6月份的模型>)。 20 | - 本地JSON数据库。 21 | - 非常模块化和可定制。 22 | - 使用/search命令让GPT访问互联网! 23 | - 发送文本文件、PDF或URL,机器人可以分析它们! 24 | - 添加任意数量的OpenAI反向代理和相应的模型! 25 | - 多语言支持。 26 | - 读取图像中的文本。 27 | - 转录音频。 28 | 29 | # 重要提示: 30 | - 自定义API必须遵循OpenAI的相同结构,即 "https://domain.dom/v1/..."。 31 | 32 | ## 设置 33 | 1. 获取你的[OpenAI API](https://openai.com/api/)密钥。 34 | 35 | 2. 获取你的Telegram机器人令牌,可以在[@BotFather](https://t.me/BotFather)处获取。 36 | 37 | 3. 编辑 `config/api.example.json` 文件,配置你的API-KEY或添加自定义API。 38 | 39 | 4. 添加你的Telegram令牌、Mongo数据库,修改`docker-compose.example.yml`中的其他变量,并将`docker-compose.example.yml`重命名为`docker-compose.yml`。 40 | 41 | 5. 🔥 从终端进入目录并**运行**: 42 | ```bash 43 | docker-compose up --build 44 | ``` 45 | # 星星历史记录 46 | 47 | Star History Chart 48 | 49 | ## 参考资料 50 | 1. 来源:Karfly/chatgpt_telegram_bot -------------------------------------------------------------------------------- /docs/variables/ar.md: -------------------------------------------------------------------------------- 1 | ## التكوين 2 | 3 | ### رمز تلغرام 4 | 5 | لاستخدام الروبوت في تلغرام ، تحتاج إلى توفير رمز تلغرام. يمكن الحصول على هذا الرمز عن طريق إنشاء روبوت عبر `https://t.me/botfather`. يجب تخزين الرمز في المتغير `TELEGRAM_TOKEN`. 6 | 7 | ### تكوين القائمة 8 | 9 | يمكن تكوين قائمة الروبوت باستخدام الخيارات التالية: 10 | 11 | - `MAX_ITEMS_PER_PAGE`: الحد الأقصى لعدد العناصر المعروضة في كل صفحة في القائمة. الافتراضي هو 10. 12 | - `MAX_COLUMNS_PER_PAGE`: الحد الأقصى لعدد الأعمدة المعروضة في كل صفحة في القائمة. الافتراضي هو 2. 13 | 14 | ### القائمة البيضاء للمستخدمين والدردشة 15 | 16 | يمكنك تحديد قائمة بيضاء للمستخدمين والدردشة المسموح لهم بالتفاعل مع الروبوت. يجب توفير القائمة البيضاء كقائمة من معرفات المستخدم أو المحادثة في المتغيرات `USER_WHITELIST` على التوالي. 17 | 18 | ### تكوين قاعدة البيانات 19 | 20 | يدعم الروبوت خيارات قاعدة بيانات MongoDB و JSON. بشكل افتراضي ، يستخدم قاعدة بيانات Mongo. لاستخدام قاعدة بيانات JSON ، قم بتعيين المتغير `WITHOUT_MONGODB` إلى `True`. 21 | 22 | ### مهلة الحوار 23 | 24 | يحتوي الروبوت على ميزة مهلة الحوار ، والتي تنهي تلقائيًا المحادثة إذا لم يكن هناك أي نشاط لفترة زمنية معينة. يمكن تكوين مدة المهلة باستخدام المتغير `DIALOG_TIMEOUT`. المهلة الافتراضية هي 7200 ثانية (2 ساعة). 25 | 26 | ### إنشاء الصور 27 | 28 | يدعم الروبوت إنشاء الصور بناءً على إدخال المستخدم. لتعطيل هذه الميزة ، قم بتعيين المتغير `FEATURE_IMAGE_GENERATION` إلى `False`. 29 | 30 | يمكن تكوين عدد الصور المراد إنشاؤها باستخدام المتغير `OUTPUT_IMAGES`. الافتراضي هو 4 صور. 31 | 32 | تحتوي الصور المنشأة على وقت انتهاء صلاحية بعد انقضاءه يتم حذفها من ذاكرة الروبوت. يمكن تكوين وقت انتهاء الصلاحية باستخدام المتغير `GENERATED_IMAGE_EXPIRATION_MINUTES`. الوقت الافتراضي لانتهاء الصلاحية هو 5 دقائق. 33 | 34 | ### الرد المباشر لعناوين URL 35 | 36 | بشكل افتراضي ، يجيب الروبوت بعد إرسال عنوان URL للقراءة. لتعطيل هذا والانتظار لإدخال المستخدم بعد معالجة عنوان URL ، قم بتعيين المتغير `URL_DIRECT_RESPONSE` إلى `False`. 37 | 38 | ### الإجابات المباشرة 39 | 40 | يجيب الروبوت بإجابات مباشرة ، مما يسمح بإخراج مستمر للنتائج. لتعطيل هذه الميزة ، قم بتعيين المتغير `STREAM_ANSWERS` إلى `False`. 41 | 42 | ### استدعاءات الوظائف 43 | 44 | يدعم الروبوت استدعاءات وظائف OpenAI الجديدة. لتعطيل هذه الميزة ، قم بتعيين المتغير `FEATURE_FUNCTION_CALLS` إلى `False`. 45 | 46 | ### مهلة السؤال 47 | 48 | يحتوي الروبوت على ميزة لطرح سؤال حول ما إذا كان يجب متابعة المحادثة أم بدء محادثة جديدة. إذا تم تعطيله ، سيقوم الروبوت تلقائيًا بإزالة المحادثة المهلة وبدء محادثة جديدة. لتعطيل هذه الميزة ، قم بتعيين المتغير `TIMEOUT_ASK` إلى `False`. 49 | 50 | ### التسجيل الصوتي 51 | 52 | يدعم الروبوت تسجيل الملفات الصوتية. لتعطيل هذه الميزة ، قم بتعيين المتغير `FEATURE_TRANSCRIPTION` إلى `False`. 53 | 54 | ### التعرف الضوئي على الأحرف (OCR) 55 | 56 | يدعم الروبوت التعرف الضوئي على الأحرف لقراءة النص من الصور. لتعطيل هذه الميزة ، قم بتعيين المتغير `FEATURE_IMAGE_READ` إلى `False`. 57 | 58 | ### قراءة المستندات 59 | 60 | يدعم الروبوت قراءة المستندات. لتعطيل هذه الميزة ، قم بتعيين المتغير `FEATURE_DOCUMENT_READ` إلى `False`. 61 | 62 | ### البحث على الويب 63 | 64 | يدعم الروبوت وظيفة البحث على الويب. لتعطيل هذه الميزة ، قم بتعيين المتغير `FEATURE_BROWSING` إلى `False`. 65 | 66 | ### قراءة عناوين URL 67 | 68 | يدعم الروبوت قراءة محتوى عناوين URL. لتعطيل هذه الميزة ، قم بتعيين المتغير `FEATURE_URL_READ` إلى `False`. 69 | 70 | ### حدود الصوت وحجم الملف 71 | 72 | يحتوي الروبوت على حدود لحجم ملفات الصوت والمستندات التي يمكن معالجتها. يمكن تكوين الحد الأقصى لحجم ملف الصوت باستخدام المتغير `AUDIO_MAX_MB` (الافتراضي هو 20 ميجابايت) ، ويمكن تكوين الحد الأقصى لحجم ملف المستند باستخدام المتغير `DOC_MAX_MB` (الافتراضي هو 10 ميجابايت). 73 | 74 | ### حد حجم العنوان URL 75 | 76 | يحتوي الروبوت على حد لحجم عناوين URL التي يمكن معالجتها. يمكن تكوين الحد الأقصى لحجم العنوان URL باستخدام المتغير `URL_MAX_MB`. الحد الافتراضي هو 5 ميجابايت. 77 | 78 | ### إعادة المحاولات ومهلة الطلب 79 | 80 | يدعم الروبوت إعادة المحاولات في حالة الفشل. يمكن تكوين الحد الأقصى لعدد المحاولات باستخدام المتغير `REQUEST_MAX_RETRIES`. الافتراضي هو 3 محاولات. يمكن تكوين مدة مهلة الطلب باستخدام المتغير `REQUEST_TIMEOUT`. المهلة الافتراضية هي 10 ثوانٍ. 81 | 82 | ### حد الصفحة PDF 83 | 84 | عند قراءة مستندات PDF ، يحتوي الروبوت على حد لعدد الصفحات التي يمكن معالجتها. يمكن تكوين الحد الأقصى لعدد الصفحات باستخدام المتغير `PDF_PAGE_LIMIT`. الحد الافتراضي هو 25 صفحة. 85 | 86 | ### الكشف التلقائي عن اللغة 87 | 88 | يدعم الروبوت الكشف التلقائي للغة السياق والقوائم. يمكن تكوين اللغة الافتراضية للكشف التلقائي (إذا لم تكن لغة المستخدم مدعومة من قبل الروبوت) باستخدام المتغير `AUTO_LANG`. اللغة الافتراضية هي الإنجليزية (`en`). تُستخدم هذه اللغة الافتراضية لأخطاء الروبوت أو بعض رسائل التصحيح. 89 | 90 | ### دعم الوكيل 91 | 92 | يدعم الروبوت استخدام وكيل فقط لطلبات الواجهة البرمجية. لاستخدام وكيل ، قم بتوفير عنوان URL للوكيل في المتغير `API_TUNNEL` (على سبيل المثال `http://127.0.0.1:3128`). إذا لم يكن هناك حاجة لوكيل ، اترك هذا المتغير فارغًا. -------------------------------------------------------------------------------- /docs/variables/de.md: -------------------------------------------------------------------------------- 1 | ## Konfiguration 2 | 3 | ### Telegram-Token 4 | 5 | Um den Telegram-Bot zu verwenden, müssen Sie ein Telegram-Token bereitstellen. Dieses Token kann erhalten werden, indem Sie einen Bot über `https://t.me/botfather` erstellen. Das Token muss in der Variablen `TELEGRAM_TOKEN` gespeichert werden. 6 | 7 | ### Menükonfiguration 8 | 9 | Das Menü des Bots kann mit den folgenden Optionen konfiguriert werden: 10 | 11 | - `MAX_ITEMS_PER_PAGE`: Die maximale Anzahl von Elementen, die pro Seite im Menü angezeigt werden sollen. Standardmäßig sind es 10. 12 | - `MAX_COLUMNS_PER_PAGE`: Die maximale Anzahl von Spalten, die pro Seite im Menü angezeigt werden sollen. Standardmäßig sind es 2. 13 | 14 | ### Benutzer- und Chat-Whitelist 15 | 16 | Sie können eine Whitelist von Benutzern und Chats angeben, die mit dem Bot interagieren dürfen. Die Whitelist sollte als Liste von Benutzer- oder Chat-IDs in den Variablen `USER_WHITELIST` angegeben werden. 17 | 18 | ### Datenbankkonfiguration 19 | 20 | Der Bot unterstützt sowohl MongoDB- als auch JSON-Datenbankoptionen. Standardmäßig verwendet er die Mongo-Datenbank. Um die JSON-Datenbank zu verwenden, setzen Sie die Variable `WITHOUT_MONGODB` auf `True`. 21 | 22 | ### Dialog-Timeout 23 | 24 | Der Bot verfügt über eine Funktion zum Timeout von Dialogen, die ein Gespräch automatisch beendet, wenn für eine bestimmte Zeit keine Aktivität stattfindet. Die Timeout-Dauer kann mit der Variable `DIALOG_TIMEOUT` konfiguriert werden. Der Standard-Timeout beträgt 7200 Sekunden (2 Stunden). 25 | 26 | ### Bildgenerierung 27 | 28 | Der Bot unterstützt die Generierung von Bildern basierend auf Benutzereingaben. Um diese Funktion zu deaktivieren, setzen Sie die Variable `FEATURE_IMAGE_GENERATION` auf `False`. 29 | 30 | Die Anzahl der zu generierenden Bilder kann mit der Variable `OUTPUT_IMAGES` konfiguriert werden. Standardmäßig werden 4 Bilder generiert. 31 | 32 | Generierte Bilder haben eine Ablaufzeit, nach der sie aus dem Speicher des Bots gelöscht werden. Die Ablaufzeit kann mit der Variable `GENERATED_IMAGE_EXPIRATION_MINUTES` konfiguriert werden. Die Standard-Ablaufzeit beträgt 5 Minuten. 33 | 34 | ### Direkte Antwort auf URLs 35 | 36 | Standardmäßig antwortet der Bot, nachdem er eine URL zum Lesen gesendet hat. Um dies zu deaktivieren und auf die Benutzereingabe nach der Verarbeitung der URL zu warten, setzen Sie die Variable `URL_DIRECT_RESPONSE` auf `False`. 37 | 38 | ### Streaming-Antworten 39 | 40 | Der Bot antwortet mit Streaming-Antworten, die eine kontinuierliche Ausgabe von Ergebnissen ermöglichen. Um diese Funktion zu deaktivieren, setzen Sie die Variable `STREAM_ANSWERS` auf `False`. 41 | 42 | ### Funktionsaufrufe 43 | 44 | Der Bot unterstützt neue OpenAI-Funktionsaufrufe. Um diese Funktion zu deaktivieren, setzen Sie die Variable `FEATURE_FUNCTION_CALLS` auf `False`. 45 | 46 | ### Timeout-Frage 47 | 48 | Der Bot verfügt über eine Funktion, um zu fragen, ob das Gespräch fortgesetzt oder ein neues Gespräch gestartet werden soll. Wenn diese Funktion deaktiviert ist, entfernt der Bot automatisch das Timeout-Gespräch und startet ein neues. Um diese Funktion zu deaktivieren, setzen Sie die Variable `TIMEOUT_ASK` auf `False`. 49 | 50 | ### Transkription 51 | 52 | Der Bot unterstützt die Transkription von Audiodateien. Um diese Funktion zu deaktivieren, setzen Sie die Variable `FEATURE_TRANSCRIPTION` auf `False`. 53 | 54 | ### OCR (Optische Zeichenerkennung) 55 | 56 | Der Bot unterstützt OCR zum Lesen von Texten aus Bildern. Um diese Funktion zu deaktivieren, setzen Sie die Variable `FEATURE_IMAGE_READ` auf `False`. 57 | 58 | ### Dokumentenlesen 59 | 60 | Der Bot unterstützt das Lesen von Dokumenten. Um diese Funktion zu deaktivieren, setzen Sie die Variable `FEATURE_DOCUMENT_READ` auf `False`. 61 | 62 | ### Websuche 63 | 64 | Der Bot unterstützt die Funktion zur Websuche. Um diese Funktion zu deaktivieren, setzen Sie die Variable `FEATURE_BROWSING` auf `False`. 65 | 66 | ### URL-Lesen 67 | 68 | Der Bot unterstützt das Lesen des Inhalts von URLs. Um diese Funktion zu deaktivieren, setzen Sie die Variable `FEATURE_URL_READ` auf `False`. 69 | 70 | ### Audio- und Dateigrößenbeschränkungen 71 | 72 | Der Bot hat Beschränkungen für die Größe von Audiodateien und Dokumenten, die verarbeitet werden können. Die maximale Größe der Audiodatei kann mit der Variable `AUDIO_MAX_MB` konfiguriert werden (Standardwert sind 20 MB), und die maximale Größe der Dokumentendatei kann mit der Variable `DOC_MAX_MB` konfiguriert werden (Standardwert sind 10 MB).... z.B. AUDIO_MAX_MB=20 73 | 74 | ### URL-Größenbeschränkung 75 | 76 | Der Bot hat eine Beschränkung für die Größe von URLs, die verarbeitet werden können. Die maximale URL-Größe kann mit der Variable `URL_MAX_MB` konfiguriert werden. Die Standardgrenze beträgt 5 MB. 77 | 78 | ### Anfrage-Wiederholungen und Timeout 79 | 80 | Der Bot unterstützt Anfrage-Wiederholungen im Falle von Fehlern. Die maximale Anzahl von Wiederholungen kann mit der Variable `REQUEST_MAX_RETRIES` konfiguriert werden. Standardmäßig sind es 3 Wiederholungen. Die Timeout-Dauer für Anfragen kann mit der Variable `REQUEST_TIMEOUT` konfiguriert werden. Das Standard-Timeout beträgt 10 Sekunden. 81 | 82 | ### PDF-Seitenlimit 83 | 84 | Beim Lesen von PDF-Dokumenten hat der Bot eine Begrenzung für die Anzahl der Seiten, die verarbeitet werden können. Das maximale Seitenlimit kann mit der Variable `PDF_PAGE_LIMIT` konfiguriert werden. Das Standardlimit beträgt 25 Seiten. 85 | 86 | ### Automatische Spracherkennung 87 | 88 | Der Bot unterstützt die automatische Spracherkennung für Kontext und Menüs. Die Standardsprache für die automatische Erkennung (wenn die Benutzersprache vom Bot nicht unterstützt wird) kann mit der Variable `AUTO_LANG` konfiguriert werden. Die Standardsprache ist Englisch (`en`). Diese Standardsprache wird für Bot-Fehler oder einige Debug-Nachrichten verwendet. 89 | 90 | ### Proxy-Unterstützung 91 | 92 | Der Bot unterstützt die Verwendung eines Proxys nur für API-Anfragen. Um einen Proxy zu verwenden, geben Sie die Proxy-URL in der Variable `API_TUNNEL` an (z.B. `http://127.0.0.1:3128`). Wenn kein Proxy benötigt wird, lassen Sie diese Variable leer. -------------------------------------------------------------------------------- /docs/variables/en.md: -------------------------------------------------------------------------------- 1 | ## Configuration 2 | 3 | ### Telegram Token 4 | 5 | To use the Telegram bot, you need to provide a Telegram token. This token can be obtained by creating a bot via `https://t.me/botfather`. The token needs to be stored in the `TELEGRAM_TOKEN` variable. 6 | 7 | ### Menu Configuration 8 | 9 | The bot's menu can be configured with the following options: 10 | 11 | - `MAX_ITEMS_PER_PAGE`: The maximum number of items to display per page in the menu. Default is 10. 12 | - `MAX_COLUMNS_PER_PAGE`: The maximum number of columns to display per page in the menu. Default is 2. 13 | 14 | ### User and Chat Whitelist 15 | 16 | You can specify a whitelist of users and chats that are allowed to interact with the bot. The whitelist should be provided as a list of user or chat IDs in the `USER_WHITELIST` variable, respectively. 17 | 18 | ### Database Configuration 19 | 20 | The bot supports both MongoDB and JSON database options. By default, it uses Mongo database. To use JSON Database, set the `WITHOUT_MONGODB` variable to `True`. 21 | 22 | ### Dialog Timeout 23 | 24 | The bot has a dialog timeout feature, which automatically ends a conversation if there is no activity for a certain period of time. The timeout duration can be configured using the `DIALOG_TIMEOUT` variable. The default timeout is 7200 seconds (2 hours). 25 | 26 | ### Image Generation 27 | 28 | The bot supports generating images based on user input. To disable this feature, set the `FEATURE_IMAGE_GENERATION` variable to `False`. 29 | 30 | The number of images to generate can be configured using the `OUTPUT_IMAGES` variable. The default is 4 images. 31 | 32 | Generated images have an expiration time after which they are deleted from the bot's memory. The expiration time can be configured using the `GENERATED_IMAGE_EXPIRATION_MINUTES` variable. The default expiration time is 5 minutes. 33 | 34 | ### URL Direct Response 35 | 36 | By default, the bot answers after sending a URL to be read. To disable this and wait to the user input after processing the url, set the `URL_DIRECT_RESPONSE` variable to `False`. 37 | 38 | ### Streaming Answers 39 | 40 | The bot answers with streaming responses, which allows for continuous output of results. To disable this feature, set the `STREAM_ANSWERS` variable to `False`. 41 | 42 | ### Function Calls 43 | 44 | The bot supports new OpenAI function calls. To disable this feature, set the `FEATURE_FUNCTION_CALLS` variable to `False`. 45 | 46 | ### Timeout Ask 47 | 48 | The bot has a feature for asking if continue or start a new conversation. If disabled, the bot will automatically remove the timeout conversation and start a new one. To disable this feature, set the `TIMEOUT_ASK` variable to `False`. 49 | 50 | ### Transcription 51 | 52 | The bot supports transcription of audio files. To disable this feature, set the `FEATURE_TRANSCRIPTION` variable to `False`. 53 | 54 | ### OCR (Optical Character Recognition) 55 | 56 | The bot supports OCR for reading text from images. To disable this feature, set the `FEATURE_IMAGE_READ` variable to `False`. 57 | 58 | ### Document Reading 59 | 60 | The bot supports reading documents. To disable this feature, set the `FEATURE_DOCUMENT_READ` variable to `False`. 61 | 62 | ### Web Search 63 | 64 | The bot supports web search functionality. To disable this feature, set the `FEATURE_BROWSING` variable to `False`. 65 | 66 | ### URL Reading 67 | 68 | The bot supports reading the content of URLs. To disable this feature, set the `FEATURE_URL_READ` variable to `False`. 69 | 70 | ### Audio and File Size Limits 71 | 72 | The bot has limits on the size of audio files and documents that can be processed. The maximum audio file size can be configured using the `AUDIO_MAX_MB` variable (default is 20MB), and the maximum document file size can be configured using the `DOC_MAX_MB` variable (default is 10MB).... ex. AUDIO_MAX_MB=20 73 | 74 | ### URL Size Limit 75 | 76 | The bot has a limit on the size of URLs that can be processed. The maximum URL size can be configured using the `URL_MAX_MB` variable. The default limit is 5MB. 77 | 78 | ### Request Retries and Timeout 79 | 80 | The bot supports request retries in case of failures. The maximum number of retries can be configured using the `REQUEST_MAX_RETRIES` variable. The default is 3 retries. The request timeout duration can be configured using the `REQUEST_TIMEOUT` variable. The default timeout is 10 seconds. 81 | 82 | ### PDF Page Limit 83 | 84 | When reading PDF documents, the bot has a limit on the number of pages that can be processed. The maximum page limit can be configured using the `PDF_PAGE_LIMIT` variable. The default limit is 25 pages. 85 | 86 | ### Automatic Language Detection 87 | 88 | The bot supports automatic language detection for context and menus. The default language for automatic detection (if the user language is not supported by the bot) can be configured using the `AUTO_LANG` variable. The default language is English (`en`). This default language is used for bot errors or some debug messages 89 | 90 | ### Proxy Support 91 | 92 | The bot supports using a proxy only for API requests. To use a proxy, provide the proxy URL in the `API_TUNNEL` variable (ex. `http://127.0.0.1:3128`). If no proxy is needed, leave this variable empty. -------------------------------------------------------------------------------- /docs/variables/jp.md: -------------------------------------------------------------------------------- 1 | ## 設定 2 | 3 | ### Telegramトークン 4 | 5 | Telegramボットを使用するには、Telegramトークンを提供する必要があります。このトークンは、`https://t.me/botfather`を介してボットを作成することで取得できます。トークンは`TELEGRAM_TOKEN`変数に保存する必要があります。 6 | 7 | ### メニューの設定 8 | 9 | ボットのメニューは、以下のオプションで設定できます: 10 | 11 | - `MAX_ITEMS_PER_PAGE`:メニューの1ページあたりに表示するアイテムの最大数。デフォルトは10です。 12 | - `MAX_COLUMNS_PER_PAGE`:メニューの1ページあたりに表示する列の最大数。デフォルトは2です。 13 | 14 | ### ユーザーとチャットのホワイトリスト 15 | 16 | ボットと対話することが許可されているユーザーやチャットのホワイトリストを指定することができます。ホワイトリストは、`USER_WHITELIST` 変数に、ユーザーまたはチャットのIDのリストとして提供する必要があります。 17 | 18 | ### データベースの設定 19 | 20 | ボットはMongoDBとJSONデータベースの両方をサポートしています。デフォルトでは、Mongoデータベースを使用します。JSONデータベースを使用するには、`WITHOUT_MONGODB`変数を`True`に設定します。 21 | 22 | ### ダイアログのタイムアウト 23 | 24 | ボットには、一定期間活動がない場合に自動的に会話を終了するダイアログのタイムアウト機能があります。タイムアウトの期間は`DIALOG_TIMEOUT`変数を使用して設定できます。デフォルトのタイムアウトは7200秒(2時間)です。 25 | 26 | ### 画像の生成 27 | 28 | ボットは、ユーザーの入力に基づいて画像を生成する機能をサポートしています。この機能を無効にするには、`FEATURE_IMAGE_GENERATION`変数を`False`に設定します。 29 | 30 | 生成する画像の数は、`OUTPUT_IMAGES`変数を使用して設定できます。デフォルトは4枚の画像です。 31 | 32 | 生成された画像は、一定期間経過するとボットのメモリから削除されます。有効期限は`GENERATED_IMAGE_EXPIRATION_MINUTES`変数を使用して設定できます。デフォルトの有効期限は5分です。 33 | 34 | ### URLの直接応答 35 | 36 | デフォルトでは、ボットはURLを送信した後に応答します。この機能を無効にして、URLの処理後にユーザーの入力を待つには、`URL_DIRECT_RESPONSE`変数を`False`に設定します。 37 | 38 | ### ストリーミング応答 39 | 40 | ボットはストリーミング応答で応答します。これにより、結果の連続的な出力が可能になります。この機能を無効にするには、`STREAM_ANSWERS`変数を`False`に設定します。 41 | 42 | ### 関数呼び出し 43 | 44 | ボットは新しいOpenAI関数呼び出しをサポートしています。この機能を無効にするには、`FEATURE_FUNCTION_CALLS`変数を`False`に設定します。 45 | 46 | ### タイムアウトの質問 47 | 48 | ボットには、継続するか新しい会話を開始するかを尋ねる機能があります。無効にすると、ボットは自動的にタイムアウトした会話を削除し、新しい会話を開始します。この機能を無効にするには、`TIMEOUT_ASK`変数を`False`に設定します。 49 | 50 | ### 音声の転写 51 | 52 | ボットは音声ファイルの転写をサポートしています。この機能を無効にするには、`FEATURE_TRANSCRIPTION`変数を`False`に設定します。 53 | 54 | ### OCR(光学文字認識) 55 | 56 | ボットは画像からテキストを読み取るためのOCRをサポートしています。この機能を無効にするには、`FEATURE_IMAGE_READ`変数を`False`に設定します。 57 | 58 | ### ドキュメントの読み取り 59 | 60 | ボットはドキュメントの読み取りをサポートしています。この機能を無効にするには、`FEATURE_DOCUMENT_READ`変数を`False`に設定します。 61 | 62 | ### ウェブ検索 63 | 64 | ボットはウェブ検索機能をサポートしています。この機能を無効にするには、`FEATURE_BROWSING`変数を`False`に設定します。 65 | 66 | ### URLの読み取り 67 | 68 | ボットはURLの内容を読み取る機能をサポートしています。この機能を無効にするには、`FEATURE_URL_READ`変数を`False`に設定します。 69 | 70 | ### 音声とファイルのサイズ制限 71 | 72 | ボットには、処理できる音声ファイルとドキュメントのサイズに制限があります。最大の音声ファイルサイズは`AUDIO_MAX_MB`変数を使用して設定できます(デフォルトは20MB)、最大のドキュメントファイルサイズは`DOC_MAX_MB`変数を使用して設定できます(デフォルトは10MB)... ex. AUDIO_MAX_MB=20 73 | 74 | ### URLのサイズ制限 75 | 76 | ボットには、処理できるURLのサイズに制限があります。最大のURLサイズは`URL_MAX_MB`変数を使用して設定できます。デフォルトの制限は5MBです。 77 | 78 | ### リクエストのリトライとタイムアウト 79 | 80 | ボットは、リクエストが失敗した場合にリトライをサポートしています。最大のリトライ回数は`REQUEST_MAX_RETRIES`変数を使用して設定できます。デフォルトは3回のリトライです。リクエストのタイムアウト期間は`REQUEST_TIMEOUT`変数を使用して設定できます。デフォルトのタイムアウトは10秒です。 81 | 82 | ### PDFページの制限 83 | 84 | PDFドキュメントを読み取る際、ボットには処理できるページ数の制限があります。最大のページ制限は`PDF_PAGE_LIMIT`変数を使用して設定できます。デフォルトの制限は25ページです。 85 | 86 | ### 自動言語検出 87 | 88 | ボットは、コンテキストとメニューの自動言語検出をサポートしています。ユーザーの言語がボットでサポートされていない場合のデフォルト言語は、`AUTO_LANG`変数を使用して設定できます。デフォルトの言語は英語(`en`)です。このデフォルトの言語は、ボットのエラーや一部のデバッグメッセージに使用されます。 89 | 90 | ### プロキシのサポート 91 | 92 | ボットはAPIリクエストのみにプロキシを使用することができます。プロキシを使用するには、`API_TUNNEL`変数にプロキシのURLを指定します(例:`http://127.0.0.1:3128`)。プロキシが必要ない場合は、この変数を空のままにしてください。 -------------------------------------------------------------------------------- /docs/variables/pt.md: -------------------------------------------------------------------------------- 1 | ## Configuração 2 | 3 | ### Token do Telegram 4 | 5 | Para usar o bot do Telegram, você precisa fornecer um token do Telegram. Esse token pode ser obtido criando um bot através do `https://t.me/botfather`. O token precisa ser armazenado na variável `TELEGRAM_TOKEN`. 6 | 7 | ### Configuração do Menu 8 | 9 | O menu do bot pode ser configurado com as seguintes opções: 10 | 11 | - `MAX_ITEMS_PER_PAGE`: O número máximo de itens a serem exibidos por página no menu. O padrão é 10. 12 | - `MAX_COLUMNS_PER_PAGE`: O número máximo de colunas a serem exibidas por página no menu. O padrão é 2. 13 | 14 | ### Lista Branca de Usuários e Chats 15 | 16 | Você pode especificar uma lista branca de usuários e chats que têm permissão para interagir com o bot. A lista branca deve ser fornecida como uma lista de IDs de usuário ou chat na variávei `USER_WHITELIST`, respectivamente. 17 | 18 | ### Configuração do Banco de Dados 19 | 20 | O bot suporta opções de banco de dados tanto do MongoDB quanto do JSON. Por padrão, ele usa o banco de dados do Mongo. Para usar o banco de dados JSON, defina a variável `WITHOUT_MONGODB` como `True`. 21 | 22 | ### Tempo Limite do Diálogo 23 | 24 | O bot possui uma função de tempo limite de diálogo, que encerra automaticamente uma conversa se não houver atividade por um determinado período de tempo. A duração do tempo limite pode ser configurada usando a variável `DIALOG_TIMEOUT`. O tempo limite padrão é de 7200 segundos (2 horas). 25 | 26 | ### Geração de Imagens 27 | 28 | O bot suporta a geração de imagens com base na entrada do usuário. Para desativar esse recurso, defina a variável `FEATURE_IMAGE_GENERATION` como `False`. 29 | 30 | O número de imagens a serem geradas pode ser configurado usando a variável `OUTPUT_IMAGES`. O padrão é de 4 imagens. 31 | 32 | As imagens geradas têm um tempo de expiração após o qual são excluídas da memória do bot. O tempo de expiração pode ser configurado usando a variável `GENERATED_IMAGE_EXPIRATION_MINUTES`. O tempo de expiração padrão é de 5 minutos. 33 | 34 | ### Resposta Direta de URL 35 | 36 | Por padrão, o bot responde após enviar uma URL para ser lida. Para desativar isso e aguardar a entrada do usuário após o processamento da URL, defina a variável `URL_DIRECT_RESPONSE` como `False`. 37 | 38 | ### Respostas em Streaming 39 | 40 | O bot responde com respostas em streaming, o que permite a saída contínua de resultados. Para desativar esse recurso, defina a variável `STREAM_ANSWERS` como `False`. 41 | 42 | ### Chamadas de Função 43 | 44 | O bot suporta novas chamadas de função do OpenAI. Para desativar esse recurso, defina a variável `FEATURE_FUNCTION_CALLS` como `False`. 45 | 46 | ### Pergunta de Tempo Limite 47 | 48 | O bot possui uma função para perguntar se deve continuar ou iniciar uma nova conversa. Se desativado, o bot removerá automaticamente a conversa com tempo limite e iniciará uma nova. Para desativar esse recurso, defina a variável `TIMEOUT_ASK` como `False`. 49 | 50 | ### Transcrição 51 | 52 | O bot suporta a transcrição de arquivos de áudio. Para desativar esse recurso, defina a variável `FEATURE_TRANSCRIPTION` como `False`. 53 | 54 | ### OCR (Reconhecimento Óptico de Caracteres) 55 | 56 | O bot suporta OCR para ler texto de imagens. Para desativar esse recurso, defina a variável `FEATURE_IMAGE_READ` como `False`. 57 | 58 | ### Leitura de Documentos 59 | 60 | O bot suporta a leitura de documentos. Para desativar esse recurso, defina a variável `FEATURE_DOCUMENT_READ` como `False`. 61 | 62 | ### Pesquisa na Web 63 | 64 | O bot suporta funcionalidade de pesquisa na web. Para desativar esse recurso, defina a variável `FEATURE_BROWSING` como `False`. 65 | 66 | ### Leitura de URL 67 | 68 | O bot suporta a leitura do conteúdo de URLs. Para desativar esse recurso, defina a variável `FEATURE_URL_READ` como `False`. 69 | 70 | ### Limites de Tamanho de Áudio e Arquivo 71 | 72 | O bot possui limites no tamanho de arquivos de áudio e documentos que podem ser processados. O tamanho máximo do arquivo de áudio pode ser configurado usando a variável `AUDIO_MAX_MB` (o padrão é de 20MB), e o tamanho máximo do arquivo de documento pode ser configurado usando a variável `DOC_MAX_MB` (o padrão é de 10MB). 73 | 74 | ### Limite de Tamanho de URL 75 | 76 | O bot possui um limite no tamanho de URLs que podem ser processados. O tamanho máximo do URL pode ser configurado usando a variável `URL_MAX_MB`. O limite padrão é de 5MB. 77 | 78 | ### Retentativas e Tempo Limite de Requisição 79 | 80 | O bot suporta retentativas de requisição em caso de falhas. O número máximo de retentativas pode ser configurado usando a variável `REQUEST_MAX_RETRIES`. O padrão é de 3 retentativas. A duração do tempo limite da requisição pode ser configurada usando a variável `REQUEST_TIMEOUT`. O tempo limite padrão é de 10 segundos. 81 | 82 | ### Limite de Páginas de PDF 83 | 84 | Ao ler documentos em PDF, o bot possui um limite no número de páginas que podem ser processadas. O limite máximo de páginas pode ser configurado usando a variável `PDF_PAGE_LIMIT`. O limite padrão é de 25 páginas. 85 | 86 | ### Detecção Automática de Idioma 87 | 88 | O bot suporta detecção automática de idioma para contexto e menus. O idioma padrão para detecção automática (se o idioma do usuário não for suportado pelo bot) pode ser configurado usando a variável `AUTO_LANG`. O idioma padrão é o inglês (`en`). Esse idioma padrão é usado para erros do bot ou algumas mensagens de depuração. 89 | 90 | ### Suporte a Proxy 91 | 92 | O bot suporta o uso de um proxy apenas para requisições de API. Para usar um proxy, forneça a URL do proxy na variável `API_TUNNEL` (ex. `http://127.0.0.1:3128`). Se nenhum proxy for necessário, deixe essa variável vazia. -------------------------------------------------------------------------------- /docs/variables/ru.md: -------------------------------------------------------------------------------- 1 | ## Конфигурация 2 | 3 | ### Токен Telegram 4 | 5 | Для использования Telegram-бота необходимо предоставить токен Telegram. Этот токен можно получить, создав бота через `https://t.me/botfather`. Токен должен быть сохранен в переменной `TELEGRAM_TOKEN`. 6 | 7 | ### Конфигурация меню 8 | 9 | Меню бота можно настроить с помощью следующих параметров: 10 | 11 | - `MAX_ITEMS_PER_PAGE`: Максимальное количество элементов, отображаемых на одной странице меню. По умолчанию 10. 12 | - `MAX_COLUMNS_PER_PAGE`: Максимальное количество столбцов, отображаемых на одной странице меню. По умолчанию 2. 13 | 14 | ### Белый список пользователей и чатов 15 | 16 | Вы можете указать белый список пользователей и чатов, которым разрешено взаимодействовать с ботом. Белый список должен быть предоставлен в виде списка идентификаторов пользователей или чатов в переменных `USER_WHITELIST` соответственно. 17 | 18 | ### Конфигурация базы данных 19 | 20 | Бот поддерживает как базу данных MongoDB, так и JSON. По умолчанию используется база данных Mongo. Чтобы использовать JSON-базу данных, установите переменную `WITHOUT_MONGODB` в значение `True`. 21 | 22 | ### Таймаут диалога 23 | 24 | У бота есть функция таймаута диалога, которая автоматически завершает разговор, если в течение определенного периода времени не происходит активности. Длительность таймаута можно настроить с помощью переменной `DIALOG_TIMEOUT`. По умолчанию таймаут составляет 7200 секунд (2 часа). 25 | 26 | ### Генерация изображений 27 | 28 | Бот поддерживает генерацию изображений на основе ввода пользователя. Чтобы отключить эту функцию, установите переменную `FEATURE_IMAGE_GENERATION` в значение `False`. 29 | 30 | Количество генерируемых изображений можно настроить с помощью переменной `OUTPUT_IMAGES`. По умолчанию генерируется 4 изображения. 31 | 32 | Сгенерированные изображения имеют время истечения, после которого они удаляются из памяти бота. Время истечения можно настроить с помощью переменной `GENERATED_IMAGE_EXPIRATION_MINUTES`. По умолчанию время истечения составляет 5 минут. 33 | 34 | ### Прямой ответ на URL 35 | 36 | По умолчанию бот отвечает после отправки URL для чтения. Чтобы отключить это и дождаться ввода пользователя после обработки URL, установите переменную `URL_DIRECT_RESPONSE` в значение `False`. 37 | 38 | ### Потоковые ответы 39 | 40 | Бот отвечает с использованием потоковых ответов, что позволяет непрерывно выводить результаты. Чтобы отключить эту функцию, установите переменную `STREAM_ANSWERS` в значение `False`. 41 | 42 | ### Вызовы функций 43 | 44 | Бот поддерживает новые вызовы функций OpenAI. Чтобы отключить эту функцию, установите переменную `FEATURE_FUNCTION_CALLS` в значение `False`. 45 | 46 | ### Запрос на продолжение 47 | 48 | У бота есть функция запроса на продолжение или начало нового разговора. Если она отключена, бот автоматически удалит разговор с таймаутом и начнет новый. Чтобы отключить эту функцию, установите переменную `TIMEOUT_ASK` в значение `False`. 49 | 50 | ### Транскрипция 51 | 52 | Бот поддерживает транскрипцию аудиофайлов. Чтобы отключить эту функцию, установите переменную `FEATURE_TRANSCRIPTION` в значение `False`. 53 | 54 | ### OCR (Оптическое распознавание символов) 55 | 56 | Бот поддерживает OCR для чтения текста с изображений. Чтобы отключить эту функцию, установите переменную `FEATURE_IMAGE_READ` в значение `False`. 57 | 58 | ### Чтение документов 59 | 60 | Бот поддерживает чтение документов. Чтобы отключить эту функцию, установите переменную `FEATURE_DOCUMENT_READ` в значение `False`. 61 | 62 | ### Веб-поиск 63 | 64 | Бот поддерживает функцию веб-поиска. Чтобы отключить эту функцию, установите переменную `FEATURE_BROWSING` в значение `False`. 65 | 66 | ### Чтение URL 67 | 68 | Бот поддерживает чтение содержимого URL. Чтобы отключить эту функцию, установите переменную `FEATURE_URL_READ` в значение `False`. 69 | 70 | ### Ограничения на размер аудио и файлов 71 | 72 | У бота есть ограничения на размер аудиофайлов и документов, которые могут быть обработаны. Максимальный размер аудиофайла можно настроить с помощью переменной `AUDIO_MAX_MB` (по умолчанию 20 МБ), а максимальный размер документа можно настроить с помощью переменной `DOC_MAX_MB` (по умолчанию 10 МБ). 73 | 74 | ### Ограничение размера URL 75 | 76 | У бота есть ограничение на размер URL, который может быть обработан. Максимальный размер URL можно настроить с помощью переменной `URL_MAX_MB`. По умолчанию ограничение составляет 5 МБ. 77 | 78 | ### Повторы запросов и таймаут 79 | 80 | Бот поддерживает повторы запросов в случае сбоев. Максимальное количество повторов можно настроить с помощью переменной `REQUEST_MAX_RETRIES`. По умолчанию установлено 3 повтора. Длительность таймаута запроса можно настроить с помощью переменной `REQUEST_TIMEOUT`. По умолчанию таймаут составляет 10 секунд. 81 | 82 | ### Ограничение количества страниц PDF 83 | 84 | При чтении PDF-документов у бота есть ограничение на количество страниц, которые могут быть обработаны. Максимальное количество страниц можно настроить с помощью переменной `PDF_PAGE_LIMIT`. По умолчанию ограничение составляет 25 страниц. 85 | 86 | ### Автоматическое определение языка 87 | 88 | Бот поддерживает автоматическое определение языка для контекста и меню. Язык по умолчанию для автоматического определения (если язык пользователя не поддерживается ботом) можно настроить с помощью переменной `AUTO_LANG`. Язык по умолчанию - английский (`en`). Этот язык используется для ошибок бота или некоторых отладочных сообщений. 89 | 90 | ### Поддержка прокси 91 | 92 | Бот поддерживает использование прокси только для запросов API. Чтобы использовать прокси, укажите URL прокси в переменной `API_TUNNEL` (например, `http://127.0.0.1:3128`). Если прокси не требуется, оставьте эту переменную пустой. -------------------------------------------------------------------------------- /docs/variables/zh.md: -------------------------------------------------------------------------------- 1 | ## 配置 2 | 3 | ### Telegram令牌 4 | 5 | 要使用Telegram机器人,您需要提供一个Telegram令牌。可以通过`https://t.me/botfather`创建一个机器人来获取此令牌。令牌需要存储在`TELEGRAM_TOKEN`变量中。 6 | 7 | ### 菜单配置 8 | 9 | 可以使用以下选项配置机器人的菜单: 10 | 11 | - `MAX_ITEMS_PER_PAGE`:菜单中每页显示的最大项目数。默认为10。 12 | - `MAX_COLUMNS_PER_PAGE`:菜单中每页显示的最大列数。默认为2。 13 | 14 | ### 用户和聊天白名单 15 | 16 | 您可以指定允许与机器人交互的用户和聊天的白名单。白名单应作为用户或聊天ID的列表提供,分别存储在`USER_WHITELIST`变量中。 17 | 18 | ### 数据库配置 19 | 20 | 机器人支持MongoDB和JSON数据库选项。默认情况下,它使用Mongo数据库。要使用JSON数据库,请将`WITHOUT_MONGODB`变量设置为`True`。 21 | 22 | ### 对话超时 23 | 24 | 机器人具有对话超时功能,如果一段时间内没有活动,会自动结束对话。可以使用`DIALOG_TIMEOUT`变量配置超时持续时间。默认超时时间为7200秒(2小时)。 25 | 26 | ### 图像生成 27 | 28 | 机器人支持根据用户输入生成图像。要禁用此功能,请将`FEATURE_IMAGE_GENERATION`变量设置为`False`。 29 | 30 | 可以使用`OUTPUT_IMAGES`变量配置要生成的图像数量。默认为4张图片。 31 | 32 | 生成的图像在一定时间后将从机器人的内存中删除。可以使用`GENERATED_IMAGE_EXPIRATION_MINUTES`变量配置过期时间。默认过期时间为5分钟。 33 | 34 | ### URL直接响应 35 | 36 | 默认情况下,机器人在发送URL以供阅读后立即回答。要禁用此功能,并在处理URL后等待用户输入,请将`URL_DIRECT_RESPONSE`变量设置为`False`。 37 | 38 | ### 流式回答 39 | 40 | 机器人使用流式响应进行回答,允许连续输出结果。要禁用此功能,请将`STREAM_ANSWERS`变量设置为`False`。 41 | 42 | ### 函数调用 43 | 44 | 机器人支持新的OpenAI函数调用。要禁用此功能,请将`FEATURE_FUNCTION_CALLS`变量设置为`False`。 45 | 46 | ### 超时询问 47 | 48 | 机器人具有询问是否继续或开始新对话的功能。如果禁用,机器人将自动删除超时对话并开始新对话。要禁用此功能,请将`TIMEOUT_ASK`变量设置为`False`。 49 | 50 | ### 转录 51 | 52 | 机器人支持音频文件的转录。要禁用此功能,请将`FEATURE_TRANSCRIPTION`变量设置为`False`。 53 | 54 | ### OCR(光学字符识别) 55 | 56 | 机器人支持从图像中读取文本的OCR功能。要禁用此功能,请将`FEATURE_IMAGE_READ`变量设置为`False`。 57 | 58 | ### 文档阅读 59 | 60 | 机器人支持阅读文档的功能。要禁用此功能,请将`FEATURE_DOCUMENT_READ`变量设置为`False`。 61 | 62 | ### 网络搜索 63 | 64 | 机器人支持网络搜索功能。要禁用此功能,请将`FEATURE_BROWSING`变量设置为`False`。 65 | 66 | ### URL阅读 67 | 68 | 机器人支持阅读URL的内容。要禁用此功能,请将`FEATURE_URL_READ`变量设置为`False`。 69 | 70 | ### 音频和文件大小限制 71 | 72 | 机器人对可以处理的音频文件和文档的大小有限制。可以使用`AUDIO_MAX_MB`变量配置最大音频文件大小(默认为20MB),可以使用`DOC_MAX_MB`变量配置最大文档文件大小(默认为10MB)... ex. AUDIO_MAX_MB=20 73 | 74 | ### URL大小限制 75 | 76 | 机器人对可以处理的URL的大小有限制。可以使用`URL_MAX_MB`变量配置最大URL大小。默认限制为5MB。 77 | 78 | ### 请求重试和超时 79 | 80 | 机器人在请求失败时支持请求重试。可以使用`REQUEST_MAX_RETRIES`变量配置最大重试次数。默认为3次重试。可以使用`REQUEST_TIMEOUT`变量配置请求超时持续时间。默认超时时间为10秒。 81 | 82 | ### PDF页数限制 83 | 84 | 在阅读PDF文档时,机器人对可以处理的页面数量有限制。可以使用`PDF_PAGE_LIMIT`变量配置最大页面限制。默认限制为25页。 85 | 86 | ### 自动语言检测 87 | 88 | 机器人支持上下文和菜单的自动语言检测。可以使用`AUTO_LANG`变量配置自动检测的默认语言(如果用户语言不受机器人支持)。默认语言为英语(`en`)。此默认语言用于机器人错误或某些调试消息。 89 | 90 | ### 代理支持 91 | 92 | 机器人仅支持对API请求使用代理。要使用代理,请在`API_TUNNEL`变量中提供代理URL(例如`http://127.0.0.1:3128`)。如果不需要代理,请将此变量留空。 -------------------------------------------------------------------------------- /locales/lang.ar.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "actual": "حالي", 4 | "name": "العربية 🇦🇪", 5 | "description": "لغة تتغنى بالألوان والشعر، تجسد تاريخ ثري وثقافة عريقة تتألق بالرومانسية والشجاعة.", 6 | "seleccion": "من فضلك اختر واحداً متاحاً.", 7 | "bienvenida": "تم تغيير اللغة!" 8 | }, 9 | "metagen": { 10 | "log": "سجل", 11 | "documentos": "المستندات", 12 | "urls": "الروابط", 13 | "usuario": "مستخدم", 14 | "mensaje": "رسالة", 15 | "contexto": "نعم، لدي القدرة على قراءة الملفات والوثائق والروابط وصفحات الويب. سيتم إرفاق معلومات هذه الموارد مسبقًا بهذه الرسالة في التنسيق ('url': 'محتوى_صفحة_الويب'). سأستخدم هذا المحتوى للرد على الصفحات والوثائق. منعا للإلهام الوهمي إذا سألت عن ملفات أو صفحات أبعد من تلك المكتوبة مسبقًا.\n", 16 | "transcripcion_imagen": "نص الصورة المحولة", 17 | "paginas": "صفحة", 18 | "parrafos": "فقرة", 19 | "configuracion": "الإعدادات الحالية", 20 | "api": "واجهة برمجة تطبيقات الدردشة", 21 | "image_api": "واجهة برمجة تطبيقات الصور", 22 | "modelo": "النموذج", 23 | "chatmode": "وضع المحادثة", 24 | "busquedaweb": "بحث ويب", 25 | "tokens": "الرموز", 26 | "tokensmax": "الرموز القصوى", 27 | "advertencia": "تحذير", 28 | "imaginepy_styles": "أسلوب", 29 | "imaginepy_ratios": "نسبة", 30 | "imaginepy_actual_style": "النمط الحالي لـ StableHorde", 31 | "imaginepy_actual_model": "النموذج الحالي لـ StableHorde" 32 | }, 33 | "apicheck": { 34 | "inicio": "تم تنفيذ فحص الواجهات البرمجية", 35 | "warning_chatbase": "تحذير... حد زمني لواجهة برمجة التطبيقات في Chatbase!", 36 | "connection": "تم الاتصال بنجاح مع", 37 | "bad": "غير جيدة", 38 | "total": "إجمالي", 39 | "working": "يعمل", 40 | "dead": "متوقفة" 41 | }, 42 | "commands": { 43 | "reset": "إعادة تعيين الإعدادات" 44 | }, 45 | "mensajes": { 46 | "bot_iniciado": "بدء تشغيل الروبوت", 47 | "preguntar_descargar_fotos": "هل تريد تنزيل الصور بأقصى جودة؟ ستنتهي صلاحيتها خلال {expirationtime} دقائق!", 48 | "fotos_ya_expiraron": "للأسف، انتهت صلاحية الصور.", 49 | "fotos_borradas_listo": "تم حذف الصور!", 50 | "ayuda_grupos": "يمكنك إضافة روبوت إلى أي مجموعة دردشة للمساعدة والتسلية للمشاركين.\n\nالتعليمات (انظر الفيديو أدناه)\n1. أضف الروبوت إلى مجموعة الدردشة\n2. قم بتحويله إلى مسؤول حتى يتمكن من رؤية الرسائل (يمكن تقييد حقوقه الأخرى)\n3. أنت رائع!\n\nللحصول على رد من الروبوت في المحادثة - @ علمه أو رد على رسالته.\nعلى سبيل المثال: '{bot_username} اكتب قصيدة عن Telegram'\n", 51 | "mensaje_semaforo": "⏳ من فضلك انتظر ردًا على الرسالة السابقة... أو يمكنك /cancel", 52 | "cancelado": "✅ تم الإلغاء", 53 | "nadacancelado": "لا يوجد شيء للإلغاء...", 54 | "no_retry_mensaje": "لا يوجد رسالة لإعادة المحاولة 🤷‍♂️", 55 | "timeout_ask": "هل مر وقت طويل منذ آخر مرة تحدثنا؟ هل نبدأ محادثة جديدة؟", 56 | "timeout_nodialog": "لا يوجد سجل. سنبدأ محادثة جديدة 🤷‍♂️", 57 | "timeout_ask_false": "بدء حوار جديد بسبب انتهاء وقت الانتظار. وضع الدردشة {chatmode}", 58 | "message_empty_handle": "🥲 لقد أرسلت رسالة فارغة. يرجى المحاولة مرة أخرى!", 59 | "image_ocr_ask": "🖼️ {ocresult}\n\nهل تود معرفة شيء ما عن هذا النص المحول؟", 60 | "document_anotado_ask": "تم التعليق على الوثيقة 🫡 ما الذي تريد معرفته عن الملف؟", 61 | "url_anotado_ask": "تم التعليق 📝 ما الذي تريد معرفته عن الصفحة؟", 62 | "genimagen_noargs": "يجب عليك كتابة شيء بعد الأمر", 63 | "genimagen_notext": "لم يتم اكتشاف نص لإنشاء الصور 😔" 64 | }, 65 | "errores": { 66 | "error": "خطأ", 67 | "error_inesperado": "حدث خطأ غير متوقع... إذا استمرت المشكلة، يرجى بدء حوار جديد باستخدام /new", 68 | "handler_excepcion": "استثناء في التعامل مع تحديث", 69 | "handler_error_handler": "خطأ ما في مدير الأخطاء", 70 | "utils_modelo_desconocido": "النموذج غير معروف", 71 | "utils_chatbase_limit": "تم الوصول إلى الحد الأقصى للواجهة البرمجية. يرجى المحاولة لاحقًا!", 72 | "utils_dialog_messages_0": "خطأ... إما أنه لا توجد رسائل في الحوار أو اخترت قيمة قصوى لعدد الرموز غير واقعية.", 73 | "pdf_pages_limit": "😬 يتجاوز المستند الحد المسموح به بواقع {paginas} صفحة! سيتم قراءة أول {pdf_page_lim} صفحة فقط.", 74 | "document_size_limit": "الملف كبير جدًا ({file_size_mb} ميجابايت). الحد الأقصى هو {file_max_size} ميجابايت.", 75 | "audio_size_limit": "💀 حجم ملف الصوت يتجاوز الحد الأقصى {audio_max_size} ميجابايت!", 76 | "url_size_limit": "خطأ في الحصول على محتوى صفحة الويب", 77 | "url_size_exception": "إستثناء الحجم الكبير للرد من عنوان URL", 78 | "reset_chat_attributes": "كان لديك إعداد غير صالح في التكوين ، لذلك تمت إعادة كل شيء إلى القيم الافتراضية.", 79 | "reset_chat_mode": "وضع الدردشة الخاص بك غير متاح ، لذلك تم تغييره إلى '{new}'", 80 | "reset_api": "الواجهة البرمجية (API) التي اخترتها غير متاحة، لذا تم تغييرها إلى '{new}'", 81 | "reset_model": "نموذجك الحالي غير متوافق مع واجهة برمجة التطبيقات، لذلك تم تغيير النموذج تلقائيًا إلى '{new}'.", 82 | "reset_image_styles": "نمط الصور الحالي غير متوفر. لذا تم تغييره تلقائيًا إلى {new}.", 83 | "reset_imaginepy_styles": "نمط StableHorde الحالي غير متاح. لذلك تم تغييره تلقائيًا إلى {new}.", 84 | "reset_imaginepy_ratios": "نسبة StableHorde الحالية غير متاحة. لذلك تم تغييرها تلقائيًا إلى {new}.", 85 | "reset_imaginepy_models": "نموذج StableHorde الحالي غير متاح. لذلك تم تغييره تلقائيًا إلى {new}.", 86 | "genimagen_rejected": "🥲 طلبك لا يتوافق مع سياسات استخدام OpenAI ...", 87 | "genimagen_other": "🥲 حدث خطأ أثناء معالجة طلبك. يرجى المحاولة مرة أخرى في وقت لاحق...", 88 | "genimagen_badrequest": "🥲 حدث خطأ في الطلب. يرجى التحقق من تنسيق ومحتوى رسالتك...", 89 | "menu_api_no_disponible": "API '{api_antigua}' الحالية غير متاحة. لذلك تم تغييرها تلقائيًا إلى '{api_nueva}'.", 90 | "tiempoagotado": "لقد انتهى وقت الانتظار.", 91 | "ocr_no_extract": "تعذر استخراج النص من الصورة... 😔", 92 | "menu_modes_not_ready_yet": "خيارات القوائم ليست جاهزة بعد...", 93 | "advertencia_tokens_excedidos": "تجاوز عدد الرموز المسموح به في النموذج. تم تحسين الرسائل أو حذفها لمتابعة المحادثة.", 94 | "reintentos_alcanzados": "آسف. تم الوصول إلى الحد الأقصى لعدد المحاولات {reintentos}" 95 | } 96 | } -------------------------------------------------------------------------------- /locales/lang.jp.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "actual": "現在の", 4 | "name": "日本語 🇯🇵", 5 | "description": "優美で緻密な言葉が織り成す絵画のごとく、日本語は深い感情と独特の美意識を表現する。", 6 | "seleccion": "利用可能なものを選択してください。", 7 | "bienvenida": "言語が変更されました!" 8 | }, 9 | "metagen": { 10 | "log": "ログ", 11 | "documentos": "ドキュメント", 12 | "urls": "リンク", 13 | "usuario": "ユーザー", 14 | "mensaje": "メッセージ", 15 | "contexto": "はい、私はファイル、ドキュメント、リンク、ウェブページを読む能力を持っています。これらのリソースの情報は、このメッセージに('url': 'web_page_content')の形式で添付されます。私はこの内容を使用してページやドキュメントに対する回答をします。書かれているもの以上のファイルやページについての質問があっても、私には幻覚を見ることは禁止されています。\n", 16 | "transcripcion_imagen": "画像の文字起こし", 17 | "paginas": "ページ", 18 | "parrafos": "段落", 19 | "configuracion": "現在の設定", 20 | "api": "チャットAPI", 21 | "image_api": "画像API", 22 | "modelo": "モデル", 23 | "chatmode": "チャットモード", 24 | "busquedaweb": "ウェブ検索", 25 | "tokens": "トークン", 26 | "tokensmax": "最大トークン", 27 | "advertencia": "警告", 28 | "imaginepy_styles": "スタイル", 29 | "imaginepy_ratios": "比率", 30 | "imaginepy_actual_style": "Imagine.pyの現在のスタイル", 31 | "imaginepy_actual_model": "Imagine.pyの現在のモデル" 32 | }, 33 | "apicheck": { 34 | "inicio": "APIのチェックが実行されました", 35 | "warning_chatbase": "警告... ChatbaseのAPI時間制限!", 36 | "connection": "接続成功", 37 | "bad": "悪い", 38 | "total": "合計", 39 | "working": "動作中", 40 | "dead": "停止中" 41 | }, 42 | "commands": { 43 | "reset": "設定をリセットする" 44 | }, 45 | "mensajes": { 46 | "bot_iniciado": "ボットが開始されました", 47 | "preguntar_descargar_fotos": "最高品質で写真をダウンロードしますか? {expirationtime} 分で期限が切れます!", 48 | "fotos_ya_expiraron": "申し訳ありませんが、写真は期限切れになりました。", 49 | "fotos_borradas_listo": "写真が削除されました!", 50 | "ayuda_grupos": "ボットを任意のグループチャットに追加して、参加者をサポートやエンターテイメントを提供しましょう。\n\n手順(以下のビデオを参照)\n1. ボットをグループチャットに追加します\n2. ボットを管理者にすることで、メッセージを表示できるようにします(他の権限は制限できます)\n3. すごいですね!\n\nチャットでボットからの返信を受けるには、ボットにタグを付けるか、ボットのメッセージに返信します。\n例:'{bot_username} に Telegram についての詩を書いてもらう'\n", 51 | "mensaje_semaforo": "⏳ 前のメッセージに対する回答をお待ちください... または /cancel でキャンセルすることもできます", 52 | "cancelado": "✅ キャンセルされました", 53 | "nadacancelado": "キャンセルするものはありません...", 54 | "no_retry_mensaje": "再試行するメッセージはありません 🤷‍♂️", 55 | "timeout_ask": "久しぶりです!新しい会話を始めましょうか?", 56 | "timeout_nodialog": "履歴がありません。新しい会話を始めます 🤷‍♂️", 57 | "timeout_ask_false": "タイムアウトにより新しい対話を開始します。チャットモード {chatmode}", 58 | "message_empty_handle": "🥲 空のメッセージを送信しました。もう一度お試しください!", 59 | "image_ocr_ask": "🖼️ {ocresult}\n\nこの文字起こしについて何か知りたいですか?", 60 | "document_anotado_ask": "注釈付き 🫡 ファイルについて知りたいことは何ですか?", 61 | "url_anotado_ask": "アノテーションされました📝ページについて知りたいことは何ですか?", 62 | "genimagen_noargs": "コマンドの後に何かを入力する必要があります。", 63 | "genimagen_notext": "画像生成のためのテキストが検出されませんでした 😔" 64 | }, 65 | "errores": { 66 | "error": "エラー", 67 | "error_inesperado": "予期しないエラーが発生しました... 問題が解決しない場合は、/new を使用して新しいダイアログを開始してください", 68 | "handler_excepcion": "アップデートの処理中に例外が発生しました", 69 | "handler_error_handler": "エラーハンドラーにエラーがあります", 70 | "utils_modelo_desconocido": "不明なモデル", 71 | "utils_chatbase_limit": "APIの制限に達しました。後でもう一度お試しください!", 72 | "utils_dialog_messages_0": "エラー... ダイアログメッセージが存在しないか、極端に高い最大トークン値が選択されています", 73 | "pdf_pages_limit": "😬 ドキュメントが {paginas} ページ超過しています!最初の {pdf_page_lim} ページのみが読み込まれます。", 74 | "document_size_limit": "ファイルが大きすぎます({file_size_mb} MB)。制限は{file_max_size} MBです。", 75 | "audio_size_limit": "💀 オーディオファイルが{audio_max_size} MBの制限を超えています!", 76 | "url_size_limit": "ウェブページのコンテンツ取得エラー", 77 | "url_size_exception": "URLからの応答が大きすぎます", 78 | "reset_chat_attributes": "設定に無効な設定があったため、すべての値がデフォルト値にリセットされました。", 79 | "reset_chat_mode": "チャットモードは利用できませんでしたので、'{new}' に変更されました", 80 | "reset_api": "選択したAPIは利用できませんので、'{new}'に変更されました", 81 | "reset_model": "現在のモデルはAPIと互換性がないため、モデルが自動的に'{new}'に変更されました。", 82 | "reset_image_styles": "現在の画像スタイルは利用できません。したがって、自動的に{new}に変更されました。", 83 | "reset_imaginepy_styles": "現在のImagine.pyスタイルは利用できません。したがって、自動的に{new}に変更されました。", 84 | "reset_imaginepy_ratios": "現在のImagine.py比率は利用できません。したがって、自動的に{new}に変更されました。", 85 | "reset_imaginepy_models": "現在のImagine.pyモデルは利用できません。そのため、自動的に{new}に変更されました。", 86 | "genimagen_rejected": "🥲 あなたのリクエストはOpenAIの利用ポリシーに準拠していません...", 87 | "genimagen_other": "🥲 リクエストの処理中にエラーが発生しました。後でもう一度試してください...", 88 | "genimagen_badrequest": "🥲 リクエストにエラーが発生しました。メッセージのフォーマットと内容を確認してください...", 89 | "menu_api_no_disponible": "現在のAPI '{api_antigua}'は利用できません。したがって、自動的に '{api_nueva}'に変更されました。", 90 | "tiempoagotado": "時間切れです。", 91 | "ocr_no_extract": "画像からテキストを抽出できませんでした... 😔", 92 | "menu_modes_not_ready_yet": "メニューオプションはまだ準備ができていません...", 93 | "advertencia_tokens_excedidos": "トークンの数がモデルで許可される最大数を超えました。会話を続けるために、メッセージが最適化されたり削除されています。", 94 | "reintentos_alcanzados": "申し訳ありません。最大リトライ制限 {reintentos} に達しました" 95 | } 96 | } -------------------------------------------------------------------------------- /locales/lang.zh.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "actual": "当前的", 4 | "name": "中文 🇨🇳", 5 | "description": "一种犹如山水画般的流动与变幻,文字和句子在千姿百态间自由驰骋,展现出无尽的想象空间。", 6 | "seleccion": "请选择一个可用的。", 7 | "bienvenida": "语言已更改!" 8 | }, 9 | "metagen": { 10 | "log": "日志", 11 | "documentos": "文档", 12 | "urls": "链接", 13 | "usuario": "用户", 14 | "mensaje": "消息", 15 | "contexto": "是的,我有读取文件、文档、链接和网页的能力。这些资源的信息将以('url': 'web_page_content')的格式附加到此消息中。我将使用这些内容来回答有关页面和文档的问题。如果问及超出上述文件或页面的问题,我被禁止产生幻觉。\n", 16 | "transcripcion_imagen": "图片转录", 17 | "paginas": "页", 18 | "parrafos": "段落", 19 | "configuracion": "当前设置", 20 | "api": "聊天API", 21 | "image_api": "图片API", 22 | "modelo": "模型", 23 | "chatmode": "聊天模式", 24 | "busquedaweb": "网络搜索", 25 | "tokens": "令牌", 26 | "tokensmax": "最大标记", 27 | "advertencia": "警告", 28 | "imaginepy_styles": "风格", 29 | "imaginepy_ratios": "比率", 30 | "imaginepy_actual_style": "StableHorde的当前样式", 31 | "imaginepy_actual_model": "StableHorde的当前模型" 32 | }, 33 | "apicheck": { 34 | "inicio": "执行API检查", 35 | "warning_chatbase": "警告... Chatbase上的API时间限制!", 36 | "connection": "成功连接到", 37 | "bad": "差", 38 | "total": "总计", 39 | "working": "正常", 40 | "dead": "停止" 41 | }, 42 | "commands": { 43 | "reset": "重置配置" 44 | }, 45 | "mensajes": { 46 | "bot_iniciado": "机器人已启动", 47 | "preguntar_descargar_fotos": "您想以最高质量下载照片吗? 它们将在{expirationtime}分钟后过期!", 48 | "fotos_ya_expiraron": "对不起,照片已过期。", 49 | "fotos_borradas_listo": "照片已被删除!", 50 | "ayuda_grupos": "您可以将机器人添加到任何群组聊天中,以帮助和娱乐参与者。\n\n操作步骤(请参阅下面的视频)\n1. 将机器人添加到群组聊天中\n2. 将其设置为管理员,以便它可以查看消息(其他权限可以受限)\n3. 您真棒!\n\n要在聊天中从机器人获得回复-请@标记它或回复其消息。\n例如:'请{bot_username} 为 Telegram 写一首诗'\n", 51 | "mensaje_semaforo": "⏳ 请等待上一条消息的回复或者您可以 /cancel 取消", 52 | "cancelado": "✅ 已取消", 53 | "nadacancelado": "没有要取消的内容...", 54 | "no_retry_mensaje": "没有可重试的消息 🤷‍♂️", 55 | "timeout_ask": "好久不见!我们开始新的对话吧?", 56 | "timeout_nodialog": "没有历史记录。开始新的对话 🤷‍♂️", 57 | "timeout_ask_false": "由于超时,开始新的对话。聊天模式 {chatmode}", 58 | "message_empty_handle": "🥲 您发送了一条空消息。请再试一次!", 59 | "image_ocr_ask": "🖼️ {ocresult}\n\n你想了解关于这个转录的任何信息吗?", 60 | "document_anotado_ask": "已标注 🫡 你想了解该文件的什么内容?", 61 | "url_anotado_ask": "注释 📝 您想了解页面的什么信息?", 62 | "genimagen_noargs": "在使用 命令后必须输入一些内容。", 63 | "genimagen_notext": "没有检测到文本以生成图像 😔" 64 | }, 65 | "errores": { 66 | "error": "错误", 67 | "error_inesperado": "发生了意外错误... 如果问题仍然存在,请使用 /new 开始一个新的对话", 68 | "handler_excepcion": "处理更新时出现异常", 69 | "handler_error_handler": "错误处理程序中存在某些错误", 70 | "utils_modelo_desconocido": "未知模型", 71 | "utils_chatbase_limit": "达到API限制,请稍后再试!", 72 | "utils_dialog_messages_0": "出错了... 要么没有对话消息,要么您选择了过高的最大令牌值", 73 | "pdf_pages_limit": "😬 该文档超过了 {paginas} 页的限制!只会读取前 {pdf_page_lim} 页。", 74 | "document_size_limit": "文件太大了({file_size_mb} MB)。限制是{file_max_size} MB。", 75 | "audio_size_limit": "💀 音频文件超过了{audio_max_size} MB的限制!", 76 | "url_size_limit": "获取网页内容出错", 77 | "url_size_exception": "来自网址的响应太大", 78 | "reset_chat_attributes": "由于配置中存在无效设置,因此已将所有值重置为默认值。", 79 | "reset_chat_mode": "您的聊天模式不可用,因此已更改为 '{new}'", 80 | "reset_api": "您选择的API不可用,因此已更改为 '{new}'", 81 | "reset_model": "您当前的模型与API不兼容,因此模型已自动更改为'{new}'。", 82 | "reset_image_styles": "您当前的图像样式不可用。因此,它已自动更改为{new}。", 83 | "reset_imaginepy_styles": "您当前的StableHorde样式不可用。因此,它已自动更改为{new}。", 84 | "reset_imaginepy_ratios": "您当前的StableHorde比率不可用。因此,它已自动更改为{new}。", 85 | "reset_imaginepy_models": "您当前的StableHorde模型不可用。因此,它已自动更改为{new}。", 86 | "genimagen_rejected": "🥲 您的请求不符合OpenAI的使用政策...", 87 | "genimagen_other": "🥲 处理您的请求时发生错误。请稍后再试...", 88 | "genimagen_badrequest": "🥲 请求发生错误。请检查您的消息的格式和内容...", 89 | "menu_api_no_disponible": "您当前的API '{api_antigua}'不可用。因此,它已自动更改为 '{api_nueva}'。", 90 | "tiempoagotado": "时间已耗尽。", 91 | "ocr_no_extract": "无法从图像中提取文本... 😔", 92 | "menu_modes_not_ready_yet": "菜单选项尚未准备好...", 93 | "advertencia_tokens_excedidos": "令牌数量超过了模型允许的最大值。为了继续对话,已优化或删除了消息。", 94 | "reintentos_alcanzados": "抱歉。已达到最大重试次数 {reintentos}" 95 | } 96 | } -------------------------------------------------------------------------------- /locales/props.json: -------------------------------------------------------------------------------- 1 | { 2 | "available_props": [ 3 | "api", 4 | "model", 5 | "chat_mode", 6 | "image_api", 7 | "lang" 8 | ], 9 | "info": { 10 | "api": { 11 | "name": { 12 | "es": "APIs 🔌", 13 | "ar": "واجهات برمجة التطبيقات 🔌", 14 | "en": "APIs 🔌", 15 | "jp": "API 🔌", 16 | "zh": "API 🔌", 17 | "de": "APIs 🔌", 18 | "fr": "APIs 🔌", 19 | "ru": "API 🔌", 20 | "pt": "APIs 🔌", 21 | "it": "API 🔌", 22 | "nl": "API's 🔌" 23 | } 24 | }, 25 | "model": { 26 | "name": { 27 | "es": "Modelos 🧠", 28 | "ar": "نماذج 🧠", 29 | "en": "Models 🧠", 30 | "jp": "モデル 🧠", 31 | "zh": "模型 🧠", 32 | "de": "Modelle 🧠", 33 | "fr": "Modèles 🧠", 34 | "ru": "Модели 🧠", 35 | "pt": "Modelos 🧠", 36 | "it": "Modelli 🧠", 37 | "nl": "Modellen 🧠" 38 | } 39 | }, 40 | "image_api": { 41 | "name": { 42 | "es": "Imágenes 🖼️", 43 | "ar": "صور 🖼️", 44 | "en": "Images 🖼️", 45 | "jp": "画像 🖼️", 46 | "zh": "图片 🖼️", 47 | "de": "Bilder 🖼️", 48 | "fr": "Images 🖼️", 49 | "ru": "Изображения 🖼️", 50 | "pt": "Imagens 🖼️", 51 | "it": "Immagini 🖼️", 52 | "nl": "Afbeeldingen 🖼️" 53 | } 54 | }, 55 | "chat_mode": { 56 | "name": { 57 | "es": "Modos de chat 💬", 58 | "ar": "أوضاع الدردشة 💬", 59 | "en": "Chat modes 💬", 60 | "jp": "チャットモード 💬", 61 | "zh": "聊天模式 💬", 62 | "de": "Chat-Modi 💬", 63 | "fr": "Modes de chat 💬", 64 | "ru": "Режимы чата 💬", 65 | "pt": "Modos de chat 💬", 66 | "it": "Modalità di chat 💬", 67 | "nl": "Chatmodi 💬" 68 | } 69 | }, 70 | "lang": { 71 | "name": { 72 | "es": "Idiomas 🇪🇸", 73 | "ar": "اللغات 🇦🇪", 74 | "en": "Languages 🇬🇧", 75 | "jp": "言語 🇯🇵", 76 | "zh": "语言 🇨🇳", 77 | "de": "Sprachen 🇩🇪", 78 | "fr": "Langues 🇫🇷", 79 | "ru": "Языки 🇷🇺", 80 | "pt": "Idiomas 🇵🇹", 81 | "it": "Lingue 🇮🇹", 82 | "nl": "Talen 🇳🇱" 83 | } 84 | } 85 | }, 86 | "imaginepy": { 87 | "available_options": [ 88 | "imaginepy_styles", 89 | "imaginepy_ratios", 90 | "imaginepy_models" 91 | ] 92 | }, 93 | "stablehorde": { 94 | "available_options": [ 95 | "stablehorde_models", 96 | "image_api_styles" 97 | ] 98 | } 99 | } -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | openai 2 | python-telegram-bot[rate-limiter]>=20.6 3 | PyPDF2 4 | pytesseract 5 | html2text 6 | motor 7 | duckduckgo_search 8 | python-dotenv 9 | nltk 10 | langdetect 11 | #imaginepy 12 | docstring_parser 13 | python_weather 14 | tiktoken 15 | ujson -------------------------------------------------------------------------------- /static/help_group_chat.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soyelmismo/chatgpTG/de03ee59e2a1eb8a314cced59625ea73b2e40a27/static/help_group_chat.mp4 --------------------------------------------------------------------------------