<?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: 0xGollum</title>
    <description>The latest articles on DEV Community by 0xGollum (@0xgollum).</description>
    <link>https://dev.to/0xgollum</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%2F4026311%2F3a2e5ec0-3483-4cdf-894c-cee31825ccbb.jpg</url>
      <title>DEV Community: 0xGollum</title>
      <link>https://dev.to/0xgollum</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/0xgollum"/>
    <language>en</language>
    <item>
      <title>Ike: An Android Priority App Where Every Task Has Its Own Checklist</title>
      <dc:creator>0xGollum</dc:creator>
      <pubDate>Sun, 23 Aug 2026 17:37:22 +0000</pubDate>
      <link>https://dev.to/0xgollum/ike-an-android-priority-app-where-every-task-has-its-own-checklist-11mm</link>
      <guid>https://dev.to/0xgollum/ike-an-android-priority-app-where-every-task-has-its-own-checklist-11mm</guid>
      <description>&lt;p&gt;I built Ike, an Android task app around the Eisenhower priority matrix. Every task can hold its own nested checklist of sub-steps instead of just a title.&lt;br&gt;
Features: Eisenhower matrix with 4 color-coded quadrants, nested checklists per task, reminders that actually ring, 4 color themes, drag-to-reorder, swipe to archive. Free, ad-supported, no account needed.&lt;br&gt;
In beta, sideload-only for now. Download: &lt;a href="https://files.catbox.moe/3i9cec.apk" rel="noopener noreferrer"&gt;https://files.catbox.moe/3i9cec.apk&lt;/a&gt;&lt;br&gt;
Looking for testers to break it and report bugs. Any feedback welcome!&lt;/p&gt;

</description>
      <category>android</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>X Light: Customize Your Android Flashlight — 480+ Themes, Beta Testers Wanted</title>
      <dc:creator>0xGollum</dc:creator>
      <pubDate>Thu, 20 Aug 2026 17:23:58 +0000</pubDate>
      <link>https://dev.to/0xgollum/x-light-customize-your-android-flashlight-480-themes-beta-testers-wanted-40n7</link>
      <guid>https://dev.to/0xgollum/x-light-customize-your-android-flashlight-480-themes-beta-testers-wanted-40n7</guid>
      <description>&lt;p&gt;Tired of the same plain flashlight app? X Light turns your Android torch into something you can actually customize.&lt;/p&gt;

&lt;p&gt;What you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;480+ unlockable themes: icons, glow colors, and sounds, pick your style&lt;/li&gt;
&lt;li&gt;Torch stays on in the background, no need to keep the app open&lt;/li&gt;
&lt;li&gt;Home screen widget for instant on/off&lt;/li&gt;
&lt;li&gt;Free, ad-supported, no account needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's in closed beta right now, just before the Play Store launch. Looking for Android testers to try it and report anything broken.&lt;/p&gt;

&lt;p&gt;Full details and safe download link on XDA: &lt;a href="https://xdaforums.com/t/beta-x-light-customizable-android-flashlight-app-looking-for-feedback.4798961/" rel="noopener noreferrer"&gt;https://xdaforums.com/t/beta-x-light-customizable-android-flashlight-app-looking-for-feedback.4798961/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All feedback is welcome: bugs, interface, theme ideas. Thanks for reading!&lt;/p&gt;

</description>
      <category>android</category>
      <category>mobiledev</category>
      <category>showdev</category>
      <category>beta</category>
    </item>
    <item>
      <title>I Found a Stranger's Unlocked Server in Two Minutes</title>
      <dc:creator>0xGollum</dc:creator>
      <pubDate>Mon, 17 Aug 2026 11:26:09 +0000</pubDate>
      <link>https://dev.to/0xgollum/i-found-a-strangers-unlocked-sesecuritywebdevpythonopensourcerver-in-two-minutes-418i</link>
      <guid>https://dev.to/0xgollum/i-found-a-strangers-unlocked-sesecuritywebdevpythonopensourcerver-in-two-minutes-418i</guid>
      <description>&lt;p&gt;Two minutes of scanning. No attack, no password guessed, nothing illegal - just public checks, the kind anyone can run. The result: the service used to upload files to the server (FTP) answered to any IP address on the planet. No firewall, no restriction. A door left wide open from the outside when it should only ever be reachable from the inside.&lt;/p&gt;

