{"id":391,"date":"2023-02-19T23:54:01","date_gmt":"2023-02-20T04:54:01","guid":{"rendered":"https:\/\/80bits.blog\/?p=391"},"modified":"2023-02-20T00:53:58","modified_gmt":"2023-02-20T05:53:58","slug":"bot-de-telegram-con-chat-gpt-3","status":"publish","type":"post","link":"https:\/\/80bits.blog\/index.php\/2023\/02\/19\/bot-de-telegram-con-chat-gpt-3\/","title":{"rendered":"GPT-3. Bot de Telegram"},"content":{"rendered":"\n<p>La semana pasada vi una publicaci\u00f3n sobre una plataforma o mas bien un pseudo contacto de whatsapp llamada <a href=\"https:\/\/godinabox.co\/\" target=\"_blank\" rel=\"noreferrer noopener\">God in a Box<\/a>, b\u00e1sicamente te crea un chat personal con un bot de chat GPT-3.<\/p>\n\n\n\n<p>God in a Box se ve interesante, el problema es la limitaci\u00f3n de solo poder enviar 10 mensajes de manera gratuita o pagar 10 dolares al mes, muy caro a mi gusto pero es una buena opci\u00f3n.<\/p>\n\n\n\n<p>El bot es muy sencillo de usar simplemente le env\u00edas texto y la AI de Chat GPT-3 hace el resto, por otro lado hacer un bot para Telegram es mas sencillo aun, para hacer uno hay que usar otro bot y listo.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Crear un bot de Telegram<\/h2>\n\n\n\n<p>Crear un bot para Telegram es  sencillo, solo hay que hacer uso de BotFather (un bot para crear bots) <a href=\"https:\/\/t.me\/BotFather\">@BotFather<\/a>, no voy a entrar en detalles pero solo hay que seguir los pasos, elegir un nombre, una descripci\u00f3n y tal vez una foto de perfil y eso es todo.<\/p>\n\n\n\n<p>Lo que no es sencillo es darle funcionalidad para ello hay que hacer uso de las apis de Telegram y tambi\u00e9n desarrollar un servicio rest para recibir los mensajes del bot, as\u00ed como fotos archivos y todo lo que puede enviar y recibir un chat de Telegram, <a rel=\"noreferrer noopener\" href=\"https:\/\/core.telegram.org\/bots\/api\" target=\"_blank\">aqu\u00ed pueden revisar la documentaci\u00f3n de las apis<\/a>.<\/p>\n\n\n\n<p>Una vez creado el bot con BotFather, lo que recibes es una key para acceder al bot y darle funcionalidad, hay dos maneras una mediante muchas llamadas a la api de Telegram <a rel=\"noreferrer noopener\" href=\"https:\/\/core.telegram.org\/bots\/api#getting-updates\" target=\"_blank\">(documentaci\u00f3n aqu\u00ed)<\/a>, lo que es muy ineficiente y la otra decirle a Telegram que te envi\u00e9 los mensajes a tu propio servicio <a rel=\"noreferrer noopener\" href=\"https:\/\/core.telegram.org\/bots\/api#setwebhook\" target=\"_blank\">(documentaci\u00f3n aqu\u00ed)<\/a>.<\/p>\n\n\n\n<p>Para este caso use la segunda opci\u00f3n.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"549\" height=\"425\" src=\"https:\/\/80bits.blog\/wp-content\/uploads\/2023\/02\/image.png\" alt=\"\" class=\"wp-image-403\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Chat GPT<\/h2>\n\n\n\n<p>Chat GPT se ha vuelvo muy relevante en las ultimas semanas por todas las funcionalidades y usos que se le puede dar, uno de estos usos es el chat donde puedes preguntarle a la IA casi cualquier cosa con resultados bastantes sorprendentes. <\/p>\n\n\n\n<p>Puedes usar el chat en <a href=\"https:\/\/chat.openai.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">esta direcci\u00f3n<\/a> aun que con ciertas limitaciones debido a la alta demanda del mismo.<\/p>\n\n\n\n<p>La otra opci\u00f3n es pagando por el acceso a sus apis lo cual no es nada barato si se usa de manera intensiva, no es este el objetivo del bot, ademas si te registras por primera vez te regalan 18 dolares. Los precios se pueden consultar <a rel=\"noreferrer noopener\" href=\"https:\/\/openai.com\/api\/pricing\/\" target=\"_blank\">aqu\u00ed.<\/a><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" width=\"1537\" height=\"555\" src=\"https:\/\/80bits.blog\/wp-content\/uploads\/2023\/02\/image-1.png\" alt=\"\" class=\"wp-image-406\" title=\"chat gtp models\"\/><\/figure>\n<\/div>\n\n\n<p>Como ven en la captura, los precios var\u00edan en funci\u00f3n del modelo y se cobra por cada 1000 tokens, siendo Davinci el mas caro y el mas capaz, aproximadamente 750 palabras equivalen a 1000 tokens de uso por lo que dependiendo de lo que le preguntes y lo que te responda se har\u00e1n uso de mas o menos tokens.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Apis de OpenAI GPT-3<\/h2>\n\n\n\n<p>Las apis de OpenAI GPT-3 tienen soporte para Python, NodeJS y llamadas directas por http rest, pero indagando vi que al final las librer\u00edas solo son un wrapper para esto ultimo.<\/p>\n\n\n\n<p>Yo use las de NodeJS, pero es probable que use directamente las llamadas Rest ya que detecte ciertos errores que no eran controlados por mi c\u00f3digo y prefiero controlarlos, de todos modos estas librer\u00edas usan <a rel=\"noreferrer noopener\" href=\"https:\/\/axios-http.com\/\" target=\"_blank\">Axios<\/a> por detr\u00e1s al igual que el c\u00f3digo para comunicarme con las apis de Telegram.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/80bits.blog\/wp-content\/uploads\/2023\/02\/image-2-1024x968.png\" alt=\"Chat GPT-3, ejemplo codigo nodejs\" class=\"wp-image-410\" width=\"512\" height=\"484\"\/><\/figure>\n\n\n\n<p>La captura de arriba es una porci\u00f3n del c\u00f3digo de ejemplo, pueden ver la <a href=\"https:\/\/platform.openai.com\/docs\/api-reference\/completions\/create\" target=\"_blank\" rel=\"noreferrer noopener\">documentaci\u00f3n aqu\u00ed<\/a>.<\/p>\n\n\n\n<p>Las partes mas importantes son:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>model<\/strong>: el modelo de IA que quieras utilizar.<\/li>\n\n\n\n<li><strong>prompt<\/strong>: texto que se le envia a la IA ya sea una pregunta o cualquier cosa que se te ocurra.<\/li>\n\n\n\n<li><strong>temperature<\/strong>: b\u00e1sicamente es la manera en que la IA te dar\u00e1 respuestas, un valor 0 significa que obtendr\u00e1s respuestas mas concisas y menos creativas y seg\u00fan la documentaci\u00f3n 0.9 ser\u00e1n respuestas algo mas creativas.<\/li>\n\n\n\n<li><strong>max_token<\/strong>: esta es la mas importante por que limitara el uso excesivo de tokens lo que conlleva un riesgo menor de pagar demasiado dinero, pero tambi\u00e9n puede ser que obtendr\u00e1s respuestas cortadas literalmente.  <\/li>\n<\/ul>\n\n\n\n<p>Hay otras propiedades que yo use, como <strong>stop<\/strong> o <strong>user<\/strong>, este ultimo sirve para que los servicios de OpenAI puedan identificar abusos y quien esta enviando los mensajes.<\/p>\n\n\n\n<p>La api que se usa es la de <strong>&#8220;completion<\/strong>&#8220;, no es la misma que usa la plataforma de chat, es mas bien una api para generar texto o dar sugerencias, pero el bot y &#8220;chat&#8221; no recuerda nada ni tiene contexto de conversaciones como la plataforma de OpenAI.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">C\u00f3digo Fuente<\/h2>\n\n\n\n<p>Este proyecto no tiene mas pretensiones que diversi\u00f3n, por lo que si bien es funcional no esperen funcionalidades extras ni nada, simplemente le env\u00edas un texto al bot y este texto se env\u00eda a Chat GPT-3 y te da una respuesta.<\/p>\n\n\n\n<p>Pueden clonar el c\u00f3digo fuente <a href=\"https:\/\/github.com\/genitalico\/telegram-gpt3\" target=\"_blank\" rel=\"noreferrer noopener\">aqu\u00ed.<\/a><\/p>\n\n\n\n<p>No esta desarrollado bajo ning\u00fan framework tipo <a rel=\"noreferrer noopener\" href=\"https:\/\/expressjs.com\/\" target=\"_blank\">Express<\/a>, esta en vanillaJS usando directamente las apis de NodeJS, <a rel=\"noreferrer noopener\" href=\"https:\/\/80bits.blog\/index.php\/2022\/01\/27\/net-6-minimal-api-rest\/\" target=\"_blank\">un ejemplo aqu\u00ed<\/a>.<\/p>\n\n\n\n<p>Instalar dependencias.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ npm install<\/code><\/pre>\n\n\n\n<p>Para levantar el servicio hay que ejecutar el archivo <strong>index.js<\/strong>, el cual se ejecuta en el puerto <strong>3000<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ node index.js<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Variables de entorno<\/h3>\n\n\n\n<p>El c\u00f3digo tiene unas variables de entorno para poder cambiar ciertas configuraciones sin tener que desplegar o reescribir nuevamente.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>ALLOWED_USERS<\/strong>: string separado por comas donde est\u00e1n los id de usuario permitidos en el bot.<\/li>\n\n\n\n<li><strong>OPENAI_MODEL<\/strong>: nombre del modelo GPT-3 a usar, por defecto davinci.<\/li>\n\n\n\n<li><strong>OPENAI_API_KEY<\/strong>: api key para poder acceder a los servicios de openAI.<\/li>\n\n\n\n<li><strong>OPENAI_MAX_TOKENS<\/strong>: numero m\u00e1ximo permitido de tokens al momento de usar las apis, por defecto 60 tokens.<\/li>\n\n\n\n<li><strong>OPENAI_FREQUENCY_PENALTY<\/strong>: por defecto 0.<\/li>\n\n\n\n<li><strong>OPENAI_PRESENCE_PENALTY<\/strong>: por defecto 0.<\/li>\n\n\n\n<li><strong>TELEGRAM_BOT_TOKEN<\/strong>: el api del bot de Telegram para el acceso a los servicios de Telegram.<\/li>\n<\/ul>\n\n\n\n<p>Las variables se pueden configurar como desees simplemente siguiendo los lineamientos de Telegram y Chat GPT-3.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Request Methods<\/h3>\n\n\n\n<p>El servicio solo consta de un m\u00e9todo funcional que es el m\u00e9todo <strong>post<\/strong> en la ruta <strong>\/update<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl --location --request POST 'http:\/\/localhost:3000\/update' \\\n--header 'Content-Type: application\/json' \\<\/code><\/pre>\n\n\n\n<p><strong>El path update retorna un json con tres propiedades:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"telegramIn\": {} \/\/objeto de entrada, es el objeto que envia telegram,\n\"telegramOut\": {} \/\/objeto que retorna las apis de telegram,\n\"openAI\": {} \/\/objeto que retorna las apis de openai,\n\"errors\": [] \/\/array de mensajes de errores<\/code><\/pre>\n\n\n\n<p>El m\u00e9todo GET solo funciona en el index y es para obtener &#8220;algo&#8221; lo \u00fanico que retorna es Not Found 404.<\/p>\n\n\n\n<p>Quien aplica esta l\u00f3gica es un switch dentro del index que se encarga de revisar que verbo http es el que llega en el request.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">L\u00f3gica<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">index.js<\/h4>\n\n\n\n<p>Archivo que tiene el objeto que crea el servicio http, solo tiene un switch para determinar el verbo http y la l\u00f3gica a ejecutar.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>update.js<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>telegramUpdate<\/strong>: m\u00e9todo expuesto que se usa en el archivo index.js y solo recibe el objeto body que env\u00eda Telegram, la estructura se encuentra <a href=\"https:\/\/core.telegram.org\/bots\/api#available-types\" target=\"_blank\" rel=\"noreferrer noopener\">aqu\u00ed<\/a>.<\/li>\n\n\n\n<li><strong>openaiComplete<\/strong>: m\u00e9todo donde se env\u00eda los datos hacia OpenAI, basicamente el texto que interpretara la AI.<\/li>\n\n\n\n<li><strong>telegramSendMsg<\/strong>: l\u00f3gica donde se env\u00eda la respuesta de GPT-3 hacia el usuario que uso el bot en Telegram, puede enviar cualquier texto hacia cualquier usuario de Telegram usando su ID de usuario.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">constants.js<\/h4>\n\n\n\n<p>Este es un archivo muy simple que tiene un objeto con propiedades donde se guardaran las variables de entorno, que luego puedan ser usados en cualquier parte del c\u00f3digo.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">updatePayload.json<\/h4>\n\n\n\n<p>Contiene ejemplos de entradas y salidas para los test unitarios. Tambi\u00e9n se pueden copiar estas propiedades json para probar mediante alguna app como <a rel=\"noreferrer noopener\" href=\"https:\/\/www.postman.com\/\" target=\"_blank\">Postman<\/a> el servicio.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Comandos<\/h3>\n\n\n\n<p><strong>Iniciar servicio.<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ npm run start<\/code><\/pre>\n\n\n\n<p><strong>Ejecutar test unitarios<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ npm run tests<\/code><\/pre>\n\n\n\n<p>Ejecutar fix prettier<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ npm run prettier.w<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Hoja de ruta<\/h2>\n\n\n\n<p>El c\u00f3digo como mencione antes no tiene mas pretensiones que diversi\u00f3n y tener mi propio asistente en Telegram, pero tengo algunas ideas para ampliar las funcionalidades.<\/p>\n\n\n\n<p>Actualmente el servicio lo tengo montado en la nube de Azure mediante el servicio de <a rel=\"noreferrer noopener\" href=\"https:\/\/azure.microsoft.com\/en-us\/products\/app-service\/web\/\" target=\"_blank\">Web Apps<\/a>, en la <a rel=\"noreferrer noopener\" href=\"https:\/\/azure.microsoft.com\/en-us\/pricing\/details\/app-service\/windows\/#pricing\" target=\"_blank\">capa gratuita<\/a> que da 60 minutos de uso de cpu al d\u00eda, lo cual es mas que suficiente para un uso personal y normal del bot.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Integrar Mongodb para guardar la salida del path update, esto a modo de registro de logs.<\/li>\n\n\n\n<li>Faltan test unitarios para algunos bloques de c\u00f3digo, como el de los errores.<\/li>\n\n\n\n<li>Cuando las apis de Chat GPT sean publicas tal vez las implemente aqu\u00ed. (recuerden que el bot implementa completion, no es el mismo del chat).<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>La semana pasada vi una publicaci\u00f3n sobre una plataforma o mas bien un pseudo contacto de whatsapp llamada God in a Box, b\u00e1sicamente te crea un chat personal con un bot de chat GPT-3. God in a Box se ve interesante, el problema es la limitaci\u00f3n de solo poder enviar 10 mensajes de manera gratuita [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":394,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"jetpack_post_was_ever_published":true,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[72,64,29,31],"tags":[69,70,32,71,5],"class_list":["post-391","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-chat-gpt3","category-microservicios","category-nodejs","category-telegram","tag-chat","tag-gtp3","tag-nodejs","tag-service","tag-telegram"],"jetpack_featured_media_url":"https:\/\/80bits.blog\/wp-content\/uploads\/2023\/02\/pexels-photo-8728560.jpeg","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/posts\/391","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/comments?post=391"}],"version-history":[{"count":87,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/posts\/391\/revisions"}],"predecessor-version":[{"id":485,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/posts\/391\/revisions\/485"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/media\/394"}],"wp:attachment":[{"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/media?parent=391"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/categories?post=391"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/80bits.blog\/index.php\/wp-json\/wp\/v2\/tags?post=391"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}