<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://sergioberdiales.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sergioberdiales.github.io/" rel="alternate" type="text/html" /><updated>2026-10-22T20:43:13+00:00</updated><id>https://sergioberdiales.github.io/feed.xml</id><title type="html">Datos, fotos y otras cosas</title><subtitle>Esta es mi pagína personal, donde iré dejando notas de cosas que me interesan.</subtitle><author><name>Sergio Berdiales</name></author><entry><title type="html">Automatizando tuits con ChatGPT</title><link href="https://sergioberdiales.github.io/aprendiendo/generando-tweets-chatgpt/" rel="alternate" type="text/html" title="Automatizando tuits con ChatGPT" /><published>2024-10-01T21:06:00+00:00</published><updated>2024-10-01T21:06:00+00:00</updated><id>https://sergioberdiales.github.io/aprendiendo/generando-tweets-chatgpt</id><content type="html" xml:base="https://sergioberdiales.github.io/aprendiendo/generando-tweets-chatgpt/"><![CDATA[<p>Este fin de semana me animé a experimentar un poco con algunas APIs y terminé construyendo un pequeño sistema que automatiza la creación y publicación de tuits. La idea era aprender y, de paso, mostrar cómo ahora mismo, con las nuevas herramientas de IA generativa, cualquiera puede crear cosas que hace nada eran imposibles o muy costosas en tiempo.</p>

<p><a href="https://platform.openai.com/docs/overview?lang=python" target="_blank">
  <img src="/assets/images/2024-10-02_221703_openai_developer_platform.jpg" alt="Tuit generado por ChatGPT" />
</a></p>

<p>Mi idea inicial era, con la ayuda de ChatGPT, automatizar un resumen de los tuits de algún tuitero al que sigo, pero el modo de acceso gratuito a la API de Twitter no te lo permite. Actualmente solo te deja consultar la información de tu perfil o publicar tuits.</p>

<p>Así que le planteé a ChatGPT construir un código en Python que hiciese lo siguiente:</p>

<ul>
  <li>Buscar noticias recientes sobre <strong>OpenAI</strong>.</li>
  <li><strong>Generar un tuit</strong> atractivo, breve y con hashtags que se ajustasen al tema usando la API de ChatGPT.</li>
  <li><strong>Publicar el tuit</strong> generado por ChatGPT con la API de Twitter.</li>
</ul>

<p><a href="https://x.com/SergioBerdiales/status/1841566950050123868" target="_blank">
  <img src="/assets/images/2024-10-02_215604_tuit_automatizado.jpg" alt="Tuit generado por ChatGPT" />
</a></p>

<p>A la vez le pedí que me sugiriera formas de hacerlo fácil y sin costo. Así fue cómo, por ejemplo, me propuso usar el “feed” RSS de Google News para recuperar alguna noticia actual sobre <strong>OpenAI</strong> o utilizar <strong>Bitly</strong> para acortar los enlaces. ¡Grandes aportes!</p>

<p>A partir de ahí, la creación del código fue un proceso iterativo de prueba y error, con muy pocos errores por parte de ChatGPT, por cierto.</p>

<p>Una gozada. El ratio esfuerzo / resultado cada vez es más pequeño. Algunos que saben de esto dicen que en un futuro no habrá ni aplicaciones. Interaccionaremos con una capa de IA que en tiempo real irá generando todo lo que deseemos. Fascinante e inquietante a la vez.</p>

<p>Dejo por aquí el código Python final para los curiosos.</p>

<h3 id="código-python">Código Python</h3>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">feedparser</span>
<span class="kn">import</span> <span class="nn">openai</span>
<span class="kn">from</span> <span class="nn">openai</span> <span class="kn">import</span> <span class="n">OpenAI</span>
<span class="kn">import</span> <span class="nn">bitlyshortener</span>
<span class="kn">import</span> <span class="nn">tweepy</span>
<span class="kn">from</span> <span class="nn">tweepy.errors</span> <span class="kn">import</span> <span class="n">TweepyException</span>

<span class="c1"># Claves y tokens de las APIs
# OpenAI
</span><span class="n">openai_api_key</span> <span class="o">=</span> <span class="s">'TU_API_KEY_OPENAI'</span>