&lt;p&gt;This isn't a one-off. It isn't even the result of some genius exploit. Most break-ins don't start with a clever zero-day - they start with a door nobody ever thought to check again after installing it. A site gets built once, configured once, and then nobody looks at it again. Attackers, on the other hand, scan continuously.&lt;/p&gt;

&lt;p&gt;That's exactly the gap Exploit Radar fills: not a one-time audit you order once and forget, but monitoring that runs over time and only ever tells you what changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it checks
&lt;/h2&gt;

&lt;p&gt;20 checks, all passive and legal (never an intrusion attempt, ever):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Missing security headers, expired or weak SSL certificate&lt;/li&gt;
&lt;li&gt;Sensitive files left exposed online (credentials, backups)&lt;/li&gt;
&lt;li&gt;CMS and WordPress plugin versions - cross-checked against real named CVEs, flagged if a public exploit already exists&lt;/li&gt;
&lt;li&gt;The web server's own version, same logic&lt;/li&gt;
&lt;li&gt;Missing email spoofing protection, unsigned DNS&lt;/li&gt;
&lt;li&gt;Forgotten subdomains (abandoned test servers) - and whether they point to a cloud service an attacker can claim&lt;/li&gt;
&lt;li&gt;Misconfigured, publicly-listable cloud storage&lt;/li&gt;
&lt;li&gt;Risky open ports (databases, remote access) and confirmed past ransomware history&lt;/li&gt;
&lt;li&gt;Poorly secured cookies, misconfigured CORS, HTTP not forced to HTTPS&lt;/li&gt;
&lt;li&gt;robots.txt files tipping off sensitive folders, source code exposed through debug files&lt;/li&gt;
&lt;li&gt;Publicly reachable database admin panels&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every finding comes with a plain-language explanation - not just "outdated version," but the actual named vulnerability, its real severity, and whether someone has already published how to exploit it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes this different from a one-off audit
&lt;/h2&gt;

&lt;p&gt;On the first scan, nothing is reported - listing everything that already exists as if it just showed up would be misleading. From the second scan onward, only what's genuinely new gets surfaced. The site changes, updates, an intern opens a port by mistake - Exploit Radar sees it before an automated scanning bot finds it first.&lt;/p&gt;

&lt;p&gt;No exploitation is ever attempted, period. Every single check is equivalent to what a normal browser already does when visiting a public page: a GET request, a standard TLS handshake, a public DNS lookup. That line is clear and it doesn't move.&lt;/p&gt;




&lt;p&gt;Available on Apify: &lt;a href="https://apify.com/0xgollum/exploit-radar" rel="noopener noreferrer"&gt;https://apify.com/0xgollum/exploit-radar&lt;/a&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>python</category>
      <category>opensource</category>
    </item>
    <item>
      <title>LinkedIn Jobs Scraper — Never Pay for Blocked Pages</title>
      <dc:creator>0xGollum</dc:creator>
      <pubDate>Sun, 16 Aug 2026 06:24:31 +0000</pubDate>
      <link>https://dev.to/0xgollum/why-linkedin-job-scrapers-return-empty-rows-and-how-i-fixed-that-1lhn</link>
      <guid>https://dev.to/0xgollum/why-linkedin-job-scrapers-return-empty-rows-and-how-i-fixed-that-1lhn</guid>
      <description>&lt;p&gt;It's 11pm. A deliverable for a client is due at 9am: 300 LinkedIn job postings for a niche search, filtered by location and posting date, ready to import into a spreadsheet. You kick off the scraper you've been using, go make coffee, come back to a "success" log and a dataset full of... blank rows. Not an error. Not a crash. Just empty fields where real job postings used to be, scattered through the results with no way to tell which rows are real without opening every URL by hand.&lt;/p&gt;

