<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: arti1984</title>
    <description>The latest articles on DEV Community by arti1984 (@arti1984collab).</description>
    <link>https://dev.to/arti1984collab</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4230819%2Fccd33c32-5411-4974-9db3-22a337e0d93a.png</url>
      <title>DEV Community: arti1984</title>
      <link>https://dev.to/arti1984collab</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arti1984collab"/>
    <language>en</language>
    <item>
      <title>Social-Media-Uploads ohne API: ein Uploader, der den Browser bedient</title>
      <dc:creator>arti1984</dc:creator>
      <pubDate>Fri, 06 Nov 2026 16:47:35 +0000</pubDate>
      <link>https://dev.to/arti1984collab/social-media-uploads-ohne-api-ein-uploader-der-den-browser-bedient-276b</link>
      <guid>https://dev.to/arti1984collab/social-media-uploads-ohne-api-ein-uploader-der-den-browser-bedient-276b</guid>
      <description>&lt;p&gt;Jede Plattform möchte für automatische Uploads eine eigene API-App: Developer-Konto, Review, Scopes, Tokens, und bei TikTok zusätzlich eine Freigabe, die man als Einzelperson praktisch nicht bekommt. Ich wollte einfach nur ein Video auf YouTube, Facebook, Instagram und TikTok veröffentlichen. Also habe ich das Gegenteil gebaut: ein Tool, das gar keine API benutzt, sondern den Browser steuert.&lt;/p&gt;

&lt;h2&gt;
  
  
  Die Idee: der Browser ist die Schnittstelle
&lt;/h2&gt;

&lt;p&gt;Statt mit einer API zu sprechen, öffnet das Tool die ganz normale Webseite, wählt die Datei aus, tippt Titel und Text ein und klickt auf „Posten". Es macht exakt das, was ich mit der Maus machen würde — nur reproduzierbar und per Kommandozeile.&lt;/p&gt;

&lt;p&gt;Das klingt primitiv, hat aber einen handfesten Vorteil: Es funktioniert überall dort, wo es keine Upload-API gibt. Und es braucht keine Zugangsdaten im Klartext, weil es eine bereits angemeldete Sitzung weiterbenutzt.&lt;/p&gt;

&lt;p&gt;Technisch steckt &lt;a href="https://github.com/Kaliiiiiiiiii-Vinyzu/patchright" rel="noopener noreferrer"&gt;patchright&lt;/a&gt; bzw. Playwright darunter, also ein fernsteuerbarer Chromium oder Firefox. Die Sitzung liegt entweder als Cookie-Datei (&lt;code&gt;cookies/….json&lt;/code&gt;) oder als persistentes Browserprofil (&lt;code&gt;profiles/&amp;lt;browser&amp;gt;/&amp;lt;account&amp;gt;&lt;/code&gt;) auf der eigenen Platte.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was zur Laufzeit passiert
&lt;/h2&gt;

&lt;p&gt;Der Ablauf ist bewusst langweilig und deterministisch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sau facebook upload-video &lt;span class="nt"&gt;--account&lt;/span&gt; creator &lt;span class="nt"&gt;--file&lt;/span&gt; video.mp4 &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"Titel"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Die CLI liest die Argumente und wählt Plattform, Browser und Sitzung.&lt;/li&gt;
&lt;li&gt;Der Uploader öffnet die Startseite, wartet auf die Selektoren des Composers und legt die Datei in das &lt;code&gt;input[type=file]&lt;/code&gt; — ohne Datei-Dialog, direkt über das DOM.&lt;/li&gt;
&lt;li&gt;Titel, Beschreibung und Hashtags werden eingetippt.&lt;/li&gt;
&lt;li&gt;Der Publish-Button wird über seine Beschriftung gesucht (mehrsprachig, weil die Oberfläche je nach Konto Deutsch, Englisch oder Chinesisch ist).&lt;/li&gt;
&lt;li&gt;Danach schreibt der Lauf sein Ergebnis als JSON: Instagram übernimmt die Media-ID aus der finalen Antwort des Create-Endpunkts, Facebook wartet auf den exakten Erfolgs-Toast, und der Facebook-Pages-Ablauf öffnet die Liste der veröffentlichten Beiträge und sucht den Post über die Content-ID.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Kein Agent, kein LLM, keine Entscheidungen zur Laufzeit: ein Befehl, eine feste Abfolge von Klicks. Genau das macht Fehlersuche erträglich — wenn etwas bricht, ist es ein Selektor und keine Laune eines Modells.&lt;/p&gt;

