{"id":5464,"date":"2026-08-30T20:30:35","date_gmt":"2026-08-30T11:30:35","guid":{"rendered":"https:\/\/donguri3.net\/server-tech\/n8n-x-twitter-auto-tweet-2\/"},"modified":"2026-08-30T20:30:36","modified_gmt":"2026-08-30T11:30:36","slug":"n8n-x-twitter-auto-tweet","status":"publish","type":"post","link":"https:\/\/donguri3.net\/en\/server-tech\/n8n-automation\/n8n-x-twitter-auto-tweet\/","title":{"rendered":"Implemented automated posting to X using n8n"},"content":{"rendered":"<p>Following the &#8220;Free Game Auto-Collection System&#8221; introduced in my previous article, I have now implemented a feature that automatically posts updates to X (formerly Twitter) the moment new information is detected.<\/p>\n<p>During the building process, I hit numerous technical walls\u2014including X&#8217;s specification changes, API authentication bugs, and data format traps\u2014which led to a lot of intense trial and error. To help anyone struggling with SNS integration via n8n in a similar way, I will explain the entire troubleshooting process in detail.<\/p>\n<h2>SNS Notifications for New Information<\/h2>\n<p>While the WordPress free game listing page is now updated completely autonomously, users won&#8217;t notice it just by having the page exist. To broadcast &#8220;what&#8217;s available for free right now&#8221; in real time and create a traffic conduit to the site, I decided to add a mechanism that automatically posts to X the moment the system detects new data.<\/p>\n<p><a href=\"https:\/\/donguri3.net\/wp-content\/uploads\/2026\/05\/07e164dce9a40c8fae089ca13a289f96.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-3428\" src=\"https:\/\/donguri3.net\/wp-content\/uploads\/2026\/05\/07e164dce9a40c8fae089ca13a289f96.png\" alt=\"Workflow connecting new detection to X posting\" width=\"350\" height=\"131\" srcset=\"https:\/\/donguri3.net\/wp-content\/uploads\/2026\/05\/07e164dce9a40c8fae089ca13a289f96.png 350w, https:\/\/donguri3.net\/wp-content\/uploads\/2026\/05\/07e164dce9a40c8fae089ca13a289f96-300x112.png 300w\" sizes=\"(max-width: 350px) 100vw, 350px\" \/><\/a><\/p>\n<h2>The Character Limit Wall and Logic<\/h2>\n<p>The first challenge was X&#8217;s specific &#8220;character limit&#8221; (140 full-width characters \/ 280 half-width characters). During sales periods, more than 10 new games might be detected at once, and if you simply list them all out, the character limit is inevitably exceeded and the workflow is forcibly halted.<\/p>\n<p>To counter this, I inserted a JavaScript Code node to build a calculation logic simulating X&#8217;s special character counting rules (such as URLs uniformly counting as 23 half-width characters, Japanese characters counting as 2, etc.). I combined game titles and distribution platform names like a puzzle, completing a character-limit defense logic that automatically and neatly truncates text with &#8220;+X others&#8221; into a single post if it looks like it will overflow. Additionally, by utilizing the `type` attribute stored in Data Tables from the previous setup, I designed a thoughtful feature that automatically adds a `[DLC]` label for downloadable content.<\/p>\n<h2>The OAuth 2.0 Authentication Infinite Loop<\/h2>\n<p>While the automated text generation was flawless, the system&#8217;s biggest wall stood in the way: &#8220;X API Authentication.&#8221;<\/p>\n<p>The official X (Twitter) node provided in n8n requires &#8220;OAuth 2.0&#8221; as the authentication method. However, this system runs in a secure local environment that cannot be accessed from the outside (HTTP with port 5678). Trying to pass authentication in this environment resulted in an infinite loop bug where, right after passing login and two-factor authentication on X&#8217;s screen, I was thrown back to the initial screen saying, &#8220;Log in to X to use this app.&#8221;<\/p>\n<p>I tried clearing URL security restrictions using every possible means, such as n8n&#8217;s official tunneling feature (now deprecated) or external tools (localhost.run), but I spent hours in despair facing a bug caused by session inconsistencies in X&#8217;s OAuth 2.0 server.<\/p>\n<p><a href=\"https:\/\/donguri3.net\/wp-content\/uploads\/2026\/05\/1d0b6d92bc911798840e568a518d2080.png\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-3429\" src=\"https:\/\/donguri3.net\/wp-content\/uploads\/2026\/05\/1d0b6d92bc911798840e568a518d2080.png\" alt=\"Infinite login loop screen occurring on X's authentication screen\" width=\"504\" height=\"381\" srcset=\"https:\/\/donguri3.net\/wp-content\/uploads\/2026\/05\/1d0b6d92bc911798840e568a518d2080.png 504w, https:\/\/donguri3.net\/wp-content\/uploads\/2026\/05\/1d0b6d92bc911798840e568a518d2080-300x227.png 300w\" sizes=\"(max-width: 504px) 100vw, 504px\" \/><\/a><\/p>\n<h2>Building Custom Posts via HTTP Request<\/h2>\n<p>Deciding that as long as I used the official n8n X node, I would never escape this barren OAuth 2.0 trap, I flipped my perspective 180 degrees: the approach of &#8220;giving up the official node and building a custom posting feature using the HTTP Request node.&#8221;<\/p>\n<p>In n8n&#8217;s credential registration, the older &#8220;OAuth 1.0a (X OAuth account)&#8221; method\u2014which doesn&#8217;t require URL redirects and directly inputs four cryptographic keys\u2014had successfully registered smoothly even while keeping the local environment intact.<\/p>\n<p>Therefore, I placed a general-purpose &#8220;HTTP Request&#8221; node, specified the registered &#8220;X OAuth account (OAuth 1.0a)&#8221; as the authentication type, and built a structure that sends POST requests directly to X&#8217;s latest tweet-posting API endpoint (`https:\/\/api.twitter.com\/2\/tweets`). By completely bypassing the redirect process itself, I left the login loop that had plagued me behind in a second and completely broke through the authentication wall while remaining in a fully local environment.<\/p>\n<h2>Starting Automated Local Operations<\/h2>\n<p>As a result of tackling these various traps, an automated posting system has been completed that delivers clean messages directly to X from behind the scenes, without compromising the secure local server environment by even a millimeter.<\/p>\n<p>During testing, when posts were made in rapid succession over a short period, they were rejected due to X&#8217;s API specifications (duplicate content elimination), but under production operations with a schedule of &#8220;posting new games as they appear every 6 hours,&#8221; it operates extremely cleanly without hitting rate limits.<\/p>\n<h2>Conclusion<\/h2>\n<p>Following WordPress automation, I have implemented a feature to automatically post new free game information to X. During construction, I faced high walls such as designing Code logic to fit multiple pieces of data within 140 characters, and the &#8220;OAuth 2.0 authentication infinite loop&#8221; of the official n8n X node. By switching this to directly hitting the API using &#8220;OAuth 1.0a + HTTP Request node,&#8221; I completely bypassed it and broke through authentication while keeping the local environment intact. An unattended, robust SNS dissemination infrastructure that operates stably on a 6-hour cycle is now complete.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Following the &#8220;Free Game Auto-Collection System&#8221; introduced in my previous article, I have now imp [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":3431,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_locale":"en_US","_original_post":"https:\/\/donguri3.net\/?p=3427","footnotes":""},"categories":[1167],"tags":[52,61,10,310,278],"class_list":["post-5464","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-n8n-automation","tag-https","tag-wordpress","tag-server","tag-310","tag-278","en-US"],"_links":{"self":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts\/5464","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/comments?post=5464"}],"version-history":[{"count":1,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts\/5464\/revisions"}],"predecessor-version":[{"id":5467,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/posts\/5464\/revisions\/5467"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/media\/3431"}],"wp:attachment":[{"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/media?parent=5464"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/categories?post=5464"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/donguri3.net\/wp-json\/wp\/v2\/tags?post=5464"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}