&lt;p&gt;That's the actual failure mode of most LinkedIn scrapers: they don't fail loudly, they fail quietly mid-run - and you get charged for the empty rows exactly the same as the real ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get
&lt;/h2&gt;

&lt;p&gt;Search LinkedIn job postings by keywords, location, workplace type (on-site / remote / hybrid) and posting date - no cookies, no login, no LinkedIn account required. For every real match:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Title, company, location, posting date, direct URL&lt;/li&gt;
&lt;li&gt;Seniority level, employment type, job function, industries, applicant count&lt;/li&gt;
&lt;li&gt;Full job description&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optionally, layer in results straight from a target company's Greenhouse or Lever board - useful when you already know which companies you're watching.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A row is only ever pushed to the dataset - and only ever billed - if it actually carries real data.&lt;/strong&gt; If LinkedIn blocks a page on every attempt, the run just returns fewer results. It never fabricates a placeholder row and charges you for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one rule behind it
&lt;/h2&gt;

&lt;p&gt;LinkedIn blocks automated requests with a non-standard status code, not a normal 403 - and it does it regardless of proxy unless the request first behaves like a real browser session. This actor handles that under the hood: warms up a session, rotates to a fresh identity if one gets blocked, and retries the exact page that failed rather than skipping ahead. If a job's detail page still can't be reached after that, the job is kept with the fields it already has instead of being thrown away entirely - partial-but-real beats all-or-nothing, on every actor in this line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apify.com/0xgollum/reliable-linkedin-jobs" rel="noopener noreferrer"&gt;Try it on Apify Store →&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>webscraping</category>
      <category>api</category>
      <category>career</category>
    </item>
    <item>
      <title>What "No Cookies Required" Actually Means for a LinkedIn Scraper</title>
      <dc:creator>0xGollum</dc:creator>
      <pubDate>Sat, 15 Aug 2026 18:28:35 +0000</pubDate>
      <link>https://dev.to/0xgollum/what-no-cookies-required-actually-means-for-a-linkedin-scraper-4oi4</link>
      <guid>https://dev.to/0xgollum/what-no-cookies-required-actually-means-for-a-linkedin-scraper-4oi4</guid>
      <description>&lt;p&gt;You give it a list of LinkedIn profile URLs (or just usernames). It hands back, per profile: full name, headline, current location, the "about" text, and complete work + education history — job title, company, and dates for every role; school, degree, and dates for every entry.&lt;/p&gt;

&lt;p&gt;One profile in, this is what comes out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"public_identifier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"williamhgates"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bill Gates"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"headline"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Co-chair, Gates Foundation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Seattle, Washington, United States"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"about"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"experience"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Co-chair"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"company"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Gates Foundation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"dates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2000 - Present"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"education"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"school"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Harvard University"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"degree"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"dates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1973 - 1975"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;$3.50 per 1,000 profile results. No login required on your end, no browser extension, no manually copy-pasting URLs one at a time.&lt;/p&gt;

&lt;p&gt;And the part that actually matters if you're paying for this kind of data: you're only billed for profiles that come back with real data. Private accounts, deleted profiles, blocked lookups — those get logged and skipped, never charged. That sounds obvious until you notice how many scrapers don't do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why that billing promise is harder to keep than it sounds
&lt;/h2&gt;

&lt;p&gt;"No cookies required" shows up in a dozen scraper listings. It's not a trick — LinkedIn serves a genuinely public, server-rendered version of a profile to anyone who isn't logged in, as long as the owner hasn't restricted visibility. The full experience and education history live on their own separate pages, still public, still no login. That's the entire mechanism.&lt;/p&gt;

&lt;p&gt;The catch is that the same trust gets pulled instantly if you look automated. A plain request with a normal browser User-Agent got blocked on the first handful of calls — not a 403 or 429, but a non-standard HTTP 999, specific to LinkedIn's bot defense.&lt;/p&gt;

&lt;p&gt;A residential proxy didn't fix it. What did: picking up the same visitor cookies a real browser carries before ever loading a profile — one warm-up request to the homepage, a full set of browser-shaped headers, and a Referer chain between requests. Same IP, same machine: blocked every time without it, working every time with it.&lt;/p&gt;

