<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Daily-Dev]]></title><description><![CDATA[Daily-Dev]]></description><link>https://development-daily-ak.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Tue, 08 Sep 2026 03:03:20 GMT</lastBuildDate><atom:link href="https://development-daily-ak.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[🔍 Building a LeetCode Rank Search Chrome Extension — Track Multiple Users in One Click!]]></title><description><![CDATA[🧠 Motivation
Have you ever participated in a LeetCode contest and then spent time manually flipping through rank pages just to find where you or your friends placed?
I did too. And it was painful.
So, I decided to solve it with code — by building a ...]]></description><link>https://development-daily-ak.hashnode.dev/building-a-leetcode-rank-search-chrome-extension-track-multiple-users-in-one-click</link><guid isPermaLink="true">https://development-daily-ak.hashnode.dev/building-a-leetcode-rank-search-chrome-extension-track-multiple-users-in-one-click</guid><category><![CDATA[automation]]></category><category><![CDATA[webscraping ]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[extension]]></category><category><![CDATA[leetcode]]></category><dc:creator><![CDATA[Asutosh Kataruka]]></dc:creator><pubDate>Thu, 26 Jun 2025 15:15:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1750950799216/2c545839-c6f0-4bc3-913a-3293a538ae52.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-motivation">🧠 Motivation</h2>
<p>Have you ever participated in a LeetCode contest and then spent time manually flipping through rank pages just to find where you or your friends placed?</p>
<p>I did too. And it was painful.</p>
<p>So, I decided to solve it with code — by building a <strong>Chrome extension</strong> that automates this entire process!</p>
<p>In this post, I’ll walk you through:</p>
<ul>
<li><p>Challenge for data access on LeetCode 🚫</p>
</li>
<li><p>The idea 💡</p>
</li>
<li><p>The tech stack ⚙️</p>
</li>
<li><p>How it works 🧩</p>
</li>
<li><p>Chrome extension architecture 🧱</p>
</li>
<li><p>Publishing &amp; usage 🚀</p>
</li>
</ul>
<hr />
<h2 id="heading-overcoming-the-challenge-of-data-access-on-leetcode">Overcoming the Challenge of Data Access on LeetCode</h2>
<h3 id="heading-api-blocking-by-leetcode">🚫 API Blocking by LeetCode</h3>
<p>LeetCode has strict anti-bot mechanisms in place that block automated API requests. This makes traditional API-based data retrieval methods unreliable for scraping or automation tasks.</p>
<h3 id="heading-dynamic-frontend-architecture">🔄 Dynamic Frontend Architecture</h3>
<p>LeetCode’s frontend is built on dynamic JavaScript frameworks. The platform frequently updates its internal routing, selectors, and page structures, often breaking static scraping solutions.</p>
<h3 id="heading-our-adaptive-solution-real-time-page-scraping">✅ Our Adaptive Solution: Real-Time Page Scraping</h3>
<p>To overcome these challenges, we implemented <strong>real-time page scraping</strong> using browser automation. By simulating real user interactions, we dynamically search for usernames on the leaderboard and determine their corresponding pages.</p>
<h3 id="heading-smart-dom-traversal-for-robustness">🧠 Smart DOM Traversal for Robustness</h3>
<p>Instead of relying on static links or outdated selectors, our method adapts to DOM changes by querying elements intelligently. This makes our solution more robust against frontend updates and layout shifts.</p>
<h3 id="heading-result-resilient-and-reliable-data-extraction">💡 Result: Resilient and Reliable Data Extraction</h3>
<p>This adaptive approach ensures that we can consistently retrieve user data from LeetCode, even as the platform evolves. It strikes a balance between compliance and flexibility in a dynamically changing environment.</p>
<hr />
<h2 id="heading-what-the-extension-does">📌 What the Extension Does</h2>
<p><strong>LeetCode Rank Search</strong> is a Chrome extension that:</p>
<p>✅ Lets you enter multiple LeetCode usernames ✅ Automatically flips through contest ranking pages ✅ Finds the page number for each user ✅ Stops when all users are found ✅ Gives you a friendly floating UI to view results</p>
<hr />
<h2 id="heading-tech-stack">⚙️ Tech Stack</h2>
<ul>
<li>🧭 <strong>JavaScript</strong> (Vanilla, for DOM manipulation &amp; search logic)</li>
</ul>
<hr />
<h2 id="heading-folder-structure">🧰 Folder Structure</h2>
<pre><code class="lang-plaintext">leetcode-rank-search-extension/
├── manifest.json
├── background.js
├── content.js
├── popup.html
├── popup.js
├── styles.css
├── icon16.png
├── icon48.png
├── icon128.png
├── screenshot.png
└── README.md
</code></pre>
<hr />
<h2 id="heading-key-components">🧱 Key Components</h2>
<h3 id="heading-1-manifestjson">1. <code>manifest.json</code></h3>
<p>The <strong>brain</strong> of the extension, defining permissions, content scripts, icons, and popup.</p>
<pre><code class="lang-json"><span class="hljs-string">"content_scripts"</span>: [
  {
    <span class="hljs-attr">"matches"</span>: [<span class="hljs-string">"https://leetcode.com/contest/*/ranking/*"</span>],
    <span class="hljs-attr">"js"</span>: [<span class="hljs-string">"content.js"</span>]
  }
],
<span class="hljs-string">"action"</span>: {
  <span class="hljs-attr">"default_popup"</span>: <span class="hljs-string">"popup.html"</span>
},
<span class="hljs-string">"icons"</span>: {
  <span class="hljs-attr">"16"</span>: <span class="hljs-string">"icon16.png"</span>,
  <span class="hljs-attr">"48"</span>: <span class="hljs-string">"icon48.png"</span>,
  <span class="hljs-attr">"128"</span>: <span class="hljs-string">"icon128.png"</span>
}
</code></pre>
<h3 id="heading-2-popuphtml-popupjs">2. <code>popup.html</code> + <code>popup.js</code></h3>
<p>Provides a simple UI button (<code>Start Search</code>) that sends a message to the active tab to trigger the rank search.</p>
<h3 id="heading-3-contentjs">3. <code>content.js</code></h3>
<p>Handles:</p>
<ul>
<li><p>Prompting for user IDs</p>
</li>
<li><p>Navigating back to the first page</p>
</li>
<li><p>Looping through rank pages</p>
</li>
<li><p>Detecting usernames</p>
</li>
<li><p>Updating the floating dialog</p>
</li>
<li><p>Handling STOP and Search Again</p>
</li>
</ul>
<hr />
<h2 id="heading-how-the-flow-works">🔄 How the Flow Works</h2>
<ol>
<li><p>You open the <strong>LeetCode contest ranking page</strong> (e.g., <code>weekly-contest-455/ranking</code>)</p>
</li>
<li><p>Click the extension icon → hit <strong>“Start Search”</strong></p>
</li>
<li><p>You enter usernames like: <code>alice123, bob_dev, codewarrior</code></p>
</li>
<li><p>Extension:</p>
<ul>
<li><p>Goes to the <strong>first page</strong></p>
</li>
<li><p>Starts flipping pages</p>
</li>
<li><p>Checks for usernames on each page</p>
</li>
<li><p>Displays found page numbers in a nice floating box</p>
</li>
<li><p>Stops when done or on your command</p>
</li>
</ul>
</li>
</ol>
<hr />
<h2 id="heading-special-features">💡 Special Features</h2>
<ul>
<li><p>✅ Multi-user support</p>
</li>
<li><p>🛑 Manual STOP at any time</p>
</li>
<li><p>🔄 <strong>Search Again</strong> without reloading</p>
</li>
<li><p>❌ Close button to dismiss the box</p>
</li>
<li><p>🧱 Handles dynamically loaded LeetCode pages</p>
</li>
<li><p>🧠 <strong>Special case handled</strong>: if rank table not found, instructs user to reload the page</p>
</li>
</ul>
<hr />
<h2 id="heading-preview">📸 Preview</h2>
<p><img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/81sj3ioapeonq0o2h7z6.png" alt="LeetCode Rank Search Extension Preview" /></p>
<blockquote>
<p>A floating UI helps you track user ranks in real-time while flipping pages automatically.</p>
</blockquote>
<hr />
<h2 id="heading-common-pitfall-rank-page-not-found">⚠️ Common Pitfall: Rank Page Not Found?</h2>
<p>Sometimes LeetCode uses dynamic loading which makes the table undetectable initially.</p>
<blockquote>
<p>🔧 <strong>Fix:</strong> Just reload the contest rank page and try again.</p>
</blockquote>
<hr />
<h2 id="heading-how-to-install-locally">🚀 How to Install Locally</h2>
<ol>
<li><p>Clone the repo or download ZIP</p>
</li>
<li><p>Go to <code>chrome://extensions</code></p>
</li>
<li><p>Enable <strong>Developer Mode</strong></p>
</li>
<li><p>Click <strong>“Load unpacked”</strong> and select the folder</p>
</li>
<li><p>Visit any LeetCode contest rank page and start using it!</p>
</li>
</ol>
<hr />
<h2 id="heading-open-source">🔓 Open Source</h2>
<p>Find the full source code on GitHub:</p>
<p>👉 <a target="_blank" href="https://github.com/Akataruka/leetcode-rank-search-extension">GitHub Repo Link</a></p>
<p>Feel free to star, fork, or contribute!</p>
<hr />
<h2 id="heading-final-thoughts">🙌 Final Thoughts</h2>
<p>This was a fun weekend project that solved a real annoyance and introduced me to the world of Chrome Extensions + browser scripting.</p>
<p>If you're into problem-solving, automating workflows, or just love clean tools — consider trying it out!</p>
<p>Thanks for reading! 💛</p>
<hr />
<h3 id="heading-more-about-author">More about Author</h3>
<p>👉 <a target="_blank" href="https://linktr.ee/asutoshk_09">Asutoshk - Linktree</a></p>
]]></content:encoded></item><item><title><![CDATA[Crafting Perfect Cold Messages: My AI-Powered Streamlit App Journey 🧊]]></title><description><![CDATA[The digital world thrives on connections, and often, those connections start with a "cold" message. Whether it's for a dream job, a collaboration, or just networking, crafting personalized, impactful messages can be a time sink. This challenge inspir...]]></description><link>https://development-daily-ak.hashnode.dev/crafting-perfect-cold-messages-my-ai-powered-streamlit-app-journey</link><guid isPermaLink="true">https://development-daily-ak.hashnode.dev/crafting-perfect-cold-messages-my-ai-powered-streamlit-app-journey</guid><category><![CDATA[Python]]></category><category><![CDATA[genai]]></category><category><![CDATA[llm]]></category><category><![CDATA[langchain]]></category><category><![CDATA[streamlit]]></category><category><![CDATA[dailydev]]></category><category><![CDATA[coldmail]]></category><dc:creator><![CDATA[Asutosh Kataruka]]></dc:creator><pubDate>Fri, 20 Jun 2025 06:58:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1750401783315/d65b4378-3cbb-47c9-8e9e-54b85c00ffcc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The digital world thrives on connections, and often, those connections start with a "cold" message. Whether it's for a dream job, a collaboration, or just networking, crafting personalized, impactful messages can be a time sink. This challenge inspired me to build the <strong>Cold Message Generator</strong> – an AI-powered Streamlit application designed to automate and enhance this process.</p>
<p>In this post, I'll walk you through how this app works, its core functionalities, and the step-by-step workflow that empowers you to create compelling outreach messages in minutes.</p>
<h2 id="heading-the-problem-tedious-amp-time-consuming-outreach">The Problem: Tedious &amp; Time-Consuming Outreach</h2>
<p>We've all been there: staring at a blank screen, trying to figure out how to introduce ourselves or pitch an idea to someone we don't know. Manually extracting relevant details from a resume, summarizing key achievements, and then weaving it all into a compelling message is a multi-step process that demands attention to detail and significant time.</p>
<p>My goal was to create a tool that could significantly reduce this effort, allowing users to focus on the <em>relationship</em> rather than the <em>drafting</em>.</p>
<h2 id="heading-the-solution-a-seamless-ai-powered-workflow">The Solution: A Seamless AI-Powered Workflow</h2>
<p>The <strong>Cold Message Generator</strong> automates much of this process using the power of Large Language Models (LLMs) and a friendly Streamlit interface. Here’s a detailed look at the user experience and the underlying processes:</p>
<h3 id="heading-step-1-secure-setup-amp-resume-upload">Step 1: Secure Setup &amp; Resume Upload 🚀</h3>
<p>The journey begins when you launch the application.</p>
<ul>
<li><p><strong>API Key Input:</strong> First, you'll provide your Groq API key in the dedicated sidebar section. This ensures the app has the necessary credentials to communicate with the powerful AI models.</p>
</li>
<li><p><strong>Resume Upload:</strong> The primary input is your resume. You simply upload your resume in PDF format using the designated file uploader.</p>
</li>
</ul>
<p>Once your resume is uploaded, the application immediately gets to work behind the scenes:</p>
<ul>
<li><p><strong>Text Extraction:</strong> The system rapidly extracts all textual content from your PDF resume.</p>
</li>
<li><p><strong>Initial Link Discovery:</strong> Simultaneously, it scans the extracted text for any visible URLs.</p>
</li>
</ul>
<h3 id="heading-step-2-intelligent-link-classification-amp-summarization">Step 2: Intelligent Link Classification &amp; Summarization 🧠</h3>
<p>This is where the AI and smart processing truly shine, transforming raw data into actionable insights.</p>
<ul>
<li><p><strong>Hidden Link Classification:</strong> Beyond simple extraction, the app employs a specialized utility that goes through the discovered links. It intelligently classifies ambiguous or "hidden" links, ensuring that your LinkedIn, GitHub, and personal portfolio URLs are correctly identified and categorized, ready for easy inclusion in your message.</p>
</li>
<li><p><strong>AI-Powered Resume Summarization:</strong> The full text of your resume is then sent to an advanced LLM. This AI model doesn't just condense text; it analyzes your experience and skills to generate a concise, professional, and impactful summary. This summary is automatically populated into a dedicated text area on the screen, ready for your review. This feature saves you the significant effort of crafting a summary from scratch.</p>
</li>
</ul>
<p>At this point, you'll see the AI-generated summary and any automatically detected and classified links pre-filled into input fields, allowing you to easily review and make any minor adjustments or add links if they weren't detected.</p>
<h3 id="heading-step-3-message-tailoring-amp-template-generation">Step 3: Message Tailoring &amp; Template Generation ✍️</h3>
<p>With your profile data processed, you guide the AI in crafting the perfect message.</p>
<ul>
<li><p><strong>Define Message Type:</strong> You select the desired message type from a dropdown, such as "Cold Email," "LinkedIn Message," or "Other," indicating the communication channel.</p>
</li>
<li><p><strong>Specify Target Role:</strong> You input the specific job title or role you're targeting (e.g., "Software Engineer," "Data Scientist"). This critical piece of information allows the AI to tailor the message's content directly to the context of that role.</p>
</li>
<li><p><strong>Trigger Generation:</strong> With a simple click of the "Generate Template" button, the application sends all your prepared inputs – the refined resume summary, your social links, the chosen message type, and the target job type – back to the LLM.</p>
</li>
</ul>
<p>The AI then processes this comprehensive input to produce a customized message template. This template is designed for immediate use and includes dynamic placeholders, specifically <code>{{recipient_name}}</code> and <code>{{company_name}}</code>.</p>
<h3 id="heading-step-4-final-personalization-amp-send-ready-message">Step 4: Final Personalization &amp; Send-Ready Message ✨</h3>
<p>The last mile of customization is in your hands, leading to a complete, ready-to-send message.</p>
<ul>
<li><p><strong>Recipient Details Input:</strong> You'll see dedicated input fields where you simply type in the specific recipient's name and the company's name for your current outreach.</p>
</li>
<li><p><strong>Final Message Creation:</strong> Upon clicking "Generate Message," the application seamlessly substitutes your entered recipient and company names into the template's placeholders.</p>
</li>
</ul>
<p>The result is a fully formatted, personalized message displayed in a large text area, ready for you to copy and paste directly into your email client or LinkedIn message window. This entire process significantly reduces manual effort, allowing you to scale your outreach while maintaining a personalized touch.</p>
<h2 id="heading-why-groq-amp-streamlit-under-the-hood-efficiency">Why Groq &amp; Streamlit? (Under the Hood Efficiency)</h2>
<ul>
<li><p><strong>Groq's Blazing Speed:</strong> The choice of Groq's API for the LLM inference is crucial. Its Language Processing Units (LPUs) provide incredible speed, making the AI summarization and message generation almost instantaneous. This eliminates frustrating wait times, providing a snappy user experience that truly saves time.</p>
</li>
<li><p><strong>Streamlit's User-Friendliness:</strong> For building interactive Python web applications, Streamlit is a fantastic choice. Its simplicity allowed me to focus primarily on the core AI logic and user workflow, rather than getting bogged down in complex web development frameworks.</p>
</li>
<li><p><strong>Robust Backend Logic:</strong> Leveraging libraries like LangChain helps orchestrate the LLM calls and ensures structured outputs. Pydantic schemas enforce data consistency, guaranteeing that the AI's responses are always in the expected format, leading to reliable processing at every step.</p>
</li>
</ul>
<h2 id="heading-future-enhancements">Future Enhancements</h2>
<p>I'm always thinking about how to make this tool even better:</p>
<ul>
<li><p><strong>Expanded Message Types:</strong> Introducing options for networking events, informational interview requests, and more diverse outreach scenarios.</p>
</li>
<li><p><strong>Tone Customization:</strong> Allowing users to specify the desired tone (e.g., formal, friendly, direct, assertive) for their messages.</p>
</li>
<li><p><strong>ATS Keyword Optimization:</strong> Integrating functionality to analyze job descriptions and suggest relevant keywords to include in the message for Applicant Tracking System (ATS) compatibility.</p>
</li>
<li><p><strong>Basic CRM Integration:</strong> Exploring options for simple export functionality to popular Customer Relationship Management (CRM) tools.</p>
</li>
</ul>
<h2 id="heading-try-it-yourself">Try it Yourself!</h2>
<p>Ready to automate your outreach and make impactful first impressions?</p>
<ul>
<li><p><strong>Experience the Web App:</strong> <a target="_blank" href="https://akataruka-message-creater-app-razmkn.streamlit.app/"><strong>Cold Message Generator</strong></a></p>
</li>
<li><p><strong>Dive into the Codebase:</strong> Find the full project on <a target="_blank" href="https://github.com/Akataruka/message_creater">GitHub</a></p>
</li>
<li><p><strong>See More of My Work:</strong> Check out my portfolio at <a target="_blank" href="http://asutosh-kataruka.vercel.app">asutosh-kataruka.vercel.app</a></p>
</li>
</ul>
<p>I'm keen to hear your feedback, suggestions, or ideas for future improvements! Drop a comment below or reach out on GitHub.</p>
<hr />
]]></content:encoded></item></channel></rss>