<span class="c1"># Bitly
</span><span class="n">bitly_tokens</span> <span class="o">=</span> <span class="p">[</span><span class="s">'TU_BITLY_TOKEN'</span><span class="p">]</span>

<span class="c1"># Twitter
</span><span class="n">consumer_key</span> <span class="o">=</span> <span class="s">'TU_CONSUMER_KEY_TWITTER'</span>
<span class="n">consumer_secret</span> <span class="o">=</span> <span class="s">'TU_CONSUMER_SECRET_TWITTER'</span>
<span class="n">access_token</span> <span class="o">=</span> <span class="s">'TU_ACCESS_TOKEN_TWITTER'</span>
<span class="n">access_token_secret</span> <span class="o">=</span> <span class="s">'TU_ACCESS_SECRET_TWITTER'</span>

<span class="c1"># Paso 1: Obtener la noticia de Google News
</span><span class="n">feed_url</span> <span class="o">=</span> <span class="s">"https://news.google.com/rss/search?q=OpenAI&amp;hl=en&amp;gl=US&amp;ceid=US:en"</span>
<span class="n">feed</span> <span class="o">=</span> <span class="n">feedparser</span><span class="p">.</span><span class="n">parse</span><span class="p">(</span><span class="n">feed_url</span><span class="p">)</span>

<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">feed</span><span class="p">.</span><span class="n">entries</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
    <span class="n">first_entry</span> <span class="o">=</span> <span class="n">feed</span><span class="p">.</span><span class="n">entries</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
    <span class="n">title</span> <span class="o">=</span> <span class="n">first_entry</span><span class="p">.</span><span class="n">title</span>
    <span class="n">link</span> <span class="o">=</span> <span class="n">first_entry</span><span class="p">.</span><span class="n">link</span>
<span class="k">else</span><span class="p">:</span>
    <span class="k">print</span><span class="p">(</span><span class="s">"No se encontraron noticias sobre 'OpenAI'."</span><span class="p">)</span>
    <span class="nb">exit</span><span class="p">()</span>

<span class="c1"># Paso 2: Acortar el enlace con Bitly
</span><span class="n">shortener</span> <span class="o">=</span> <span class="n">bitlyshortener</span><span class="p">.</span><span class="n">Shortener</span><span class="p">(</span><span class="n">tokens</span><span class="o">=</span><span class="n">bitly_tokens</span><span class="p">,</span> <span class="n">max_cache_size</span><span class="o">=</span><span class="mi">256</span><span class="p">)</span>
<span class="n">enlace_acortado</span> <span class="o">=</span> <span class="n">shortener</span><span class="p">.</span><span class="n">shorten_urls</span><span class="p">([</span><span class="n">link</span><span class="p">])[</span><span class="mi">0</span><span class="p">]</span>

<span class="c1"># Paso 3: Generar el tuit con OpenAI
</span><span class="n">client</span> <span class="o">=</span> <span class="n">OpenAI</span><span class="p">(</span><span class="n">api_key</span><span class="o">=</span><span class="n">openai_api_key</span><span class="p">)</span>
<span class="n">prompt</span> <span class="o">=</span> <span class="p">(</span>
    <span class="sa">f</span><span class="s">"Genera un tuit breve y llamativo sobre esta noticia titulada '</span><span class="si">{</span><span class="n">title</span><span class="si">}</span><span class="s">'. "</span>
    <span class="sa">f</span><span class="s">"Incluye el enlace acortado: </span><span class="si">{</span><span class="n">enlace_acortado</span><span class="si">}</span><span class="s">. "</span>
    <span class="s">"Añade los hashtags: #OpenAI #IA #GeneradoPorIA. Mantén el tuit por debajo de 280 caracteres."</span>
<span class="p">)</span>