&lt;p&gt;The second problem showed up once the main page was reachable: a block on just the experience or education sub-page — after the main page had already succeeded — was killing the entire lookup and discarding data that was already good. Fixed by treating sub-page failures as recoverable: return what you have, leave that one section empty, don't burn a whole session re-fetching data you already got.&lt;/p&gt;

&lt;p&gt;Both of those are the difference between "no cookies required" meaning something and it just meaning the empty rows are cheaper to produce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Packaged as a bulk LinkedIn profile lookup on Apify, no login needed on your end: &lt;a href="https://apify.com/0xgollum/reliable-linkedin-profiles" rel="noopener noreferrer"&gt;Reliable LinkedIn Profiles&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>webscraping</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why Trend-Data Scrapers Silently Fail (And How I Fixed It)</title>
      <dc:creator>0xGollum</dc:creator>
      <pubDate>Sat, 15 Aug 2026 09:01:12 +0000</pubDate>
      <link>https://dev.to/0xgollum/why-trend-data-scrapers-silently-fail-and-how-i-fixed-it-7a2</link>
      <guid>https://dev.to/0xgollum/why-trend-data-scrapers-silently-fail-and-how-i-fixed-it-7a2</guid>
      <description>&lt;p&gt;You give it a list of keywords. It hands back, per keyword, Google Trends' interest-over-time series plus the related queries — the same data you'd read off the Trends website, structured and ready to use.&lt;/p&gt;

&lt;p&gt;One keyword in, this is what comes out: a time series of interest scores over the period you asked for, and the list of related queries (rising and top) for that keyword.&lt;/p&gt;

&lt;p&gt;$30 per 1,000 results. And the part that actually matters: you're only billed for keywords that come back with real data. If a lookup fails after exhausting retries, it's logged and skipped — never charged. That's the whole point: you don't pay for the twenty-minute run that comes back empty.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "runs, returns nothing, bills you anyway" is the default failure mode
&lt;/h2&gt;

&lt;p&gt;Google Trends doesn't have a public API — every scraper, mine included, talks to the same internal endpoint the website itself uses, and it treats requests from datacenter IPs very differently from a real residential connection. A bare request from a dev machine, no proxy, got an instant 429: no warm-up, no browser fingerprint, just a blunt rejection. That's the failure mode hiding behind "ran 20 minutes, returned nothing" — the scraper isn't broken, it's being told no, and most scrapers don't handle that gracefully.&lt;/p&gt;

&lt;p&gt;There's a second failure mode, easy to miss: every JSON response from the Trends endpoint is prefixed with an anti-hijacking guard. Most write-ups online show it followed by a comma. On the real endpoint, it's followed by a bare newline instead — a parser hardcoded against the documented version worked fine against a mock and broke instantly against the live response.&lt;/p&gt;

&lt;p&gt;Two fixes, neither exotic. A residential proxy with a warm-up request first, which is what actually kills most of the blunt rejections — arguably a bigger lever than anything in the code. And session rotation instead of blind retries: a fresh proxy identity and cookies after a failure, capped attempts, exponential backoff so retries don't hammer the endpoint in a tight loop. If every attempt still comes back empty, that result is logged clearly and simply isn't pushed to output — not a silent empty row you already paid for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Packaged as a Google Trends scraper on Apify, interest-over-time plus related queries: &lt;a href="https://apify.com/0xgollum/reliable-trends-scraper" rel="noopener noreferrer"&gt;Reliable Trends Scraper&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Your competitor launched a new Facebook ad 3 days ago. Did you notice?</title>
      <dc:creator>0xGollum</dc:creator>
      <pubDate>Thu, 13 Aug 2026 08:32:19 +0000</pubDate>
      <link>https://dev.to/0xgollum/your-competitor-launched-a-new-facebook-ad-3-days-ago-did-you-notice-ggn</link>
      <guid>https://dev.to/0xgollum/your-competitor-launched-a-new-facebook-ad-3-days-ago-did-you-notice-ggn</guid>
      <description>&lt;p&gt;Checking a competitor's Meta Ad Library by hand means comparing screenshots from memory, or just not noticing which creative is actually new versus recycled from last month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What this actor does, in one line:&lt;/strong&gt; it wraps a Meta Ad Library source actor, keeps a persistent history so it only returns ads it hasn't seen before, and classifies the marketing angle used from the ad copy itself — discount, urgency, social proof, novelty, or conversion CTA — in French or English.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt; a Meta Ad Library search URL or a page ID.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output per new ad:&lt;/strong&gt; advertiser, headline, primary text, CTA, landing page URL, creative format, detected marketing angle, first-seen date.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Honest detail from building it:&lt;/strong&gt; the first version would still report a summary even if the source scrape failed halfway through — no way to tell an actually-empty result apart from a broken run. Fixed it to refuse and fail loudly instead of quietly reporting nothing.&lt;/p&gt;

