<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Sqlite on Christian Martínez De La Rosa</title><link>https://christt105.github.io/ca/tags/sqlite/</link><description>Recent content in Sqlite on Christian Martínez De La Rosa</description><generator>Hugo -- gohugo.io</generator><language>ca</language><lastBuildDate>Wed, 28 Oct 2026 00:00:00 +0100</lastBuildDate><atom:link href="https://christt105.github.io/ca/tags/sqlite/index.xml" rel="self" type="application/rss+xml"/><item><title>InformadoRSS</title><link>https://christt105.github.io/ca/projects/informadorss/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://christt105.github.io/ca/projects/informadorss/</guid><enclosure url="https://christt105.github.io/projects/informadorss/cover.webp" length="34178" type="image/webp"/><description>&lt;p&gt;&lt;code&gt;InformadoRSS&lt;/code&gt; és un servei lleuger i self-hosted que vigila feeds RSS i Atom, filtra els seus elements per ruta i els lliura a canals de Discord o a &lt;a class="link" href="https://ntfy.sh/" target="_blank" rel="noopener"&#10; &gt;ntfy&lt;/a&gt;. Funciona en un únic contenidor: un binari en C# amb .NET 10 compilat amb NativeAOT que serveix una interfície web en Vue 3 i ho guarda tot a SQLite. Només parla amb Discord a través de l&amp;rsquo;API REST del bot (sense gateway ni comandes). És de codi obert amb llicència MIT.&lt;/p&gt;&#10;&lt;p&gt;Característiques principals:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Feeds i rutes&lt;/strong&gt;: Un feed és una URL; cada feed té rutes amb un filtre, un o diversos destins (Discord o ntfy) i una plantilla de missatge.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Constructor de filtres i editor de plantilles&lt;/strong&gt;: Crea els filtres i edita els missatges des de la interfície web en lloc d&amp;rsquo;escriure&amp;rsquo;ls a mà.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Selector de servidor i canal de Discord&lt;/strong&gt;: Tria els destins pel nom i comprova en quins canals no pot publicar el bot.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Alertes&lt;/strong&gt;: Un avís quan un feed o un destí es trenca i un altre quan es recupera, per Discord o ntfy.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Còpies de seguretat diàries&lt;/strong&gt;: Còpies programades de la base de dades en una carpeta, conservant les més recents.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Importador de MonitoRSS&lt;/strong&gt;: Importa feeds i rutes des d&amp;rsquo;una exportació de MonitoRSS, amb simulació i un canal de proves per comparar els missatges abans de canviar.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Patró d&amp;rsquo;identitat per a feeds que reescriuen entrades&lt;/strong&gt;: Una expressió regular sobre la descripció que s&amp;rsquo;afegeix a l&amp;rsquo;id de l&amp;rsquo;element, així un canvi d&amp;rsquo;estat en una llista de MyAnimeList compta com a element nou.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Explico com i per què el vaig fer en &lt;a class="link" href="https://christt105.github.io/ca/blog/informadorss/" &gt;el post del blog&lt;/a&gt;. La imatge es publica a &lt;code&gt;ghcr.io/christt105/informadorss&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="L’editor de rutes: filtre, plantilla del missatge i canal de destí" class="gallery-image" data-flex-basis="252px" data-flex-grow="105" height="1994" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://christt105.github.io/projects/informadorss/web-route.webp" srcset="https://christt105.github.io/projects/informadorss/web-route_hu_a1005d249803043c.webp 800w, https://christt105.github.io/projects/informadorss/web-route_hu_458b51e51904d625.webp 1600w, https://christt105.github.io/projects/informadorss/web-route.webp 2100w" width="2100"&gt;&lt;/p&gt;&#10;</description></item><item><title>InformadoRSS: substituint MonitoRSS</title><link>https://christt105.github.io/ca/blog/informadorss/</link><pubDate>Wed, 28 Oct 2026 00:00:00 +0100</pubDate><guid>https://christt105.github.io/ca/blog/informadorss/</guid><enclosure url="https://christt105.github.io/blog/informadorss/cover.png" length="429533" type="image/png"/><description>&lt;p&gt;Hola una altra vegada!&lt;/p&gt;&#10;&lt;p&gt;Tinc un parell de servidors de Discord on un bot avisa de les entrades noves de blogs, vídeos de YouTube, newsletters i de les llistes d&amp;rsquo;anime i manga dels meus amics. Durant anys això ho va fer MonitoRSS. Funciona, però són nou contenidors (diversos serveis en Node, Mongo, Postgres, RabbitMQ&amp;hellip;) i uns 670 MB de RAM per mirar cada deu minuts si hi ha alguna cosa nova en uns quants feeds. En un servidor casolà que ja té Jellyfin i mitja dotzena de coses més, em semblava una barbaritat, i com sabeu, el món no està per regalar RAM. Així que me&amp;rsquo;n vaig fer un de propi.&lt;/p&gt;&#10;&lt;h2 id="què-és"&gt;Què és&#10;&lt;/h2&gt;&lt;p&gt;InformadoRSS és un servei autoallotjat que mira feeds RSS i Atom, filtra els elements i els envia a canals de Discord. Un contenidor, un fitxer SQLite i una web que serveix el mateix binari. És de codi obert (MIT):&lt;/p&gt;&#10;&lt;a class="github-repo-card" href="https://github.com/christt105/InformadoRSS" target="_blank" rel="noopener"&gt;&#10; &lt;img src="https://avatars.githubusercontent.com/u/36189169?v=4" alt="christt105 avatar" class="repo-avatar"&gt;&#10; &lt;h3&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-github" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"&gt;&#10; &lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/&gt;&#10; &lt;path d="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5" /&gt;&#10;&lt;/svg&gt;&#10;&#10;&#10; christt105/InformadoRSS&lt;/h3&gt;&#10; &lt;p&gt;Lightweight single-container RSS/Atom to Discord forwarder&lt;/p&gt;&#10; &lt;div class="repo-stats"&gt;&#10; &lt;span&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" class="icon icon-tabler icons-tabler-filled icon-tabler-star"&gt;&lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/&gt;&lt;path d="M8.243 7.34l-6.38 .925l-.113 .023a1 1 0 0 0 -.44 1.684l4.622 4.499l-1.09 6.355l-.013 .11a1 1 0 0 0 1.464 .944l5.706 -3l5.693 3l.1 .046a1 1 0 0 0 1.352 -1.1l-1.091 -6.355l4.624 -4.5l.078 -.085a1 1 0 0 0 -.633 -1.62l-6.38 -.926l-2.852 -5.78a1 1 0 0 0 -1.794 0l-2.853 5.78z" /&gt;&lt;/svg&gt; 0&lt;/span&gt;&#10; &lt;span&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-git-fork"&gt;&lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/&gt;&lt;path d="M10 18a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /&gt;&lt;path d="M5 6a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /&gt;&lt;path d="M15 6a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /&gt;&lt;path d="M7 8v2a2 2 0 0 0 2 2h6a2 2 0 0 0 2 -2v-2" /&gt;&lt;path d="M12 12l0 4" /&gt;&lt;/svg&gt; 0&lt;/span&gt;&#10; &lt;span&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-calendar-event"&gt;&lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/&gt;&lt;path d="M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2l0 -12" /&gt;&lt;path d="M16 3l0 4" /&gt;&lt;path d="M8 3l0 4" /&gt;&lt;path d="M4 11l16 0" /&gt;&lt;path d="M8 15h2v2h-2l0 -2" /&gt;&lt;/svg&gt; 2026-10-24&lt;/span&gt;&#10; &lt;/div&gt;&#10; &lt;/a&gt;&#10;&lt;p&gt;&lt;img alt="El Pregonero, el bot, avisant d’una entrada nova del blog de Godot" class="gallery-image" data-flex-basis="225px" data-flex-grow="94" height="1360" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://christt105.github.io/blog/informadorss/discord-godot.webp" srcset="https://christt105.github.io/blog/informadorss/discord-godot_hu_be3e79b240a22aeb.webp 800w, https://christt105.github.io/blog/informadorss/discord-godot.webp 1280w" width="1280"&gt;&lt;/p&gt;&#10;&lt;p&gt;La idea és senzilla:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Un &lt;strong&gt;feed&lt;/strong&gt; és una URL.&lt;/li&gt;&#10;&lt;li&gt;Una &lt;strong&gt;ruta&lt;/strong&gt; diu què fer amb un feed: un filtre, una o diverses destinacions (un canal de Discord o ntfy) i una plantilla de missatge.&lt;/li&gt;&#10;&lt;li&gt;La web té un constructor de filtres, un editor de plantilles i un selector de servidors i canals, per no haver de copiar ids a mà.&lt;/li&gt;&#10;&lt;li&gt;El bot parla amb Discord només per l&amp;rsquo;API REST. Res de gateway, ni comandes, ni webhooks. Així de senzill.&lt;/li&gt;&#10;&lt;li&gt;Quan un feed o una destinació es trenca m&amp;rsquo;envia un únic missatge privat per Discord, i un altre quan es recupera.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;img alt="La llista de feeds, amb l’última entrada de cadascun i el seu estat" class="gallery-image" data-flex-basis="204px" data-flex-grow="85" height="1690" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://christt105.github.io/blog/informadorss/web-feeds.webp" srcset="https://christt105.github.io/blog/informadorss/web-feeds_hu_5ee8d49264e2f793.webp 800w, https://christt105.github.io/blog/informadorss/web-feeds.webp 1440w" width="1440"&gt;&lt;/p&gt;&#10;&lt;p&gt;Per exemple, el feed de Media Tracker, on surt el que acabo de veure o de jugar, té quatre rutes: a cada servidor les pel·lícules i sèries van a un canal i els videojocs a un altre. Quan acabo Tetris, l&amp;rsquo;entrada passa per les quatre i només arriba als canals que l&amp;rsquo;accepten:&lt;/p&gt;&#10;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart LR&#10; I["Entrada nova&lt;br/&gt;a Media Tracker&lt;br/&gt;&lt;b&gt;Tetris&lt;/b&gt; · pel·lícula"]&#10; I --&gt; R1["Ruta 3&lt;br/&gt;sense videojocs"]&#10; I --&gt; R2["Ruta 4&lt;br/&gt;només videojocs"]&#10; I --&gt; R3["Ruta 1&lt;br/&gt;sense videojocs"]&#10; I --&gt; R4["Ruta 2&lt;br/&gt;només videojocs"]&#10; R1 --&gt;|"✔ passa"| C1&#10; R2 -.-x|"✘ no passa"| G1&#10; R3 --&gt;|"✔ passa"| C2&#10; R4 -.-x|"✘ no passa"| G2&#10; subgraph Z["Discord · Los Zanahorios"]&#10; C1["#cine"]&#10; G1["#games"]&#10; end&#10; subgraph P["Discord · Los Panas"]&#10; C2["#animu-pelis-series"]&#10; G2["#gaming"]&#10; end&lt;/pre&gt;&lt;p&gt;&lt;img alt="L’editor d’una ruta: filtre, plantilla del missatge i canal de destinació" class="gallery-image" data-flex-basis="252px" data-flex-grow="105" height="1994" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://christt105.github.io/blog/informadorss/web-route.webp" srcset="https://christt105.github.io/blog/informadorss/web-route_hu_a1005d249803043c.webp 800w, https://christt105.github.io/blog/informadorss/web-route_hu_458b51e51904d625.webp 1600w, https://christt105.github.io/blog/informadorss/web-route.webp 2100w" width="2100"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="Així arriba Tetris a Discord" class="gallery-image" data-flex-basis="157px" data-flex-grow="65" height="1955" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://christt105.github.io/blog/informadorss/discord-mediatracker.webp" srcset="https://christt105.github.io/blog/informadorss/discord-mediatracker_hu_fb324b3eb85bfa5f.webp 800w, https://christt105.github.io/blog/informadorss/discord-mediatracker.webp 1280w" width="1280"&gt;&lt;/p&gt;&#10;&lt;h2 id="lstack"&gt;L&amp;rsquo;stack&#10;&lt;/h2&gt;&lt;p&gt;C# amb .NET 10 compilat amb NativeAOT, i un frontend en Vue 3 que acaba com a fitxers estàtics dins del mateix binari. Vaig triar C# perquè és el que faig servir cada dia, i per això vaig descartar Go i C++. Tenia curiositat per provar de fer alguna cosa d&amp;rsquo;aquest estil amb un d&amp;rsquo;aquests llenguatges, però al final C# és amb el que em sento més còmode llegint. L&amp;rsquo;emmagatzematge és SQLite, amb una còpia de seguretat diària a un altre disc, tot i que no seria una gran pèrdua.&lt;/p&gt;&#10;&lt;p&gt;Així es veu per dins:&lt;/p&gt;&#10;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart TD&#10; F["Feeds RSS / Atom"] --&gt; SRC&#10; YO["Navegador a la LAN"] --&gt; WEB&#10; subgraph BIN["Un sol binari de C# · .NET 10 amb NativeAOT"]&#10; WEB["Web en Vue 3"] &lt;--&gt; API["API"]&#10; API &lt;--&gt; DB[("SQLite")]&#10; SCH["Planificador"] &lt;--&gt; DB&#10; SCH --&gt; SRC["Font&lt;br/&gt;descarrega i analitza"]&#10; SRC --&gt; PIPE["Rutes&lt;br/&gt;filtre i plantilla"]&#10; subgraph SK["Sinks"]&#10; DSC["Discord"]&#10; NT["ntfy"]&#10; NEXT["Telegram?"]&#10; end&#10; PIPE --&gt; DSC&#10; PIPE --&gt; NT&#10; PIPE -.-&gt; NEXT&#10; end&#10; classDef futuro stroke-dasharray: 5 5&#10; class NEXT futuro&lt;/pre&gt;&lt;p&gt;La idea és que tot sigui modular. Cada destinació és un sink, una classe que implementa una interfície molt petita: un nom i un mètode que lliura el missatge. Ara mateix n&amp;rsquo;hi ha dos, Discord i ntfy, i afegir-ne un altre, com Telegram, és escriure aquesta classe i registrar-la, sense tocar el planificador ni els filtres; la web el detecta sola i ja l&amp;rsquo;ofereix com a destinació. Amb les fonts passa el mateix: avui només hi ha RSS i Atom, però estan darrere de la seva pròpia interfície.&lt;/p&gt;&#10;&lt;h2 id="els-números"&gt;Els números&#10;&lt;/h2&gt;&lt;p&gt;Posem els números sobre la taula i comparem els dos serveis en moments semblants: en repòs, amb els mateixos feeds i mirant cada deu minuts. MonitoRSS ja l&amp;rsquo;he apagat per raons òbvies, així que les seves xifres són d&amp;rsquo;abans del canvi.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;InformadoRSS&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;MonitoRSS&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Contenidors&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;1&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;9&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;RAM&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;75 MiB&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;uns 670 MB&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Imatge&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;37 MB&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;uns 3,9 GB sumades&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Dades en disc&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;4,5 MB&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;656 MB&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;Tot i que els números són molt bons, encara hi ha marge de millora. En el primer experiment, sense feeds ni web, el binari AOT gastava uns 10 MiB, i en producció són 75 MiB: el recol·lector d&amp;rsquo;escombraries de .NET no té cap pressa per tornar memòria en una màquina amb 15 GB lliures. Si algun dia m&amp;rsquo;importa, li puc limitar el heap. També escriu uns 50 MB al dia en disc, gairebé tot logs massa detallats del client HTTP, que s&amp;rsquo;arreglen abaixant el nivell de log.&lt;/p&gt;&#10;&lt;h2 id="fet-amb-claude"&gt;Fet amb Claude&#10;&lt;/h2&gt;&lt;p&gt;Primer vaig escriure el disseny en una nota d&amp;rsquo;Obsidian (què fa MonitoRSS, què faig servir jo de debò i què puc llençar) i després el vaig partir en tasques. Claude en va executar diverses en paral·lel en worktrees de git diferents, cadascuna amb la seva pull request, i jo les revisava i les fusionava per onades: emmagatzematge, filtres i parser de feeds, després el planificador i l&amp;rsquo;enviament a Discord, i finalment l&amp;rsquo;importador, les alertes, les còpies de seguretat i la web. Crec que he trobat una manera de treballar molt còmoda amb la IA, potser aviat escric un post de com treballo.&lt;/p&gt;&#10;&lt;h2 id="el-canvi"&gt;El canvi&#10;&lt;/h2&gt;&lt;p&gt;El que feia por no era el codi, era el canvi de l&amp;rsquo;un a l&amp;rsquo;altre. Vaig fer un importador que llegeix un &lt;code&gt;mongoexport&lt;/code&gt; de MonitoRSS i crea els feeds i les rutes. La primera passada enviava totes les destinacions a un canal de proves i enviava l&amp;rsquo;últim element de cada feed, per comparar els missatges l&amp;rsquo;un al costat de l&amp;rsquo;altre. Quan va quadrar, vaig aturar els contenidors de MonitoRSS, vaig apuntar les 22 rutes als canals de veritat i les vaig marcar com a vistes en silenci perquè ningú es mengés una allau d&amp;rsquo;entrades velles. Si alguna cosa sortia malament, un &lt;code&gt;docker start&lt;/code&gt; i torna l&amp;rsquo;stack antic. La veritat és que va sortir gairebé perfecte a la primera.&lt;/p&gt;&#10;&lt;h2 id="coses-que-em-van-donar-guerra"&gt;Coses que em van donar guerra&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Els feeds de YouTube retornen 404 unes hores cada matí.&lt;/strong&gt; És una caiguda global, no la meva IP. Per això un feed només es considera trencat després de sis hores seguides fallant. No entenc gaire per què li passa això a YouTube. &lt;a class="link" href="https://www.reddit.com/r/youtube/comments/1r61jpo/all_youtube_channel_rss_feeds_are_down_return_404/" target="_blank" rel="noopener"&#10; &gt;Sembla un error de fa temps&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;MyAnimeList reescriu les entrades al mateix lloc.&lt;/strong&gt; El guid de cada entrada és la URL de l&amp;rsquo;anime i l&amp;rsquo;estat viu a la descripció, així que passar de &lt;code&gt;Watching&lt;/code&gt; a &lt;code&gt;Completed&lt;/code&gt; no s&amp;rsquo;enviava mai. A MonitoRSS passava igual. Ara un feed pot tenir un patró d&amp;rsquo;identitat, una expressió regular sobre la descripció que s&amp;rsquo;afegeix a l&amp;rsquo;id de l&amp;rsquo;element, i cada estat compta com un element nou. Igualment és una merda com MAL organitza l&amp;rsquo;RSS (Ori, no t&amp;rsquo;ho dic més, posa RSS a la teva app de tracking).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Elements vells després d&amp;rsquo;una caiguda.&lt;/strong&gt; Els elements més antics que un màxim es marquen com a vistos sense enviar-se, i des de la web se&amp;rsquo;n pot enviar o reiniciar qualsevol a mà. Això em sol passar perquè trigo diversos dies a escriure un post: m&amp;rsquo;oblido d&amp;rsquo;actualitzar la data, apareix com a publicat fa uns quants dies i es perd l&amp;rsquo;enviament.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;img alt="Un canvi d’estat a MyAnimeList que ara sí que arriba a Discord" class="gallery-image" data-flex-basis="375px" data-flex-grow="156" height="818" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://christt105.github.io/blog/informadorss/discord-mal.webp" srcset="https://christt105.github.io/blog/informadorss/discord-mal_hu_a1a7bf577e79ccc3.webp 800w, https://christt105.github.io/blog/informadorss/discord-mal.webp 1280w" width="1280"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="La vista d’un feed, amb les seves rutes i el camp del patró d’identitat" class="gallery-image" data-flex-basis="309px" data-flex-grow="128" height="1629" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://christt105.github.io/blog/informadorss/web-feed.webp" srcset="https://christt105.github.io/blog/informadorss/web-feed_hu_384fba0bd150d037.webp 800w, https://christt105.github.io/blog/informadorss/web-feed_hu_a98081b772e13ef9.webp 1600w, https://christt105.github.io/blog/informadorss/web-feed.webp 2100w" width="2100"&gt;&lt;/p&gt;&#10;&lt;h2 id="el-que-falta"&gt;El que falta&#10;&lt;/h2&gt;&lt;p&gt;És un servei molt bàsic, té just el que necessito. MonitoRSS té molta més personalització i pots fer més coses, però no ho necessito, i menys a canvi de gastar nou vegades més RAM.&lt;/p&gt;&#10;&lt;p&gt;Falten coses com els missatges de Discord amb Components V2, una previsualització del missatge a l&amp;rsquo;estil de Discord i un filtre de Shorts per a YouTube. No té login: està pensat per a una LAN de confiança.&lt;/p&gt;&#10;&lt;p&gt;Ho tinc muntat força modular, així que puc afegir altres fonts o altres sinks, i si necessito alguna funcionalitat la puc afegir fàcilment: no és un servei gaire complex. De moment ho deixaré així, obert per a qui el vulgui fer servir o millorar.&lt;/p&gt;&#10;&lt;p&gt;Si fas servir MonitoRSS i vols alguna cosa més lleugera, prova&amp;rsquo;l i fes-hi una ullada.&lt;/p&gt;&#10;&lt;p&gt;Ens veiem al següent!&lt;/p&gt;&#10;</description></item></channel></rss>