&lt;h2&gt;
  
  
  Captions ohne KI-Dienst
&lt;/h2&gt;

&lt;p&gt;Beschreibungen und Hashtags kann das Tool selbst vorschlagen (&lt;code&gt;--auto-desc&lt;/code&gt;, &lt;code&gt;--auto-tags&lt;/code&gt;, &lt;code&gt;sau caption&lt;/code&gt;). Das ist absichtlich regelbasiert: Text aus Titel und Notizen, ein fester Call-to-Action pro Plattform, Hashtags aus den signifikanten Wörtern, alles gekürzt auf die Zeichenlimits der Plattform. Gleiche Eingabe, gleiche Ausgabe, kein Netzwerkaufruf, keine Kosten.&lt;/p&gt;

&lt;p&gt;Für meinen Zweck reicht das. Wer wirklich kreative Texte will, hängt dort ein Modell dran — die Stelle ist klar abgegrenzt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loslegen
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv venv
&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate        &lt;span class="c"&gt;# Windows: .venv\Scripts\Activate.ps1&lt;/span&gt;
uv pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
patchright &lt;span class="nb"&gt;install &lt;/span&gt;chromium
&lt;span class="nb"&gt;cp &lt;/span&gt;conf.example.py conf.py
sau &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dann einmal anmelden — das Fenster geht sichtbar auf, Captcha und 2FA macht man selbst:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sau youtube login &lt;span class="nt"&gt;--account&lt;/span&gt; creator
sau youtube check &lt;span class="nt"&gt;--account&lt;/span&gt; creator
sau youtube upload-video &lt;span class="nt"&gt;--account&lt;/span&gt; creator &lt;span class="nt"&gt;--file&lt;/span&gt; videos/demo.mp4 &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"Titel"&lt;/span&gt; &lt;span class="nt"&gt;--visibility&lt;/span&gt; public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--account&lt;/code&gt; ist nur ein lokaler Alias für eine gespeicherte Sitzung. Für Facebook, Facebook Pages und Instagram gibt es dieselben drei Schritte (&lt;code&gt;login&lt;/code&gt;, &lt;code&gt;check&lt;/code&gt;, &lt;code&gt;upload-video&lt;/code&gt; bzw. &lt;code&gt;upload-note&lt;/code&gt;). TikTok hat keinen CLI-Befehl, sondern einen eigenen Python-Uploader, der auf Wunsch einen bereits laufenden Browser über CDP übernimmt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wo es weh tut
&lt;/h2&gt;

&lt;p&gt;Ehrlich gehört das in einen solchen Artikel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Selektoren brechen.&lt;/strong&gt; Baut eine Plattform ihr Web-UI um, findet das Tool den Button nicht mehr. Dann wird gestoppt und angepasst, nicht geraten.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Die Nutzungsbedingungen.&lt;/strong&gt; Cookie-Automatisierung ist bei den meisten Plattformen nicht vorgesehen. Risk-Control, Captchas und im schlimmsten Fall Sperren sind reale Risiken. Wer das produktiv einsetzt, sollte wissen, was er tut.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;„Unklar" ist nicht „fehlgeschlagen".&lt;/strong&gt; Die Ergebnisdatei wird mit &lt;code&gt;submission_unknown&lt;/code&gt; geschrieben, bevor der Submit-Klick passiert — ein Absturz hinterlässt also einen Eintrag, und nichts wird automatisch erneut gesendet. Ein stummer Composer ist in beide Richtungen kein Beweis: &lt;code&gt;sau instagram verify&lt;/code&gt; und &lt;code&gt;sau facebook verify&lt;/code&gt; öffnen den Live-Post und prüfen ID, Autor und Caption — dieser Check ist verlässlicher als jeder Toast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Planen ist Plattform-Sache.&lt;/strong&gt; Facebook Pages terminieren über den Zeitplan-Dialog der Seite, Instagram und Facebook-Profile können gar nicht planen.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fazit
&lt;/h2&gt;