&lt;p&gt;It also remembers what it already delivered, so scheduled runs only surface genuinely new creatives instead of the same ones every time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apify.com/0xgollum/meta-ads-competitor-intelligence" rel="noopener noreferrer"&gt;https://apify.com/0xgollum/meta-ads-competitor-intelligence&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>api</category>
      <category>marketing</category>
      <category>automation</category>
    </item>
    <item>
      <title>Your Google Maps reviews just tanked. How would you even know today?</title>
      <dc:creator>0xGollum</dc:creator>
      <pubDate>Wed, 12 Aug 2026 22:05:18 +0000</pubDate>
      <link>https://dev.to/0xgollum/your-google-maps-reviews-just-tanked-how-would-you-even-know-today-57cj</link>
      <guid>https://dev.to/0xgollum/your-google-maps-reviews-just-tanked-how-would-you-even-know-today-57cj</guid>
      <description>&lt;p&gt;Most business owners don't check their Google Maps reviews every day. A single 1-star review can sit unanswered for weeks. Worse: three negative reviews hitting the same business in the same week — a real reputation crisis — can go completely unnoticed until a client mentions it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What this actor does, in one line:&lt;/strong&gt; it wraps a Google Maps reviews source actor, keeps only new negative reviews (you set the rating threshold), flags a "crisis" when several hit the same business in one run, extracts the actual complaint theme (service, wait time, cleanliness, price...) in French and English, and drafts a professional response you can adapt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt; Google Maps place URLs — one client, or a whole portfolio of clients to monitor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output per alert:&lt;/strong&gt; rating, complaint themes, whether the owner already replied, crisis flag, a suggested response, and the review link.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Honest detail from building it:&lt;/strong&gt; the first version silently kept going if the source run failed halfway through, which meant it could alert on a partial, stale dataset without saying so. Fixed it to refuse and fail loudly instead of pretending everything's fine.&lt;/p&gt;

&lt;p&gt;It also remembers what it already alerted on: point it at the same business list on a schedule and it only surfaces genuinely new negative reviews, not the same ones every day.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apify.com/0xgollum/local-review-crisis-radar" rel="noopener noreferrer"&gt;https://apify.com/0xgollum/local-review-crisis-radar&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>api</category>
      <category>automation</category>
      <category>apimonitoring</category>
    </item>
    <item>
      <title>You scraped 200 local businesses. Which ones are worth calling first?</title>
      <dc:creator>0xGollum</dc:creator>
      <pubDate>Wed, 12 Aug 2026 21:27:26 +0000</pubDate>
      <link>https://dev.to/0xgollum/you-scraped-200-local-businesses-which-ones-are-worth-calling-first-3k63</link>
      <guid>https://dev.to/0xgollum/you-scraped-200-local-businesses-which-ones-are-worth-calling-first-3k63</guid>
      <description>&lt;p&gt;You ran a Google Maps scraper for "plumbers in your city" and got a spreadsheet back: name, address, phone, rating, review count. Two hundred rows. No way to tell which ones are actually missing a website, or drowning in bad reviews, without opening each listing by hand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What this actor does, in one line:&lt;/strong&gt; it wraps a Google Maps source actor, scores every business 0-100 on visible signals of unmet need — no website, low rating, too few reviews, no phone, no category — and tells you why in plain English, plus a recommended pitch for each one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt; any search + location, works in any country/language Google Maps supports — "dentists in New York, USA", "plombiers à Lyon, France", "roofers in London, UK".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output per lead:&lt;/strong&gt; business name, opportunity score + the exact reasons behind it ("No website detected", "Below-average Google rating (3.4)"...), a recommended pitch (website + GBP optimization, reputation management, review generation...), contact info, Maps link.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Honest bug I found building it:&lt;/strong&gt; the score was advertised as "0 to 100," but the actual math topped out at 92 in the worst case — nobody catches that kind of thing just reading the code, only by running the worst-case input through it. Recalibrated so a business with every red flag now genuinely scores 100.&lt;/p&gt;