<span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="p">.</span><span class="n">chat</span><span class="p">.</span><span class="n">completions</span><span class="p">.</span><span class="n">create</span><span class="p">(</span>
    <span class="n">model</span><span class="o">=</span><span class="s">"gpt-4o-mini"</span><span class="p">,</span>
    <span class="n">messages</span><span class="o">=</span><span class="p">[{</span><span class="s">"role"</span><span class="p">:</span> <span class="s">"user"</span><span class="p">,</span> <span class="s">"content"</span><span class="p">:</span> <span class="n">prompt</span><span class="p">}],</span>
    <span class="n">max_tokens</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
    <span class="n">temperature</span><span class="o">=</span><span class="mf">0.7</span>
<span class="p">)</span>
<span class="n">tuit</span> <span class="o">=</span> <span class="n">response</span><span class="p">.</span><span class="n">choices</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">message</span><span class="p">.</span><span class="n">content</span><span class="p">.</span><span class="n">strip</span><span class="p">()</span>

<span class="c1"># Paso 4: Publicar el tuit con Tweepy
</span><span class="n">auth</span> <span class="o">=</span> <span class="n">tweepy</span><span class="p">.</span><span class="n">OAuth1UserHandler</span><span class="p">(</span>
    <span class="n">consumer_key</span><span class="p">,</span> <span class="n">consumer_secret</span><span class="p">,</span>
    <span class="n">access_token</span><span class="p">,</span> <span class="n">access_token_secret</span>
<span class="p">)</span>
<span class="n">client_twitter</span> <span class="o">=</span> <span class="n">tweepy</span><span class="p">.</span><span class="n">Client</span><span class="p">(</span>
    <span class="n">consumer_key</span><span class="o">=</span><span class="n">consumer_key</span><span class="p">,</span>
    <span class="n">consumer_secret</span><span class="o">=</span><span class="n">consumer_secret</span><span class="p">,</span>
    <span class="n">access_token</span><span class="o">=</span><span class="n">access_token</span><span class="p">,</span>
    <span class="n">access_token_secret</span><span class="o">=</span><span class="n">access_token_secret</span>
<span class="p">)</span>

<span class="k">try</span><span class="p">:</span>
    <span class="n">response_twitter</span> <span class="o">=</span> <span class="n">client_twitter</span><span class="p">.</span><span class="n">create_tweet</span><span class="p">(</span><span class="n">text</span><span class="o">=</span><span class="n">tuit</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="s">'Tweet publicado exitosamente.'</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'ID del Tweet: </span><span class="si">{</span><span class="n">response_twitter</span><span class="p">.</span><span class="n">data</span><span class="p">[</span><span class="s">"id"</span><span class="p">]</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
<span class="k">except</span> <span class="n">TweepyException</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Error al publicar el tweet: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="n">response</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span> <span class="ow">and</span> <span class="n">e</span><span class="p">.</span><span class="n">response</span><span class="p">.</span><span class="n">text</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
        <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">'Detalles del error: </span><span class="si">{</span><span class="n">e</span><span class="p">.</span><span class="n">response</span><span class="p">.</span><span class="n">text</span><span class="si">}</span><span class="s">'</span><span class="p">)</span>

</code></pre></div></div>]]></content><author><name>Sergio Berdiales</name></author><category term="aprendiendo" /><summary type="html"><![CDATA[Este fin de semana me animé a experimentar un poco con algunas APIs y terminé construyendo un pequeño sistema que automatiza la creación y publicación de tuits. La idea era aprender y, de paso, mostrar cómo ahora mismo, con las nuevas herramientas de IA generativa, cualquiera puede crear cosas que hace nada eran imposibles o muy costosas en tiempo.]]></summary></entry><entry><title type="html">Probando Claude 3.5 Sonnet</title><link href="https://sergioberdiales.github.io/aprendiendo/probando-claude-35-sonnet/" rel="alternate" type="text/html" title="Probando Claude 3.5 Sonnet" /><published>2024-08-25T16:27:00+00:00</published><updated>2024-08-25T16:27:00+00:00</updated><id>https://sergioberdiales.github.io/aprendiendo/probando-claude-35-sonnet</id><content type="html" xml:base="https://sergioberdiales.github.io/aprendiendo/probando-claude-35-sonnet/"><![CDATA[<p>El otro día se me ocurrió hacer una pequeña aplicación web para que mi hija practicase de forma divertida la multiplicación. Y aproveché para probar el nuevo modelo de Anthropic, Claude 3.5 Sonnet.</p>