&lt;p&gt;Wer für ein paar eigene Konten regelmäßig postet und keine Lust auf vier API-Integrationen hat, kommt mit Browser-Automatisierung erstaunlich weit. Es ist kein Produkt für Kundenkonten, sondern ein Werkzeug für den eigenen Account — mit allen Ecken und Kanten, die dazugehören.&lt;/p&gt;

&lt;p&gt;Code, Handbuch und alle Schalter: &lt;a href="https://github.com/arti1984-collab/social-auto-upload-international" rel="noopener noreferrer"&gt;github.com/arti1984-collab/social-auto-upload-international&lt;/a&gt; (MIT).&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>automation</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Social media uploads without an API: an uploader that drives the browser</title>
      <dc:creator>arti1984</dc:creator>
      <pubDate>Fri, 06 Nov 2026 16:42:28 +0000</pubDate>
      <link>https://dev.to/arti1984collab/social-media-uploads-without-an-api-an-uploader-that-drives-the-browser-1ggm</link>
      <guid>https://dev.to/arti1984collab/social-media-uploads-without-an-api-an-uploader-that-drives-the-browser-1ggm</guid>
      <description>&lt;p&gt;Every platform wants its own API app for automated uploads: a developer account, a review, scopes, tokens — and on TikTok an approval an individual practically never gets. I just wanted to publish one video to YouTube, Facebook, Instagram and TikTok. So I built the opposite: a tool that uses no API at all and drives the browser instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea: the browser is the interface
&lt;/h2&gt;

&lt;p&gt;Instead of talking to an API, the tool opens the ordinary website, picks the file, types the title and the text and clicks "Post" — exactly what I would do with a mouse, just reproducible and from the command line.&lt;/p&gt;

&lt;p&gt;That sounds primitive, but it has one solid advantage: it works wherever there is no upload API. And it needs no plaintext credentials, because it reuses a session that is already signed in.&lt;/p&gt;

&lt;p&gt;Under the hood it is &lt;a href="https://github.com/Kaliiiiiiiiii-Vinyzu/patchright" rel="noopener noreferrer"&gt;patchright&lt;/a&gt; and Playwright, so a remote-controlled Chromium or Firefox. The session lives either as a cookie file (&lt;code&gt;cookies/….json&lt;/code&gt;) or as a persistent browser profile (&lt;code&gt;profiles/&amp;lt;browser&amp;gt;/&amp;lt;account&amp;gt;&lt;/code&gt;) on your own disk.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens at runtime
&lt;/h2&gt;

&lt;p&gt;The flow is intentionally boring and deterministic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sau facebook upload-video &lt;span class="nt"&gt;--account&lt;/span&gt; creator &lt;span class="nt"&gt;--file&lt;/span&gt; video.mp4 &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"Title"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;The CLI reads the arguments and picks the platform, the browser and the session.&lt;/li&gt;
&lt;li&gt;The uploader opens the home page, waits for the composer selectors and attaches the file to the &lt;code&gt;input[type=file]&lt;/code&gt; — no file dialog, straight through the DOM.&lt;/li&gt;
&lt;li&gt;Title, description and hashtags are typed in.&lt;/li&gt;
&lt;li&gt;The publish button is found by its label (in several languages, because the UI is German, English or Chinese depending on the account).&lt;/li&gt;
&lt;li&gt;Afterwards the run writes its result as JSON: Instagram uses the media id from the final create response, Facebook waits for the exact success toast, and the Facebook Page flow opens the published list and looks the post up by content id.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No agent, no LLM, no decisions at runtime: one command, a fixed sequence of clicks. That is what makes debugging bearable — when something breaks, it is a selector, not the mood of a model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Captions without an AI service
&lt;/h2&gt;