&lt;p&gt;It also remembers what it already delivered: point it at the same search on a schedule and it only sends the leads you haven't seen yet, instead of the same 200 businesses every week.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apify.com/0xgollum/local-lead-opportunity-finder" rel="noopener noreferrer"&gt;https://apify.com/0xgollum/local-lead-opportunity-finder&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webscraping</category>
      <category>api</category>
      <category>leadgen</category>
      <category>automation</category>
    </item>
    <item>
      <title>You scraped 500 leads. How many of those emails actually exist?</title>
      <dc:creator>0xGollum</dc:creator>
      <pubDate>Tue, 11 Aug 2026 17:40:40 +0000</pubDate>
      <link>https://dev.to/0xgollum/you-scraped-500-leads-how-many-of-those-emails-actually-exist-3fp9</link>
      <guid>https://dev.to/0xgollum/you-scraped-500-leads-how-many-of-those-emails-actually-exist-3fp9</guid>
      <description>&lt;p&gt;You bought or scraped a list of leads. Every row has a name, a company, maybe an email pulled from a Google Maps listing or a website footer. Nothing tells you which of those emails are about to bounce.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What this actor does, in one line:&lt;/strong&gt; give it a list of website URLs, it visits each one and gives back every email it finds — plus two checks on each address: is it real (does the domain have a mail server?) and is it worth reaching out to (a named person on the company's own domain, vs. a generic info@ mailbox, vs. someone's personal Gmail)?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt; a list of website URLs — the output of a Google Maps scraper, a LinkedIn export, or any CSV of leads you already have.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output, per email found:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;deliverability&lt;/code&gt;: &lt;code&gt;mx_confirmed&lt;/code&gt; (the domain has a real mail server) or &lt;code&gt;no_mx_record&lt;/code&gt; (the domain can't receive mail — this address is dead, skip it)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;address_type&lt;/code&gt;: &lt;code&gt;corporate_personal&lt;/code&gt; (a named contact on the company's own domain — the good one), &lt;code&gt;role_or_generic&lt;/code&gt; (info@, contact@ — still usable, just not a person), or &lt;code&gt;personal_free_provider&lt;/code&gt; (a real person, but on gmail.com/yahoo.com, not the company)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;source&lt;/code&gt;: &lt;code&gt;mailto&lt;/code&gt; (wired into a real clickable link — trust it) or &lt;code&gt;text&lt;/code&gt; (found as plain text — usually real too, but this is also where fictional example emails hide: found this the hard way testing against a well-known payments company's homepage, which surfaced a made-up customer email used in a product screenshot)&lt;/li&gt;
&lt;li&gt;Whatever LinkedIn/X/Instagram/Facebook links are on the same page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What it deliberately doesn't do:&lt;/strong&gt; a live SMTP handshake (actually connecting to the mail server to check one specific mailbox). Outbound port 25 is blocked on most infrastructure to stop spam — mine included, while building this. &lt;code&gt;mx_confirmed&lt;/code&gt; is the strongest signal available without it; it's not a guarantee, and the README says so instead of pretending otherwise.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apify.com/0xgollum/lead-contact-verifier" rel="noopener noreferrer"&gt;https://apify.com/0xgollum/lead-contact-verifier&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>api</category>
      <category>webscraping</category>
      <category>leadgen</category>
    </item>
    <item>
      <title>Most sportsbook APIs block datacenter IPs on sight. I found the one sharp book that doesn't - and it's the one that matters most.</title>
      <dc:creator>0xGollum</dc:creator>
      <pubDate>Sun, 09 Aug 2026 07:52:12 +0000</pubDate>
      <link>https://dev.to/0xgollum/most-sportsbook-apis-block-datacenter-ips-on-sight-i-found-the-one-sharp-book-that-doesnt-and-4me0</link>
      <guid>https://dev.to/0xgollum/most-sportsbook-apis-block-datacenter-ips-on-sight-i-found-the-one-sharp-book-that-doesnt-and-4me0</guid>
      <description>&lt;p&gt;Sharp bettors and syndicates watch odds move for a reason: when real money hits one side of a match fast, the market's implied probability shifts - often ahead of news (injury, lineup change, sharp money) reaching the public. By the time it's obvious, the value is gone.&lt;/p&gt;

&lt;p&gt;This actor watches Pinnacle's live match odds around the clock. For every match it tracks, you get a snapshot: current odds and implied probability per outcome. Between runs, it flags the moves that matter - a "steamer" when money is coming in fast on one side, a "drifter" when confidence is draining out. Coverage follows where the real depth is: major football nations and international tournaments, shifting automatically to World Cup or Euro matches during a tournament and back to domestic leagues the rest of the year, no config needed.&lt;/p&gt;

&lt;p&gt;Most sportsbook APIs make this hard to watch programmatically - DraftKings and FanDuel are geo-gated and sit behind Akamai bot protection, blocking datacenter IPs outright. Pinnacle doesn't: its own guest API, the same JSON its web client renders, works cleanly from any datacenter IP, no proxy needed. It's also the reference sharp book, the one line syndicates actually watch, not a recreational-book average diluted by public money. That's also why this actor pulls Pinnacle's live league index every run instead of hardcoding a league list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apify.com/0xgollum/soccer-odds-pulse" rel="noopener noreferrer"&gt;https://apify.com/0xgollum/soccer-odds-pulse&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>api</category>
      <category>webscraping</category>
    </item>
    <item>
      <title>A shortening horse racing price is one of the oldest tells in betting. I built something to catch it before the off.</title>
      <dc:creator>0xGollum</dc:creator>
      <pubDate>Sat, 08 Aug 2026 18:55:53 +0000</pubDate>
      <link>https://dev.to/0xgollum/a-shortening-horse-racing-price-is-one-of-the-oldest-tells-in-betting-i-built-something-to-catch-46l7</link>
      <guid>https://dev.to/0xgollum/a-shortening-horse-racing-price-is-one-of-the-oldest-tells-in-betting-i-built-something-to-catch-46l7</guid>
      <description>&lt;p&gt;Pari-mutuel odds aren't set by a bookmaker - they float with the betting pool right up until the race starts. When real money lands on a horse, its implied probability jumps and the price shortens, fast. By the time a human notices, the move is usually half over.&lt;/p&gt;

&lt;p&gt;This actor watches every PMU (France's official pari-mutuel operator) race still open for betting and flags that movement as it happens: a steamer when a horse's implied probability jumps between runs, a drifter when it fades. Only races with an active status get scanned - anything already off is skipped automatically, so every run does useful work.&lt;/p&gt;

&lt;p&gt;The data source is PMU's own public JSON API - the same one their website and app use, no key, no login, no proxy. As an opt-in extra, the actor can also flag hidden form patterns per horse: a jockey switch on the day, a horse still winless after ten-plus starts, earnings swinging sharply year over year - things a human would normally have to cross-reference by hand to catch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apify.com/0xgollum/horse-racing-pulse" rel="noopener noreferrer"&gt;https://apify.com/0xgollum/horse-racing-pulse&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>api</category>
      <category>betting</category>
      <category>webscraping</category>
    </item>
  </channel>
</rss>