<p><a href="https://www.anthropic.com/news/claude-3-5-sonnet"><img src="/assets/images/2024-08-25 164436_claude_35_sonnet.png" alt="Claude 3.5 Sonnet" /></a></p>

<p>Y es que desde que este modelo apareció a finales de junio pasado, se dice que es el mejor modelo del mercado, por delante de ChatGpt 4o.</p>

<p>No sé decir si Sonnet es superior o no a ChatGpt 4o en términos de potencia o rendimiento, pero lo que está clarísimo es que la interfaz de Claude 3.5 Sonnet es muchísimo mejor. Y eso es muy importante.</p>

<p>La mejora de la interfaz viene de algo tan sencillo como la de dividir verticalmente la pantalla en dos. A la izquierda tenemos nuestros prompts y las respuestas. Y a la derecha podemos ver el código resultante y, aquí es donde va la novedad importante, la previsualización del resultado final. En este caso podía ver el aspecto de la aplicación según se iba construyendo, lo que no se puede hacer con ChatGpt. Cuando hago este tipo de cosas con ChatGpt, lo que tengo que ir haciendo es copiar el código resultante, pegarlo en un archivo en local y ejecutarlo en un entorno compatible, lo que dispara la fricción con la aplicación y dificulta la iteración, básica en este tipo de procesos.</p>

<p><img src="/assets/images/2024-08-25_164436_interfaz_usuario_claude.jpg" alt="Interfaz de usuario de Claude 3.5 Sonnet" /></p>

<p>Al final tuve que acabar la aplicación con la ayuda de ChatGpt porque el límite de la versión gratuita de Sonnet 3.5 no dio para mucho. Pero Sonnet me dejó una gran sabor de boca. A ver si OpenAI se pone las pilas y mejora este aspecto, que no parece algo tan difícil.</p>

<p>Por si tienes curiosidad aquí dejo la aplicación. Solo tienes que pinchar en la siguiente imagen. Creo que quedó resultona, sobre todo para el poco tiempo que le pude dedicar.</p>

<p><a href="https://sergioberdiales.github.io/juegos/juego_multiplicacion/index.html"><img src="/assets/images/2024-08-26_212618_juego_multiplicar.jpg" alt="Juego de multiplicar" /></a></p>]]></content><author><name>Sergio Berdiales</name></author><category term="aprendiendo" /><summary type="html"><![CDATA[El otro día se me ocurrió hacer una pequeña aplicación web para que mi hija practicase de forma divertida la multiplicación. Y aproveché para probar el nuevo modelo de Anthropic, Claude 3.5 Sonnet.]]></summary></entry><entry><title type="html">Mi primera entrada</title><link href="https://sergioberdiales.github.io/aprendiendo/primera-entrada/" rel="alternate" type="text/html" title="Mi primera entrada" /><published>2024-08-10T22:41:58+00:00</published><updated>2024-08-10T22:41:58+00:00</updated><id>https://sergioberdiales.github.io/aprendiendo/primera-entrada</id><content type="html" xml:base="https://sergioberdiales.github.io/aprendiendo/primera-entrada/"><![CDATA[<p>Esta es mi primera entrada en Github Pages. ¿Impresionante, eh?
De aquí en adelante esto solo puede mejorar.</p>

<p>Os dejo una foto de unos gorriones.</p>

<p><img src="/assets/images/2024-08-11_gorriones_IMG_1377.jpg" alt="Unos gorriones" /></p>

<p>La IA, vaya flipe.</p>

<p>No quiero confundiros. La foto es real. No es IA.</p>

<p>Tengo que trabajar más mi forma de expresarme por escrito.</p>

<p>¡Hasta mi próxima entrada!</p>]]></content><author><name>Sergio Berdiales</name></author><category term="aprendiendo" /><summary type="html"><![CDATA[Esta es mi primera entrada en Github Pages. ¿Impresionante, eh? De aquí en adelante esto solo puede mejorar.]]></summary></entry></feed>