&lt;p&gt;The tool can suggest descriptions and hashtags by itself (&lt;code&gt;--auto-desc&lt;/code&gt;, &lt;code&gt;--auto-tags&lt;/code&gt;, &lt;code&gt;sau caption&lt;/code&gt;). That is deliberately rule-based: text from the title and the notes, one fixed call to action per platform, hashtags from the significant words, everything trimmed to the platform's character limits. Same input, same output, no network call, no cost.&lt;/p&gt;

&lt;p&gt;That is enough for my use case. If you want genuinely creative copy, plug a model in there — the seam is clearly defined.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv venv
&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate        &lt;span class="c"&gt;# Windows: .venv\Scripts\Activate.ps1&lt;/span&gt;
uv pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
patchright &lt;span class="nb"&gt;install &lt;/span&gt;chromium
&lt;span class="nb"&gt;cp &lt;/span&gt;conf.example.py conf.py
sau &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then sign in once — the window opens visibly, and you solve captchas and 2FA yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sau youtube login &lt;span class="nt"&gt;--account&lt;/span&gt; creator
sau youtube check &lt;span class="nt"&gt;--account&lt;/span&gt; creator
sau youtube upload-video &lt;span class="nt"&gt;--account&lt;/span&gt; creator &lt;span class="nt"&gt;--file&lt;/span&gt; videos/demo.mp4 &lt;span class="nt"&gt;--title&lt;/span&gt; &lt;span class="s2"&gt;"Title"&lt;/span&gt; &lt;span class="nt"&gt;--visibility&lt;/span&gt; public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--account&lt;/code&gt; is only a local alias for a stored session. Facebook, Facebook Pages and Instagram have the same three steps (&lt;code&gt;login&lt;/code&gt;, &lt;code&gt;check&lt;/code&gt;, &lt;code&gt;upload-video&lt;/code&gt; or &lt;code&gt;upload-note&lt;/code&gt;). TikTok has no CLI command but its own Python uploader, which can take over an already running browser over CDP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it hurts
&lt;/h2&gt;

&lt;p&gt;Honesty belongs in an article like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Selectors break.&lt;/strong&gt; When a platform redesigns its web UI, the tool no longer finds the button. Then it stops and gets adjusted — it does not guess.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The terms of service.&lt;/strong&gt; Cookie automation is not something most platforms provide for. Risk control, captchas and, in the worst case, bans are real risks. If you run this in production, you should know what you are doing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Unknown" is not "failed".&lt;/strong&gt; The result file is written with &lt;code&gt;submission_unknown&lt;/code&gt; before the submit click, so a crash leaves a record and nothing is re-sent automatically. A silent composer proves nothing either way: &lt;code&gt;sau instagram verify&lt;/code&gt; and &lt;code&gt;sau facebook verify&lt;/code&gt; reopen the live post and check id, author and caption — the check I trust more than any toast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduling is the platform's job.&lt;/strong&gt; Facebook Pages schedule through the page's own scheduling dialog; Instagram and Facebook profiles cannot schedule at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;For posting regularly to a handful of your own accounts without wiring up four API integrations, browser automation gets you surprisingly far. It is not a product for client accounts, it is a tool for your own account — with all the rough edges that come with it.&lt;/p&gt;

&lt;p&gt;Code, handbook and every flag: &lt;a href="https://github.com/arti1984-collab/social-auto-upload-international" rel="noopener noreferrer"&gt;github.com/arti1984-collab/social-auto-upload-international&lt;/a&gt; (MIT).&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>automation</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
