<?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: Amit Wani</title>
    <description>The latest articles on DEV Community by Amit Wani (@mtwn105).</description>
    <link>https://dev.to/mtwn105</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F728995%2Fc44c0cc5-8fbf-4c42-ab4f-e1957baeb03a.jpeg</url>
      <title>DEV Community: Amit Wani</title>
      <link>https://dev.to/mtwn105</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mtwn105"/>
    <language>en</language>
    <item>
      <title>DecipherIt: Building a NotebookLM-Inspired AI Research Assistant powered by Bright Data</title>
      <dc:creator>Amit Wani</dc:creator>
      <pubDate>Sun, 25 May 2025 22:13:33 +0000</pubDate>
      <link>https://dev.to/mtwn105/decipherit-building-a-notebooklm-inspired-ai-research-assistant-powered-by-bright-data-ckf</link>
      <guid>https://dev.to/mtwn105/decipherit-building-a-notebooklm-inspired-ai-research-assistant-powered-by-bright-data-ckf</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/brightdata-2025-05-07"&gt;Bright Data AI Web Access Hackathon&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;DecipherIt&lt;/strong&gt; is a cutting-edge AI-powered research assistant inspired by &lt;strong&gt;Google NotebookLM&lt;/strong&gt; that revolutionizes how researchers, students, and professionals explore, analyze, and synthesize information from the web. The platform transforms any combination of documents, URLs, or topics into comprehensive research notebooks complete with AI-generated summaries, interactive Q&amp;amp;A capabilities, audio overviews, visual mindmaps, and automatically generated FAQs.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem DecipherIt Solves
&lt;/h3&gt;

&lt;p&gt;Traditional research is time-consuming and fragmented. Researchers often struggle with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Information Overload&lt;/strong&gt;: Sifting through countless sources manually&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geo-restrictions&lt;/strong&gt;: Unable to access content from different regions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bot Detection&lt;/strong&gt;: Getting blocked when trying to scrape valuable data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synthesis Challenges&lt;/strong&gt;: Difficulty connecting insights across multiple sources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility&lt;/strong&gt;: Converting research into different formats for various audiences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DecipherIt addresses these challenges by leveraging &lt;strong&gt;Bright Data's MCP Server&lt;/strong&gt; to provide unrestricted, intelligent web access combined with advanced AI agents that can understand, synthesize, and present information in multiple formats.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;p&gt;🔬 &lt;strong&gt;Deep Research&lt;/strong&gt; - Conduct thorough research on any topic with AI-assisted analysis and synthesis&lt;br&gt;
🔍 &lt;strong&gt;Multi-Source Research&lt;/strong&gt; - Seamlessly integrate documents, URLs, and manual text into unified research spaces&lt;br&gt;
🤖 &lt;strong&gt;AI-Powered Summaries&lt;/strong&gt; - Generate comprehensive, well-structured research analyses using advanced AI agents&lt;br&gt;
💬 &lt;strong&gt;Interactive Q&amp;amp;A&lt;/strong&gt; - Chat with your research materials using natural language queries&lt;br&gt;
🎧 &lt;strong&gt;Audio Overviews&lt;/strong&gt; - AI-generated podcast-style audio summaries with multiple voices&lt;br&gt;
❓ &lt;strong&gt;Smart FAQ Generation&lt;/strong&gt; - Automatically create relevant FAQs from your research content&lt;br&gt;
🧠 &lt;strong&gt;Visual Mindmaps&lt;/strong&gt; - Generate interactive, hierarchical mindmaps to visualize research structure and connections&lt;br&gt;
🌐 &lt;strong&gt;Global Web Access&lt;/strong&gt; - Bypass geo-restrictions and bot detection using Bright Data's infrastructure&lt;/p&gt;
&lt;h3&gt;
  
  
  🔍 &lt;strong&gt;Detailed Feature Overview&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;🔬 Deep Research&lt;/strong&gt;&lt;br&gt;
DecipherIt's AI agents conduct comprehensive research by strategically planning data collection, discovering diverse sources through Bright Data's global search capabilities, and synthesizing information from multiple perspectives. The system can research any topic from current events to academic subjects, providing thorough analysis that rivals human researchers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔍 Multi-Source Research&lt;/strong&gt;&lt;br&gt;
Users can combine various input types in a single research project: upload documents (PDF, DOCX, PPTX, XLSX), add custom URLs for specific web content, input manual text for direct analysis, or simply enter topics for AI-driven discovery. All sources are processed and integrated into a unified research space.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🤖 AI-Powered Summaries&lt;/strong&gt;&lt;br&gt;
Specialized CrewAI agents work together to create comprehensive research summaries. The Research Analyst synthesizes information from all sources, while the Content Writer crafts engaging, well-structured analyses that highlight key insights, trends, and connections across the research material.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💬 Interactive Q&amp;amp;A&lt;/strong&gt;&lt;br&gt;
Using vector embeddings and semantic search through Qdrant database, users can ask natural language questions about their research content. The system provides contextual answers by retrieving relevant information from all processed sources, enabling deep exploration of the research material.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎧 Audio Overviews&lt;/strong&gt;&lt;br&gt;
On-demand feature that transforms research into engaging podcast-style audio content. The Podcast Script Generator agent creates conversational scripts, which are then converted to high-quality audio using LemonFox TTS with multiple AI voices, making research accessible in audio format.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;❓ Smart FAQ Generation&lt;/strong&gt;&lt;br&gt;
AI agents automatically analyze research content to generate relevant, insightful questions and comprehensive answers. This feature helps users understand key aspects of their research topic and provides quick access to important information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧠 Visual Mindmaps&lt;/strong&gt;&lt;br&gt;
The Mindmap Creator agent analyzes research structure to generate interactive, hierarchical visualizations with up to 5 levels of depth. Built with react-mindmap-visualiser, these mindmaps help users understand complex topics at a glance and navigate research relationships visually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🌐 Global Web Access&lt;/strong&gt;&lt;br&gt;
Powered by Bright Data's MCP Server, DecipherIt bypasses geo-restrictions and bot detection to access content from anywhere in the world. This ensures comprehensive research coverage and access to diverse, authoritative sources that traditional scraping methods cannot reach.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🚀 &lt;strong&gt;Live Demo&lt;/strong&gt;: &lt;a href="https://decipherit.xyz" rel="noopener noreferrer"&gt;https://decipherit.xyz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo Credentials&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Email: &lt;a href="mailto:demo@dev.to"&gt;demo@dev.to&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Password: demodemo@123&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📂 &lt;strong&gt;GitHub Repository&lt;/strong&gt;: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mtwn105" rel="noopener noreferrer"&gt;
        mtwn105
      &lt;/a&gt; / &lt;a href="https://github.com/mtwn105/decipher-research-agent" rel="noopener noreferrer"&gt;
        decipher-research-agent
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Turn topics, links, and files into AI-generated research notebooks — summarize, explore, and ask anything.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🔍 DecipherIt - AI-Powered Research Assistant&lt;/h1&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/b5efb4a4a2fc0db3c09f48d5d072813603a59bcfde4985f8aff9ffcfff8adca2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f446563697068657249742d41492532305265736561726368253230417373697374616e742d626c75653f7374796c653d666f722d7468652d6261646765266c6f676f3d646174613a696d6167652f7376672b786d6c3b6261736536342c50484e325a79423361575230614430694d6a51694947686c6157646f644430694d6a516949485a705a58644362336739496a41674d4341794e4341794e4349675a6d6c7362443069626d39755a53496765473173626e4d39496d6830644841364c79393364336375647a4d7562334a6e4c7a49774d44417663335a6e496a344b50484268644767675a4430695454457949444a4d4d544d754d446b674f4334794e6b77794d4341355444457a4c6a4135494445314c6a63305444457949444979544445774c6a6b78494445314c6a6330544451674f5577784d4334354d5341344c6a49325444457949444a614969426d6157787350534a6a64584a795a57353051323973623349694c7a344b5043397a646d632b"&gt;&lt;img src="https://camo.githubusercontent.com/b5efb4a4a2fc0db3c09f48d5d072813603a59bcfde4985f8aff9ffcfff8adca2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f446563697068657249742d41492532305265736561726368253230417373697374616e742d626c75653f7374796c653d666f722d7468652d6261646765266c6f676f3d646174613a696d6167652f7376672b786d6c3b6261736536342c50484e325a79423361575230614430694d6a51694947686c6157646f644430694d6a516949485a705a58644362336739496a41674d4341794e4341794e4349675a6d6c7362443069626d39755a53496765473173626e4d39496d6830644841364c79393364336375647a4d7562334a6e4c7a49774d44417663335a6e496a344b50484268644767675a4430695454457949444a4d4d544d754d446b674f4334794e6b77794d4341355444457a4c6a4135494445314c6a63305444457949444979544445774c6a6b78494445314c6a6330544451674f5577784d4334354d5341344c6a49325444457949444a614969426d6157787350534a6a64584a795a57353051323973623349694c7a344b5043397a646d632b" alt="DecipherIt Logo"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Transform your research process with AI-powered intelligence&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://nextjs.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3e2e7f1311e2c973fbaf78b931c58686f23339932f390f135088a5c1b41cc206/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4e6578742e6a732d31352e332e322d626c61636b3f7374796c653d666c61742d737175617265266c6f676f3d6e6578742e6a73" alt="Next.js"&gt;&lt;/a&gt;
&lt;a href="https://reactjs.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/dceb2c2665087de4b8fab7799a2ee92eee3487a153196f0062da9410b74bf717/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f52656163742d31392e302e302d626c75653f7374796c653d666c61742d737175617265266c6f676f3d7265616374" alt="React"&gt;&lt;/a&gt;
&lt;a href="https://python.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/807252c6cff24d131a3381ca3bfb31e16b34adfc533e605432a3ebffd29ff466/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d332e31322d626c75653f7374796c653d666c61742d737175617265266c6f676f3d707974686f6e" alt="Python"&gt;&lt;/a&gt;
&lt;a href="https://fastapi.tiangolo.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/52e7a33de1924de56694007a2814ffa098b57d026f9c0f1720cd457beae66cb5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f466173744150492d4c61746573742d677265656e3f7374796c653d666c61742d737175617265266c6f676f3d66617374617069" alt="FastAPI"&gt;&lt;/a&gt;
&lt;a href="https://typescriptlang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b995d8224e72a0fa717f2cdb567c2c5c47320652afbf91c370e227cfb94c542b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f547970655363726970742d352e302d626c75653f7374796c653d666c61742d737175617265266c6f676f3d74797065736372697074" alt="TypeScript"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://decipherit.xyz" rel="nofollow noopener noreferrer"&gt;🚀 Live Demo&lt;/a&gt; • &lt;a href="https://github.com/mtwn105/decipher-research-agent#installation" rel="noopener noreferrer"&gt;🛠️ Installation&lt;/a&gt; • &lt;a href="https://github.com/mtwn105/decipher-research-agent#contributing" rel="noopener noreferrer"&gt;🤝 Contributing&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;⭐ Star on GitHub!&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;&lt;a href="https://www.star-history.com/#mtwn105/decipher-research-agent&amp;amp;Date" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5b14edc45e6c157a728256b8cebf2bdc5b5960a12614f018e1ffbe3d92c37c8a/68747470733a2f2f6170692e737461722d686973746f72792e636f6d2f7376673f7265706f733d6d74776e3130352f64656369706865722d72657365617263682d6167656e7426747970653d44617465" alt="Star History Chart"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Overview&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;DecipherIt is a cutting-edge AI-powered research assistant inspired by &lt;strong&gt;Google NotebookLM&lt;/strong&gt; that revolutionizes how researchers, students, and professionals explore, analyze, and synthesize information from the web. The platform transforms any combination of documents, URLs, or topics into comprehensive research notebooks complete with AI-generated summaries, interactive Q&amp;amp;A capabilities, audio overviews, visual mindmaps, and automatically generated FAQs.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;The Problem DecipherIt Solves&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Traditional research is time-consuming and fragmented. Researchers often struggle with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Information Overload&lt;/strong&gt;: Sifting through countless sources manually&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geo-restrictions&lt;/strong&gt;: Unable to access content from different regions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bot Detection&lt;/strong&gt;: Getting blocked when trying to scrape valuable data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synthesis Challenges&lt;/strong&gt;: Difficulty connecting insights across multiple sources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility&lt;/strong&gt;: Converting research into different formats for various audiences&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;DecipherIt addresses these challenges by leveraging…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mtwn105/decipher-research-agent" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Video Demo
&lt;/h3&gt;

&lt;p&gt;📺 Watch DecipherIt in action:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/CcfhiE4h9WY"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The video demonstrates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up a new research notebook&lt;/li&gt;
&lt;li&gt;Adding multiple sources (URLs, documents, text)&lt;/li&gt;
&lt;li&gt;AI-powered research and analysis process&lt;/li&gt;
&lt;li&gt;Exploring generated summaries and insights&lt;/li&gt;
&lt;li&gt;Using interactive features like Q&amp;amp;A and mindmaps&lt;/li&gt;
&lt;li&gt;Generating audio overviews&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frorif1inudcgue2pu7n6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frorif1inudcgue2pu7n6.png" alt="DecipherIt-LandingPage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu51mv10ryf7mkgs703lh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu51mv10ryf7mkgs703lh.png" alt="DecipherIt-Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbc60xvomh309yudeqyis.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbc60xvomh309yudeqyis.png" alt="DecipherIt-Create-New-Notebook"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnsdr4jb243i3asb4tiz0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnsdr4jb243i3asb4tiz0.png" alt="DecipherIt-Create-New-Notebook-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxmyqtmyaijdmnhrdyqi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxmyqtmyaijdmnhrdyqi.png" alt="DecipherIt-Notebook"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13zvdoh5v79ea8ywi2zn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13zvdoh5v79ea8ywi2zn.png" alt="DecipherIt-Notebook-Summary"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2ykro5wauyzf92c3v1j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2ykro5wauyzf92c3v1j.png" alt="DecipherIt-Notebook-Audio"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1athxv41vkommi396cv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1athxv41vkommi396cv.png" alt="DecipherIt-Notebook-Chat"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wzx169ezx8896ywmhiw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wzx169ezx8896ywmhiw.png" alt="DecipherIt-Notebook-FAQ"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi71kzjril590mpro8me0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi71kzjril590mpro8me0.png" alt="DecipherIt-Notebook-Mindmap"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Input Your Research Sources&lt;/strong&gt;: Enter any topic, upload documents, add custom URLs, or input manual text&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Planning&lt;/strong&gt;: The system creates a strategic research plan using specialized AI agents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web Discovery&lt;/strong&gt;: Bright Data's search engine finds relevant sources globally&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intelligent Scraping&lt;/strong&gt;: Bright Data extracts content and converts it to clean markdown format&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Analysis&lt;/strong&gt;: Multiple AI agents analyze, synthesize, and create comprehensive summaries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Format Output&lt;/strong&gt;: Get research summaries, FAQs, visual mindmaps, and podcast-style audio overviews&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js 15&lt;/strong&gt; with App Router&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React 19&lt;/strong&gt; with concurrent features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript 5&lt;/strong&gt; for type safety&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS 4&lt;/strong&gt; for styling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shadcn/ui&lt;/strong&gt; component library&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Auth&lt;/strong&gt; for authentication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;react-mindmap-visualiser&lt;/strong&gt; for interactive mindmap visualization&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Backend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python 3.12&lt;/strong&gt; with FastAPI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CrewAI&lt;/strong&gt; for multi-agent orchestration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bright Data MCP Server&lt;/strong&gt; for web access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Qdrant&lt;/strong&gt; vector database for semantic search&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQLAlchemy&lt;/strong&gt; with PostgreSQL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LemonFox TTS&lt;/strong&gt; for audio generation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI &amp;amp; ML Services
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Google Gemini&lt;/strong&gt; via OpenRouter for LLM capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI Embeddings&lt;/strong&gt; for semantic search&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MarkItDown&lt;/strong&gt; for document processing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CrewAI Crews Overview
&lt;/h3&gt;

&lt;p&gt;DecipherIt employs a sophisticated multi-crew architecture powered by &lt;strong&gt;CrewAI&lt;/strong&gt;:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Planning Crew&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent&lt;/strong&gt;: Web Scraping Strategy Expert&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task&lt;/strong&gt;: Generate 3 targeted search queries for comprehensive topic coverage&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Link Discovery Crew&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent&lt;/strong&gt;: Link Discovery Specialist&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task&lt;/strong&gt;: Find authoritative sources using Bright Data search engine&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Web Scraping Crew&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent&lt;/strong&gt;: Expert Web Scraping Engineer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task&lt;/strong&gt;: Extract clean markdown content from URLs using Bright Data scraper&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Research Analysis Crew&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent&lt;/strong&gt;: Senior Research Analyst&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task&lt;/strong&gt;: Synthesize multi-source data into comprehensive research insights&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Content Creation Crew&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agents&lt;/strong&gt;: Research Analyst + Content Writer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tasks&lt;/strong&gt;: Create engaging blog posts + Generate 10 detailed FAQs&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Audio Overview Crew&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agents&lt;/strong&gt;: Research Analyst + Conversation Planner + Script Writer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tasks&lt;/strong&gt;: Analyze content + Plan conversation + Generate 4-5 minute podcast transcript&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Mindmap Generation Crew&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agents&lt;/strong&gt;: Content Analyzer + Mindmap Creator&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tasks&lt;/strong&gt;: Identify hierarchical themes + Build interactive visualizations (up to 5 levels)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Chat Response Crew&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent&lt;/strong&gt;: Decipher (Analytical Assistant)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task&lt;/strong&gt;: Answer questions using vector search and chat context with source citations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2tf92be6yvkqj1semxd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2tf92be6yvkqj1semxd.png" alt="Decipher-It Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Bright Data's Infrastructure
&lt;/h2&gt;

&lt;p&gt;Bright Data's &lt;strong&gt;&lt;a href="https://github.com/brightdata-com/brightdata-mcp" rel="noopener noreferrer"&gt;MCP (Model Context Protocol) Server&lt;/a&gt;&lt;/strong&gt; is the backbone of DecipherIt's web access capabilities. Here's how I integrated it:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Official MCP Server Integration&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StdioServerParameters&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;crewai_tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MCPServerAdapter&lt;/span&gt;

&lt;span class="n"&gt;server_params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StdioServerParameters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pnpm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dlx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@brightdata/mcp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;API_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BRIGHT_DATA_API_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BROWSER_AUTH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BRIGHT_DATA_BROWSER_AUTH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;strong&gt;Two Core Tools Implementation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Search Engine Tool&lt;/strong&gt; - For discovering relevant sources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;web_scraping_link_collector_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_engine&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Scrape as Markdown Tool&lt;/strong&gt; - For extracting clean content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;web_scraping_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;scrape_as_markdown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. &lt;strong&gt;Multi-Agent Workflow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I created specialized CrewAI agents that leverage Bright Data's tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Link Collector Agent&lt;/strong&gt;: Uses &lt;code&gt;search_engine&lt;/code&gt; to find relevant sources based on research topics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web Scraper Agent&lt;/strong&gt;: Uses &lt;code&gt;scrape_as_markdown&lt;/code&gt; to extract clean, structured content from discovered URLs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Parallel Processing for Scale&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Execute multiple scraping tasks in parallel
&lt;/span&gt;&lt;span class="n"&gt;web_scraping_tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;links&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;web_scraping_tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;web_scraping_crew&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;kickoff_async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;current_time&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;current_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;web_scraping_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;web_scraping_tasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. &lt;strong&gt;Data Processing &amp;amp; AI Integration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here's how we process the scraped data and integrate it with our AI agents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Process scraped content for AI analysis
&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;integrate_scraped_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;web_scraping_results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;links&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;scraped_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="c1"&gt;# Extract clean content from Bright Data results
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;links&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;web_scraping_results&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;scraped_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Clean markdown format
&lt;/span&gt;            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="c1"&gt;# Create vector embeddings for semantic search
&lt;/span&gt;    &lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;create_embeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scraped_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Store in Qdrant vector database
&lt;/span&gt;    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;store_in_vector_db&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scraped_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Trigger AI analysis crew
&lt;/span&gt;    &lt;span class="n"&gt;research_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;research_content_crew&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;kickoff_async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;scraped_data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scraped_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;current_time&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d %H:%M:%S&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;research_result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Frontend integration with React and TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Research hook for managing AI-powered research&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useResearch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;research&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setResearch&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Research&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;startResearch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ResearchSource&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/research&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;sources&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nf"&gt;setResearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Research failed:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;research&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;startResearch&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. &lt;strong&gt;Seamless Integration with AI Pipeline&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The scraped data from Bright Data flows seamlessly into DecipherIt's multi-layered AI processing system:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Immediate Processing:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vector embeddings&lt;/strong&gt; created using OpenAI embeddings and stored in Qdrant for semantic search capabilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contextual analysis&lt;/strong&gt; by Research Analyst agents to synthesize information from multiple sources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic FAQ generation&lt;/strong&gt; by analyzing content patterns and extracting key insights&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;On-Demand Generation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Audio script creation&lt;/strong&gt; when users request podcast-style overviews, processed by specialized TTS agents&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mindmap structure analysis&lt;/strong&gt; for hierarchical visualization when users want visual representations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive Q&amp;amp;A responses&lt;/strong&gt; powered by vector similarity search through processed content&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Performance Improvements
&lt;/h2&gt;

&lt;p&gt;Real-time web data access through Bright Data's infrastructure dramatically enhanced DecipherIt's AI system performance compared to traditional static data approaches:&lt;/p&gt;

&lt;h3&gt;
  
  
  🚀 &lt;strong&gt;Key Improvements&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Real-Time Information Access&lt;/strong&gt;: Unlike AI systems limited by training data cutoffs, DecipherIt's agents access current information including breaking news, latest research papers, and up-to-date statistics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Global Content Discovery&lt;/strong&gt;: Bright Data's search engine enables AI agents to discover diverse perspectives from global sources, access region-specific content, and find specialized publications that static systems cannot reach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clean Data Processing&lt;/strong&gt;: The Bright Data's tool provides structured, clean content that AI agents process more effectively, improving analysis accuracy and reducing noise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Enhancements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Interactive Mindmap&lt;/strong&gt;: Enhanced mindmap features with expandable nodes, custom styling, and export options&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email Notifications&lt;/strong&gt;: Automated email alerts for research completion and important updates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile App&lt;/strong&gt;: Native mobile experience for research on-the-go&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More Robust Retry Mechanism&lt;/strong&gt;: Improved background task handling with intelligent retry logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live Status Updates&lt;/strong&gt;: Real-time agent activity monitoring and progress tracking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More Complex Scraping&lt;/strong&gt;: Advanced web scraping capabilities for dynamic content and complex sites&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Social Sign-ins&lt;/strong&gt;: Integration with Google, GitHub, and other social authentication providers&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;DecipherIt demonstrates the power of combining Bright Data's robust web access infrastructure with advanced AI agents. By leveraging the &lt;strong&gt;Bright Data MCP Server&lt;/strong&gt;, we've created a research assistant that can access, analyze, and synthesize information from across the global web without the typical limitations of traditional scraping methods.&lt;/p&gt;

&lt;p&gt;The platform showcases how real-time web data access can dramatically improve AI system performance, making research faster, more comprehensive, and more reliable than ever before.&lt;/p&gt;

&lt;p&gt;Special thanks to &lt;a href="https://dev.to"&gt;DEV.to&lt;/a&gt; and &lt;a href="https://brightdata.com" rel="noopener noreferrer"&gt;Bright Data&lt;/a&gt; for organizing this amazing hackathon that made DecipherIt possible! The opportunity to build with Bright Data's powerful infrastructure has been invaluable in bringing this project to life.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>brightdatachallenge</category>
      <category>ai</category>
      <category>webdata</category>
    </item>
    <item>
      <title>Vibe Coded AI Stock Analyst with Amazon Q in 1 Hour!</title>
      <dc:creator>Amit Wani</dc:creator>
      <pubDate>Mon, 12 May 2025 06:13:09 +0000</pubDate>
      <link>https://dev.to/mtwn105/vibe-coded-ai-stock-analyst-with-amazon-q-in-1-hour-20hf</link>
      <guid>https://dev.to/mtwn105/vibe-coded-ai-stock-analyst-with-amazon-q-in-1-hour-20hf</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/aws-amazon-q-v2025-04-30"&gt;Amazon Q Developer "Quack The Code" Challenge&lt;/a&gt;: Crushing the Command Line &amp;amp; Exploring Possibilities&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built 🛠️📈
&lt;/h2&gt;

&lt;p&gt;I have built &lt;strong&gt;Stock Pulse&lt;/strong&gt;. Stock Pulse is a Python tool that analyzes stocks using financial metrics, news trends, and AI-powered sentiment analysis. It provides investment recommendations (BUY, SELL, HOLD) with detailed reasoning based on comprehensive analysis.&lt;/p&gt;

&lt;p&gt;I have used &lt;strong&gt;Amazon Q Developer CLI&lt;/strong&gt; to &lt;strong&gt;Vibe Code&lt;/strong&gt; this in under &lt;strong&gt;1 hour&lt;/strong&gt; without writing a single line of code. I have recorded my full vibe-coding session. It can be found in the Demo section below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features ✨
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔍 Analyze multiple stocks at once&lt;/li&gt;
&lt;li&gt;💹 Fetch financial metrics and news data using yfinance&lt;/li&gt;
&lt;li&gt;🤖 Utilize OpenAI's GPT-4o-mini model for intelligent analysis&lt;/li&gt;
&lt;li&gt;📈 Generate investment signals with detailed reasoning&lt;/li&gt;
&lt;li&gt;⚠️ Identify key factors and potential risks&lt;/li&gt;
&lt;li&gt;💻 Command-line interface and Streamlit web UI&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Screenshots 🖼️
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fougxkrn6y2n857o0pbbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fougxkrn6y2n857o0pbbg.png" alt="Stock Pulse CLI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fumpht88n22dgauo0a8qb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fumpht88n22dgauo0a8qb.png" alt="Stock Pulse CLI - Analysis Output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fme433wq7sy3n675z31wn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fme433wq7sy3n675z31wn.png" alt="Stock Pulse CLI - Stock News"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefo2kmlbu4obupkktbsw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefo2kmlbu4obupkktbsw.png" alt="Stock Pulse CLI - Metrics"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qjr2xzky7kzg0y2a72x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qjr2xzky7kzg0y2a72x.png" alt="Stock Pulse UI - Analysis Output 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjtxfi4kyto2mcjurg1kc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjtxfi4kyto2mcjurg1kc.png" alt="Stock Pulse UI - Analysis Output 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bmtpsacz655a2j9dvg6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bmtpsacz655a2j9dvg6.png" alt="Stock Pulse UI - Stock News"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo 🎬
&lt;/h2&gt;

&lt;p&gt;Streamlit Link: &lt;a href="https://stock-pulse-amit-wani.streamlit.app" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
Vibe-Coding Session Demo:&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/FP5kS3BJrLE"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Repository 🗃️
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mtwn105" rel="noopener noreferrer"&gt;
        mtwn105
      &lt;/a&gt; / &lt;a href="https://github.com/mtwn105/stock-pulse" rel="noopener noreferrer"&gt;
        stock-pulse
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Feel the pulse of the market with AI-powered stock insights. Vibe Coded with Amazon Q Developer CLI in 1 hour!
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Stock Pulse&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Feel the pulse of the market with AI-powered stock insights.&lt;/p&gt;
&lt;p&gt;Vibe Coded with Amazon Q Developer CLI in 1 hour!&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Stock Pulse is a Python tool that analyzes stocks using financial metrics, news trends, and AI-powered sentiment analysis. It provides investment recommendations (BUY, SELL, HOLD) with detailed reasoning based on comprehensive analysis.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Analyze multiple stocks at once&lt;/li&gt;
&lt;li&gt;Fetch financial metrics and news data using yfinance&lt;/li&gt;
&lt;li&gt;Utilize OpenAI's GPT-4o-mini model for intelligent analysis&lt;/li&gt;
&lt;li&gt;Generate investment signals with detailed reasoning&lt;/li&gt;
&lt;li&gt;Identify key factors and potential risks&lt;/li&gt;
&lt;li&gt;Command-line interface and Streamlit web UI&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Clone the repository:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;git clone https://github.com/yourusername/stock-pulse.git
cd stock-pulse
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install dependencies using Poetry:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;poetry install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a &lt;code&gt;.env&lt;/code&gt; file with your OpenAI API key:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;cp .env.example .env
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then edit the &lt;code&gt;.env&lt;/code&gt; file to add your OpenAI API key.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Command Line Interface&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Analyze stocks using the command line:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Analyze a single stock&lt;/span&gt;
poetry run python&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mtwn105/stock-pulse" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Used Amazon Q Developer 🤖⚡
&lt;/h2&gt;

&lt;p&gt;I have used &lt;strong&gt;Amazon Q Developer CLI&lt;/strong&gt; to &lt;strong&gt;Vibe Code&lt;/strong&gt; this project in under &lt;strong&gt;1 hour&lt;/strong&gt; without writing a single line of code manually.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initial Prompt 📝
&lt;/h3&gt;

&lt;p&gt;I kickstarted the development by giving Amazon Q a single, well-crafted prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;i want to create a stock analysis script in python using langchain and langgraph with using openai llm with gpt-4o-mini model. 

use poetry for deps management. poetry is already installed on the system. 

use yfinance tools from langchain for news and price data. use last 1 year price return. 
also use other financial metrics from yfinance like roce, roe, etc. and llm will analyze and return recommendation with signal - BUY,SELL,HOLD and reasoning for it. 

accept list of tickers as argument to the script. 

use poetry to setup project and add deps. dont create pyproject.toml by yourself. 

use python best practices and folder structure for a cli.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Amazon Q responded by generating an organized, ready-to-run CLI project using &lt;strong&gt;Poetry&lt;/strong&gt;, fetching real-time stock data, and integrating GPT-4o-mini for analysis and recommendations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Iterative Development with Q 🔁💡
&lt;/h3&gt;

&lt;p&gt;I continued to use Amazon Q Developer CLI throughout the process for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Debugging and resolving errors by simply pasting the error logs into Q.&lt;/li&gt;
&lt;li&gt;Requesting code refactors and feature enhancements (e.g., adding streamlit UI or news items in output).&lt;/li&gt;
&lt;li&gt;Running Git commands and pushing my code without switching terminals.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Zero Manual Edits ✋❌
&lt;/h3&gt;

&lt;p&gt;From project initialization to the final commit, I &lt;strong&gt;did not write or modify any code manually&lt;/strong&gt;. Every change—big or small—was executed through &lt;strong&gt;Amazon Q Developer CLI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To show full transparency and the incredible capability of Amazon Q, I’ve recorded my entire coding session, which you can find in the demo video above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Amazon Q Was a Game-Changer 💥🎯
&lt;/h3&gt;

&lt;p&gt;Amazon Q isn’t just another coding assistant—it’s an AI developer. It allowed me to stay in flow, innovate rapidly, and push creative boundaries, eliminating friction from the development lifecycle. &lt;/p&gt;

&lt;p&gt;From initializing the project with Poetry to handling dependencies, coding logic, bug fixing, git commands, and even feature iterations—Amazon Q handled everything like a true coding copilot. I never had to touch the code manually.&lt;/p&gt;

&lt;p&gt;I’ve also recorded my entire coding session (watch the demo video above) to showcase how seamlessly Q guided me through the entire development lifecycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion ✅🎉
&lt;/h2&gt;

&lt;p&gt;Participating in the &lt;strong&gt;Amazon Q Developer "Quack The Code" Challenge&lt;/strong&gt; was a fun and productive experience. I built an intelligent UI &amp;amp; CLI-based stock analysis tool using LangChain, LangGraph, and OpenAI—all within an hour—thanks to the power of &lt;strong&gt;Amazon Q Developer CLI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This project proved that with the right tools and a powerful AI assistant like Amazon Q Developer, building complex and intelligent applications becomes fast, efficient, and even enjoyable.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>awschallenge</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>AudioIntel - Transform Audio into Actionable Intelligence</title>
      <dc:creator>Amit Wani</dc:creator>
      <pubDate>Mon, 25 Nov 2024 04:29:09 +0000</pubDate>
      <link>https://dev.to/mtwn105/audiointel-transform-audio-into-actionable-intelligence-nd8</link>
      <guid>https://dev.to/mtwn105/audiointel-transform-audio-into-actionable-intelligence-nd8</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/assemblyai"&gt;AssemblyAI Challenge&lt;/a&gt;: Sophisticated Speech-to-Text &amp;amp; No More Monkey Business.&lt;/em&gt; 🏆&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built 🛠️
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;AudioIntel&lt;/strong&gt; - a powerful platform that transforms audio content into actionable intelligence using AssemblyAI's cutting-edge APIs. The platform helps users extract valuable insights from audio content through advanced transcription, analysis, and AI-powered features. ✨&lt;/p&gt;

&lt;h3&gt;
  
  
  🔗 Live Demo: &lt;a href="https://audiointel.amitwani.dev" rel="noopener noreferrer"&gt;https://audiointel.amitwani.dev&lt;/a&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  🎥 Demo Video
&lt;/h3&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/P4ghVEwGDB4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Journey 🗺️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Inspiration 💡
&lt;/h3&gt;

&lt;p&gt;The idea for AudioIntel came from my own struggles with processing audio content efficiently. As someone who consumes a lot of podcasts, interviews, and video content, I often found myself wanting to quickly extract key insights without listening to hours of content. I realized this was a common pain point for many content creators, researchers, and professionals. 🎧&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning &amp;amp; Iterations 📚
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔄 Integration with AssemblyAI's powerful APIs for transcription and analysis&lt;/li&gt;
&lt;li&gt;🗣️ Leveraging AssemblyAI's speaker diarization and sentiment analysis features&lt;/li&gt;
&lt;li&gt;🧠 Leveraging AssemblyAI with LeMUR for summarization, question answering, and intelligent content analysis&lt;/li&gt;
&lt;li&gt;⚠️ Error handling in audio processing and real-time status updates&lt;/li&gt;
&lt;li&gt;🔄 State management for handling complex UI interactions&lt;/li&gt;
&lt;li&gt;⚡ Performance optimization for processing large audio files&lt;/li&gt;
&lt;li&gt;💾 Database integration using Neon PostgreSQL with Drizzle ORM&lt;/li&gt;
&lt;li&gt;🔒 User authentication implementation with Better Auth&lt;/li&gt;
&lt;li&gt;🌐 Language translation features using Google Translate API&lt;/li&gt;
&lt;li&gt;📤 File upload handling through UploadThing integration&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Features Showcase ✨
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Multiple Input Sources 📥
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;📁 File Upload: Support for various audio formats through UploadThing integration&lt;/li&gt;
&lt;li&gt;🎙️ Browser Recording: Direct audio capture using the Web Audio API&lt;/li&gt;
&lt;li&gt;📺 YouTube Integration: YouTube video to audio conversion and analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-time Analysis 📊
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;👥 Speaker diarization with timeline visualization&lt;/li&gt;
&lt;li&gt;😊 Sentiment analysis with color-coded segments&lt;/li&gt;
&lt;li&gt;🔍 Interactive transcript search and navigation&lt;/li&gt;
&lt;li&gt;💬 Interactive chat with the transcript&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Smart Content Generation 📝
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🤖 AI-powered blog post creation&lt;/li&gt;
&lt;li&gt;💭 Context-aware chat interface&lt;/li&gt;
&lt;li&gt;📌 Key sections identification with timestamps&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Language Translation 🌍
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔄 Translate transcript to multiple languages&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Screenshots 📸
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Multiple Sources - Audio file, Record file &amp;amp; YouTube 📱
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj43w6y8wwarb6clixx0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj43w6y8wwarb6clixx0w.png" alt="audioFile" width="800" height="319"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2a3swa9qnaca1ifu0fr2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2a3swa9qnaca1ifu0fr2.png" alt="recordAudio" width="800" height="283"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa6db5cszift2m85x4zwq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa6db5cszift2m85x4zwq.png" alt="youtube" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Overview &amp;amp; Analysis 📊
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvjhd3srphwat77n0y71.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzvjhd3srphwat77n0y71.png" alt="overview" width="800" height="375"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yzx3udswhlht4upuqbl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yzx3udswhlht4upuqbl.png" alt="summary" width="800" height="289"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Interactive Features ⚡
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fplbecd84yypenaxuhq5a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fplbecd84yypenaxuhq5a.png" alt="transcript" width="800" height="390"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndolv1e12r8uk0f063ve.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndolv1e12r8uk0f063ve.png" alt="chat" width="800" height="377"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24zmegps45yqssa210pj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24zmegps45yqssa210pj.png" alt="blog" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Tech Stack 💻
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔥 &lt;strong&gt;Framework&lt;/strong&gt;: Next.js 14 with App Router&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;Language&lt;/strong&gt;: TypeScript&lt;/li&gt;
&lt;li&gt;💾 &lt;strong&gt;Database&lt;/strong&gt;: Neon PostgreSQL with Drizzle ORM&lt;/li&gt;
&lt;li&gt;🎨 &lt;strong&gt;UI&lt;/strong&gt;: Tailwind CSS + shadcn/ui&lt;/li&gt;
&lt;li&gt;🎙️ &lt;strong&gt;Audio Processing&lt;/strong&gt;: AssemblyAI&lt;/li&gt;
&lt;li&gt;📤 &lt;strong&gt;File Upload&lt;/strong&gt;: UploadThing&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;Analytics&lt;/strong&gt;: OpenPanel&lt;/li&gt;
&lt;li&gt;🔒 &lt;strong&gt;Authentication&lt;/strong&gt;: Better Auth&lt;/li&gt;
&lt;li&gt;🌐 &lt;strong&gt;Translation&lt;/strong&gt;: Google Translate&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Deployment&lt;/strong&gt;: Vercel&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Techincal Archicture 🏗️
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgo76j5khuigft192bykb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgo76j5khuigft192bykb.png" alt="tech-architecture" width="682" height="441"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Technical Implementation ⚙️
&lt;/h2&gt;
&lt;h3&gt;
  
  
  AssemblyAI Integration 🔌
&lt;/h3&gt;

&lt;p&gt;I leveraged several powerful features from AssemblyAI's SDK:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Transcription API&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transcript&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;assemblyai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transcripts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transcribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fileUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;speaker_labels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;summarization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;summary_model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;conversational&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;summary_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bullets&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sentiment_analysis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;LeMUR for Content Generation&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Generate blog post&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;blogPostResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;assemblyai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lemur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;transcript_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Generate a blog post from the transcript in markdown format`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;final_model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;anthropic/claude-3-5-sonnet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Generate actionable insights&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;insights&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;assemblyai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lemur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;transcript_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Provide actionable insights from the transcript`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;final_model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;anthropic/claude-3-5-sonnet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;LeMUR for Interactive Chat&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;qas&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;assemblyai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lemur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;questionAnswer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;transcript_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;transcriptId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;final_model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;anthropic/claude-3-5-sonnet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;questions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;answer_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;short sentence&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Future Enhancements 🚀
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Multi-language support&lt;/li&gt;
&lt;li&gt;Advanced analytics dashboard&lt;/li&gt;
&lt;li&gt;API endpoints&lt;/li&gt;
&lt;li&gt;Custom templates&lt;/li&gt;
&lt;li&gt;Advanced search capabilities&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Source Code 🔗
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mtwn105" rel="noopener noreferrer"&gt;
        mtwn105
      &lt;/a&gt; / &lt;a href="https://github.com/mtwn105/audio-intel" rel="noopener noreferrer"&gt;
        audio-intel
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      AudioIntel - Audio/Video Intelligence, Transcripts, Summary, and much more 
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🎙️ AudioIntel&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Transform audio into actionable intelligence with our powerful AI platform. AudioIntel helps you extract valuable insights from audio content through transcription, analysis, and AI-powered features.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;&lt;a href="https://audiointel.amitwani.dev" rel="nofollow noopener noreferrer"&gt;Live Demo&lt;/a&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;🎵 &lt;strong&gt;Multiple Input Methods&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Upload audio files (MP3, WAV)&lt;/li&gt;
&lt;li&gt;Record directly in browser&lt;/li&gt;
&lt;li&gt;Analyze YouTube videos&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🤖 &lt;strong&gt;AI-Powered Analysis&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Smart summaries and key takeaways&lt;/li&gt;
&lt;li&gt;Sentiment analysis&lt;/li&gt;
&lt;li&gt;Speaker identification&lt;/li&gt;
&lt;li&gt;Actionable insights generation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;📝 &lt;strong&gt;Content Generation&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Automatic blog post creation&lt;/li&gt;
&lt;li&gt;Interactive chat with transcripts&lt;/li&gt;
&lt;li&gt;Key sections identification&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🔍 &lt;strong&gt;Advanced Features&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Timeline view with precise timestamps&lt;/li&gt;
&lt;li&gt;Multi-speaker detection&lt;/li&gt;
&lt;li&gt;Searchable transcripts&lt;/li&gt;
&lt;li&gt;Real-time sentiment tracking&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Getting Started&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Prerequisites&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Node.js 18+&lt;/li&gt;
&lt;li&gt;npm or yarn&lt;/li&gt;
&lt;li&gt;AssemblyAI API key&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Installation&lt;/h3&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Clone the repository&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;git clone https://github.com/yourusername/audio-intel.git
cd audio-intel
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Install dependencies&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or&lt;/span&gt;
yarn install&lt;/pre&gt;

&lt;/div&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Set up environment variables&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;cp .env.example .env&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Required environment variables:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;ASSEMBLYAI_API_KEY=your_api_key
NEXT_PUBLIC_APP_URL=http://localhost:3000
UPLOADTHING_TOKEN=your_uploadthing_token
GOOGLE_GENERATIVE_AI_API_KEY=your_google_generative_ai_api_key
GOOGLE_TRANSLATE_API_KEY=your_google_translate_api_key
BETTER_AUTH_SECRET=your_better_auth_secret
BETTER_AUTH_BASE_URL=http://localhost:3000
DATABASE_URL=your_database_url
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Run the development server&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm run dev
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; or&lt;/span&gt;
yarn dev&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Open…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mtwn105/audio-intel" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Submission 📝
&lt;/h2&gt;

&lt;p&gt;This submission was made for the &lt;a href="https://dev.to/challenges/assemblyai"&gt;AssemblyAI Challenge&lt;/a&gt; for &lt;strong&gt;"Sophisticated Speech-to-Text"&lt;/strong&gt; &amp;amp; &lt;strong&gt;"No More Monkey Business"&lt;/strong&gt; Prompts.&lt;/p&gt;

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

&lt;p&gt;I had a great time participating in the AssemblyAI Challenge and learned a lot from the experience. I'm looking forward to seeing what other developers come up with! 🚀&lt;/p&gt;

&lt;p&gt;Thank you Dev.To &amp;amp; AssemblyAI for organizing this challenge and providing such a great platform for developers to showcase their skills! 🎉&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>assemblyaichallenge</category>
      <category>ai</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>MailTales - Make Emails Fun Again!</title>
      <dc:creator>Amit Wani</dc:creator>
      <pubDate>Mon, 02 Sep 2024 05:56:50 +0000</pubDate>
      <link>https://dev.to/mtwn105/mailtales-make-emails-fun-again-5d9l</link>
      <guid>https://dev.to/mtwn105/mailtales-make-emails-fun-again-5d9l</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/nylas"&gt;Nylas Challenge&lt;/a&gt;: AI Expedition &amp;amp; Galaxy Brain&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built and Why
&lt;/h2&gt;

&lt;p&gt;MailTales is a web app designed to breathe life into your email inbox. With the help of &lt;strong&gt;Nylas&lt;/strong&gt; &amp;amp; AI, MailTales offers unique and creative ways to interact with your emails, transforming them into bite-sized stories, engaging summaries, and even providing insights through sentiment analysis. You can try it &lt;a href="https://mailtales.amitwani.dev" rel="noopener noreferrer"&gt;https://mailtales.amitwani.dev&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;MailTales: You can go to &lt;a href="https://mailtales.amitwani.dev" rel="noopener noreferrer"&gt;https://mailtales.amitwani.dev&lt;/a&gt;&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/zk88KqHMCR0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Chat Over Your Inbox&lt;/strong&gt;: With MailTales, you can chat with your email inbox!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pl9tbbdi70lidxwthsd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pl9tbbdi70lidxwthsd.png" alt="chat-over-emails" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI-Powered Email Summaries&lt;/strong&gt;: MailTales provides concise, AI-generated summaries of your emails&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fau67ahoawtfe8ig4kpdh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fau67ahoawtfe8ig4kpdh.png" alt="ai-summary" width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Listen to AI-Generated Stories&lt;/strong&gt;: MailTales can convert the content of your emails into engaging audio stories.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsm4ufaabt6j2ctrnt8pt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsm4ufaabt6j2ctrnt8pt.png" alt="ai-story" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sentiment Analysis and Categorization&lt;/strong&gt;: MailTales' sentiment analysis feature helps you understand the tone of your messages. The app also categorizes emails based on their content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjrfywjchv34ju53yrbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyjrfywjchv34ju53yrbg.png" alt="sentiment" width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mtwn105" rel="noopener noreferrer"&gt;
        mtwn105
      &lt;/a&gt; / &lt;a href="https://github.com/mtwn105/MailTales" rel="noopener noreferrer"&gt;
        MailTales
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Turn your Emails into Captivating Stories
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;MailTales&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Make emails fun again!&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;MailTales is a web app designed to breathe life into your email inbox. With the help of &lt;strong&gt;Nylas&lt;/strong&gt; &amp;amp; AI, MailTales offers unique and creative ways to interact with your emails, transforming them into bite-sized stories, engaging summaries, and even providing insights through sentiment analysis. You can try it &lt;a href="https://mailtales.amitwani.dev" rel="nofollow noopener noreferrer"&gt;https://mailtales.amitwani.dev&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Demo&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Youtube - &lt;a href="https://youtu.be/zk88KqHMCR0" rel="nofollow noopener noreferrer"&gt;https://youtu.be/zk88KqHMCR0&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Chat Over Your Inbox&lt;/strong&gt;: With MailTales, you can chat with your email inbox!&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/3807b4b6ed87b071780171125923d0c261c967ec3d37f04211b9c5ba8813acf9/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f30706c39746262646937306c69647877746873642e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/3807b4b6ed87b071780171125923d0c261c967ec3d37f04211b9c5ba8813acf9/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f30706c39746262646937306c69647877746873642e706e67" alt="chat-over-emails"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI-Powered Email Summaries&lt;/strong&gt;: MailTales provides concise, AI-generated summaries of your emails&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/b1489800ec372955720ca0aca679fe9cd4758a22caa55743492275423610293a/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f6175363761686f6177746665386967346b7064682e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/b1489800ec372955720ca0aca679fe9cd4758a22caa55743492275423610293a/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f6175363761686f6177746665386967346b7064682e706e67" alt="ai-summary"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Listen to AI-Generated Stories&lt;/strong&gt;: MailTales can convert the content of your emails into engaging audio stories.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/73f72c756375db60178bd483781653866e67d3642f54ea8dba0c99a083fb1209/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f736d34756661616274366a326374726e743870742e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/73f72c756375db60178bd483781653866e67d3642f54ea8dba0c99a083fb1209/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f736d34756661616274366a326374726e743870742e706e67" alt="ai-story"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sentiment Analysis and Categorization&lt;/strong&gt;: MailTales' sentiment analysis feature helps you understand the tone of your messages. The app also categorizes emails based on their content.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/22219b3f0858725d8aa4175e96843d20ed72aa9bf6bc808741828f7e272ff270/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f796a726679776a63687633346a753533797262672e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/22219b3f0858725d8aa4175e96843d20ed72aa9bf6bc808741828f7e272ff270/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f796a726679776a63687633346a753533797262672e706e67" alt="sentiment"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Tech Stack&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Full Stack:&lt;/strong&gt; NextJS
&lt;strong&gt;Backend:&lt;/strong&gt; NodeJS
&lt;strong&gt;Deployment:&lt;/strong&gt; Vercel, Fly.io
&lt;strong&gt;Database:&lt;/strong&gt; PostgreSQL
&lt;strong&gt;Queues:&lt;/strong&gt; Upstash Kafka
&lt;strong&gt;Email:&lt;/strong&gt; Nylas
&lt;strong&gt;AI:&lt;/strong&gt; Gemini&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Architecture&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/1cb799a9cdface4f517257c19fb61c9bdf45ffba6c2b5ca72ea3e68b9b46729b/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f707335787369666c756d6969376d376172766a712e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/1cb799a9cdface4f517257c19fb61c9bdf45ffba6c2b5ca72ea3e68b9b46729b/68747470733a2f2f6465762d746f2d75706c6f6164732e73332e616d617a6f6e6177732e636f6d2f75706c6f6164732f61727469636c65732f707335787369666c756d6969376d376172766a712e706e67" alt=" mail-tales-architecture"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nylas:&lt;/strong&gt;…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mtwn105/MailTales" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Full Stack:&lt;/strong&gt; NextJS&lt;br&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; NodeJS&lt;br&gt;
&lt;strong&gt;Deployment:&lt;/strong&gt; Vercel, Fly.io&lt;br&gt;
&lt;strong&gt;Database:&lt;/strong&gt; PostgreSQL&lt;br&gt;
&lt;strong&gt;Queues:&lt;/strong&gt; Upstash Kafka&lt;br&gt;
&lt;strong&gt;Email:&lt;/strong&gt; Nylas&lt;br&gt;
&lt;strong&gt;AI:&lt;/strong&gt; Gemini&lt;/p&gt;
&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fps5xsiflumii7m7arvjq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fps5xsiflumii7m7arvjq.png" alt="&amp;lt;br&amp;gt;
![mail-tales-architecture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/djz8c5hbsmbhpu7l6qiu.png)" width="690" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nylas:&lt;/strong&gt; Nylas is used for authentication of user and fetching their emails from inbox&lt;br&gt;
&lt;strong&gt;Gemini:&lt;/strong&gt; Gemini is used for generating AI responses as well as generating embeddings. Model used for generating responses is &lt;code&gt;gemini-1.5-flash&lt;/code&gt; and for embeddings it is &lt;code&gt;text-embedding-004&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Postgres:&lt;/strong&gt; Postgres is used to store user and emails data. &lt;code&gt;@vercel/postgres&lt;/code&gt; is used for this.&lt;br&gt;
&lt;strong&gt;Upstash Kafka:&lt;/strong&gt; Upstash Kafka is used for the job of generating email embeddings. Generating email embeddings is done by a NodeJS Backend by consuming messages from Upstash Kafka topic.&lt;/p&gt;
&lt;h2&gt;
  
  
  Your Journey
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Nylas
&lt;/h3&gt;

&lt;p&gt;I have used &lt;strong&gt;Nylas&lt;/strong&gt; to get email inbox and its contents. I have used the &lt;strong&gt;Nylas NodeJS SDK&lt;/strong&gt; for this. Logging in the user was very easy using the SDK. The &lt;code&gt;grantId&lt;/code&gt; received is then saved to the DB for further requests. Overall it was really interesting experience in building on top of &lt;strong&gt;Nylas&lt;/strong&gt; features. There are many more features which are still left to explore!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get Emails&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;queryParams&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ListMessagesQueryParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;in&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;INBOX&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pageToken&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;pageToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;queryParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pageToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pageToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nylas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;grantId&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;queryParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Search Emails&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;queryParams&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ListMessagesQueryParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;in&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;INBOX&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;searchQueryNative&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;query&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pageToken&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;pageToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;queryParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pageToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pageToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;nylas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;grantId&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;queryParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Upstash Kafka
&lt;/h3&gt;

&lt;p&gt;Used Upstash Kafka's REST API to produce message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UPSTASH_KAFKA_REST_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/produce`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Basic &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UPSTASH_KAFKA_REST_AUTH&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;generate-email-embeddings&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Used &lt;code&gt;kafkajs&lt;/code&gt; in the backend to consume the messages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;kafka&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Kafka&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;brokers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UPSTASH_KAFKA_BROKERS&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sasl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;mechanism&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scram-sha-256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UPSTASH_KAFKA_USERNAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UPSTASH_KAFKA_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;logLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;logLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;consumer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;groupId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;consumer_group_1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;generate-email-embeddings&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fromBeginning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;eachMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;partition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="nx"&gt;partition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Generating email embeddings for user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;generateEmailEmbeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Gemini &amp;amp; Vercel AI SDK
&lt;/h3&gt;

&lt;p&gt;Used Vercel AI SDK to interact with Gemini models.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get Streaming Response&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getGoogleResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;streamText&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;google&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gemini-1.5-flash&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Generate Embeddings&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateEmbeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;emailStrings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;embeddings&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;embedMany&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;google&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text-embedding-004&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;emailStrings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, this was the first time of using NextJS and building a proper RAG agent from the scratch using Vercel AI SDK, so overall a great learning experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Scope
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;More deeper insights into mailbox&lt;/li&gt;
&lt;li&gt;Integration of AI in alot of parts of the app&lt;/li&gt;
&lt;li&gt;Crafting beautiful professional replies.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;It was a great experience in building this app using &lt;strong&gt;Nylas&lt;/strong&gt; &amp;amp; &lt;strong&gt;Gemini&lt;/strong&gt; over NextJS. I have learnt alot in the last week while building this project. Thanks to &lt;strong&gt;Dev.To&lt;/strong&gt; as well for providing such platforms for building the projects.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>nylaschallenge</category>
      <category>api</category>
      <category>ai</category>
    </item>
    <item>
      <title>Redis Performance Testing</title>
      <dc:creator>Amit Wani</dc:creator>
      <pubDate>Sat, 23 Dec 2023 14:18:54 +0000</pubDate>
      <link>https://dev.to/mtwn105/redis-performance-testing-1e57</link>
      <guid>https://dev.to/mtwn105/redis-performance-testing-1e57</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Redis Benchmark&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Redis Benchmark is a command-line tool that comes bundled with Redis. It is designed to simulate various scenarios and workloads, helping you evaluate the performance of your Redis server. Whether you are a developer fine-tuning your application or an administrator optimizing system resources, Redis Benchmark provides valuable insights into your Redis instance's capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation:
&lt;/h3&gt;

&lt;p&gt;If you have Redis installed on your system, Redis Benchmark is likely available. To use it, open a terminal and simply type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;redis-benchmark
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will execute the benchmark with default settings, providing you with a quick overview of your Redis server's performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Benchmarking Workloads&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Simple Operations:
&lt;/h4&gt;

&lt;p&gt;Start by testing the basic operations, such as GET and SET commands. These operations are fundamental to Redis, and their performance directly impacts the overall responsiveness of your application. Use the following command to run a simple benchmark:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;redis-benchmark &lt;span class="nt"&gt;-t&lt;/span&gt; get,set
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will test the throughput and latency of GET and SET commands, giving you an idea of how quickly Redis can handle these operations.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Pipelining:
&lt;/h4&gt;

&lt;p&gt;Pipelining allows you to send multiple commands to Redis in a single request, reducing the number of round trips between the client and server. Test the impact of pipelining on performance with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;redis-benchmark &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;,get &lt;span class="nt"&gt;-P&lt;/span&gt; 16
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adjust the value &lt;code&gt;-P&lt;/code&gt; to set the number of commands to pipeline.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Parallel Connections:
&lt;/h4&gt;

&lt;p&gt;Simulate real-world scenarios by testing the performance of parallel connections. This helps identify how well your Redis instance scales under increased load:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;redis-benchmark &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;,get &lt;span class="nt"&gt;-c&lt;/span&gt; 50 &lt;span class="nt"&gt;-n&lt;/span&gt; 100000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, 50 clients will perform 100,000 SET and GET operations concurrently.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Analyzing Results&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Once the benchmark is completed, Redis Benchmark provides detailed output, including throughput, latency, and other performance metrics. Analyze this data to identify potential bottlenecks or areas for improvement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentation
&lt;/h3&gt;

&lt;p&gt;More documentation can be found at &lt;a href="https://redis.io/docs/management/optimization/benchmarks/" rel="noopener noreferrer"&gt;Redis benchmark | Redis&lt;/a&gt;&lt;/p&gt;

</description>
      <category>redis</category>
      <category>performance</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Shoppable - E-commerce For Everyone</title>
      <dc:creator>Amit Wani</dc:creator>
      <pubDate>Mon, 29 Aug 2022 20:57:00 +0000</pubDate>
      <link>https://dev.to/mtwn105/shoppable-e-commerce-for-everyone-4ab8</link>
      <guid>https://dev.to/mtwn105/shoppable-e-commerce-for-everyone-4ab8</guid>
      <description>&lt;h2&gt;
  
  
  Overview of My Submission
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Shoppable&lt;/strong&gt; is A Platform to create an online store for your business. &lt;strong&gt;&lt;em&gt;Powered by Redis Stack!&lt;/em&gt;&lt;/strong&gt;. You can visit it &lt;strong&gt;&lt;a href="https://shoppable.amitwani.dev" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1e4jg5kt4ei7xpx1fem9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1e4jg5kt4ei7xpx1fem9.png" alt="image" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Submission Category:
&lt;/h2&gt;

&lt;p&gt;My category would be &lt;strong&gt;Microservice Mavens&lt;/strong&gt; as this project has 6 decoupled backend microservices and one frontend&lt;/p&gt;

&lt;h3&gt;
  
  
  Languages/Technologies Used
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;NodeJS&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Angular&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Redis Stack&lt;/strong&gt; (RedisJSON, RedisSearch, Redis Streams)&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/sxY6KHoRkn8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Info
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Process Flow
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Merchant can register on the platform and create a store&lt;/li&gt;
&lt;li&gt;He can add the items to inventory&lt;/li&gt;
&lt;li&gt;A customer can visit that merchant store&lt;/li&gt;
&lt;li&gt;Customer can purchase items listed by merchant&lt;/li&gt;
&lt;li&gt;Merchant will receive the order and will fulfill it&lt;/li&gt;
&lt;li&gt;Customer will receive notifications regarding the order&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Technical Overview
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;There are 6 microservices (merchant, inventory, customer, order, update, file-upload)&lt;/li&gt;
&lt;li&gt;All servers are based on &lt;strong&gt;NodeJS&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The client is based on &lt;strong&gt;Angular&lt;/strong&gt; and &lt;strong&gt;Angular Material&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;An nginx is used to route request to various microservices as a reverse proxy&lt;/li&gt;
&lt;li&gt;Redis Stack is integrated with the help of &lt;strong&gt;&lt;a href="https://github.com/redis/redis-om-node" rel="noopener noreferrer"&gt;Redis OM&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://github.com/redis/node-redis" rel="noopener noreferrer"&gt;Node Redis&lt;/a&gt;&lt;/strong&gt; NodeJS libraries&lt;/li&gt;
&lt;li&gt;Redis Stack is hosted on Redis Cloud itself&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RedisJSON&lt;/strong&gt;, &lt;strong&gt;RedisSearch&lt;/strong&gt; and &lt;strong&gt;Redis Streams&lt;/strong&gt; has been used&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RedisJSON&lt;/strong&gt; is used to store JSON documents for various schema such as Merchant, Customer, Product, Order, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RedisSearch&lt;/strong&gt; is used alongside RedisJSON to search through different repositories&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis Streams&lt;/strong&gt; is used for publishing and listening to order updates and send email using &lt;strong&gt;Mailjet&lt;/strong&gt; to the customer regarding the update&lt;/li&gt;
&lt;li&gt;Apart from this, &lt;strong&gt;Google Cloud Storage&lt;/strong&gt; is also used to store images of the products uploaded by the merchant&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7atrl8a6vveda9a3k2sn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7atrl8a6vveda9a3k2sn.png" alt="shoppable_architecture" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Application Screenshots
&lt;/h3&gt;

&lt;p&gt;Merchant Login&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuij935vwilf4xym8f6uu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuij935vwilf4xym8f6uu.png" alt="Login" width="755" height="595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Merchant Dashboard&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fijwgxci1lhl9v7v9e1i9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fijwgxci1lhl9v7v9e1i9.png" alt="Merchant Dashboard" width="683" height="196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Merchant Inventory&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgjbcr7oxc21oy4omn4qx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgjbcr7oxc21oy4omn4qx.png" alt="Merchant Inventory" width="671" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Merchant Add/Edit Product&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2b9d3qdlqwm01n7ax0a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2b9d3qdlqwm01n7ax0a.png" alt="Merchant Add/Edit Product" width="668" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Merchant Orders&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6qw9dhjaje7szbdqief.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6qw9dhjaje7szbdqief.png" alt="Merchant Orders" width="685" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Store Home&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5cgv45jy2l1ppdlwm81.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi5cgv45jy2l1ppdlwm81.png" alt="Store Home" width="669" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Product Page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fweii8m3xqfyxwj2w9a1i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fweii8m3xqfyxwj2w9a1i.png" alt="Product Page" width="680" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cart&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiksivh2eog79y91fqvgr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiksivh2eog79y91fqvgr.png" alt="Cart" width="677" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Order Details&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fma1kmi75go9u1zro1qsf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fma1kmi75go9u1zro1qsf.png" alt="Order Details" width="663" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Email Notification&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1skzkpl6a6l7ing76kjk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1skzkpl6a6l7ing76kjk.png" alt="Email Notification" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Link to Code
&lt;/h2&gt;

&lt;p&gt;More details are available on the GitHub repo:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mtwn105" rel="noopener noreferrer"&gt;
        mtwn105
      &lt;/a&gt; / &lt;a href="https://github.com/mtwn105/Shopable" rel="noopener noreferrer"&gt;
        Shopable
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A Platform to create an online store for your business. Powered by Redis Stack!
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Shoppable - E-commerce for Everyone&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A Platform to create an online store for your business
Powered by Redis Stack!&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/12975481/187288703-1ff8c94f-75d7-4547-b86d-f01959a9511f.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F12975481%2F187288703-1ff8c94f-75d7-4547-b86d-f01959a9511f.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Powered By&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Redis Stack&lt;/strong&gt; (RedisJSON, RedisSearch, Redis Streams)
&lt;strong&gt;NodeJS&lt;/strong&gt;
&lt;strong&gt;Angular&lt;/strong&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Demo Video&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Checkout video &lt;a href="https://youtu.be/sxY6KHoRkn8" rel="nofollow noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Process flow&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Merchant can register on the platform and create a store&lt;/li&gt;
&lt;li&gt;He can add the items to inventory&lt;/li&gt;
&lt;li&gt;A customer can visit that merchant store&lt;/li&gt;
&lt;li&gt;Customer can purchase items listed by merchant&lt;/li&gt;
&lt;li&gt;Merchant will receive the order and will fulfill it&lt;/li&gt;
&lt;li&gt;Customer will receive notifications regarding the order&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Technical Overview&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;There are 6 microservices (merchant, inventory, customer, order, update, file-upload)&lt;/li&gt;
&lt;li&gt;All servers are based on &lt;strong&gt;NodeJS&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The client is based on &lt;strong&gt;Angular&lt;/strong&gt; and &lt;strong&gt;Angular Material&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;An nginx is used to route request to various microservices as a reverse proxy&lt;/li&gt;
&lt;li&gt;Redis Stack is integrated with the help of &lt;strong&gt;&lt;a href="https://github.com/redis/redis-om-node" rel="noopener noreferrer"&gt;Redis OM&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://github.com/redis/node-redis" rel="noopener noreferrer"&gt;Node Redis&lt;/a&gt;&lt;/strong&gt; NodeJS libraries&lt;/li&gt;
&lt;li&gt;Redis Stack is hosted on Redis Cloud itself&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mtwn105/Shopable" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Check out &lt;a href="https://redis.io/docs/stack/get-started/clients/#high-level-client-libraries" rel="noopener noreferrer"&gt;Redis OM&lt;/a&gt;, client libraries for working with Redis as a multi-model database.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Use &lt;a href="https://redis.info/redisinsight" rel="noopener noreferrer"&gt;RedisInsight&lt;/a&gt; to visualize your data in Redis.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Sign up for a &lt;a href="https://redis.info/try-free-dev-to" rel="noopener noreferrer"&gt;free Redis database&lt;/a&gt;.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>redishackathon</category>
      <category>node</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Create a Chatbot using WhatsApp Cloud API</title>
      <dc:creator>Amit Wani</dc:creator>
      <pubDate>Mon, 27 Jun 2022 05:02:05 +0000</pubDate>
      <link>https://dev.to/mtwn105/create-a-chatbot-using-whatsapp-cloud-api-18d9</link>
      <guid>https://dev.to/mtwn105/create-a-chatbot-using-whatsapp-cloud-api-18d9</guid>
      <description>&lt;p&gt;Hello folks, today in this article, we will be going through how you can create a chatbot and integrate it with &lt;strong&gt;WhatsApp Cloud API&lt;/strong&gt;. We will be also giving this chatbot a brain using an &lt;strong&gt;OpenAI&lt;/strong&gt; model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To create a WhatsApp chatbot you will need a few Prerequisites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Meta Business Account&lt;/li&gt;
&lt;li&gt;A Meta Developer Account&lt;/li&gt;
&lt;li&gt;An OpenAI Account&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can create these easily using your existing Facebook account or create a new one.&lt;/p&gt;

&lt;p&gt;Once you have all of these ready, we can get started by configuring in Meta Developer account to enable WhatsApp integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create Meta App
&lt;/h3&gt;

&lt;p&gt;Logon to &lt;a href="https://developers.facebook.com/apps/" rel="noopener noreferrer"&gt;https://developers.facebook.com/apps/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Create a New App.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4q5okp52n4qfier5e4t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4q5okp52n4qfier5e4t.png" alt="Image description" width="800" height="187"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Choose &lt;strong&gt;Business&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbv78kyiv4rafmvsmtqi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbv78kyiv4rafmvsmtqi.png" alt="Image description" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose your &lt;strong&gt;Business Manager Account&lt;/strong&gt; and enter other details&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrgxog3717gz99w8h5m9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrgxog3717gz99w8h5m9.png" alt="Image description" width="800" height="427"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;Create App&lt;/strong&gt; and your app will be created.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add WhatsApp Integration
&lt;/h3&gt;

&lt;p&gt;Open your app page and you will land on this screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fezvo1x40gafq2bd7bxsb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fezvo1x40gafq2bd7bxsb.png" alt="Image description" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scroll down and find &lt;strong&gt;WhatsApp&lt;/strong&gt;. Click on &lt;strong&gt;Set up&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmafaq9tsh92dxe59par.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmafaq9tsh92dxe59par.png" alt="Image description" width="487" height="423"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  WhatsApp Configuration
&lt;/h3&gt;

&lt;p&gt;You will see this screen. Here you have been assigned &lt;strong&gt;a Temporary Token&lt;/strong&gt; and &lt;strong&gt;a Test WhatsApp Number&lt;/strong&gt;. We will use these to send and receive messages on that Test WhatsApp Number. In future, if you want, you can connect real numbers as well which will be a proper WhatsApp Business account. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsc06lfikhta4zjald6rv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsc06lfikhta4zjald6rv.png" alt="Image description" width="800" height="447"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;You have to configure a few recipient WhatsApp numbers for testing, up to 5 numbers can be added.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Phone Number ID&lt;/strong&gt; shown will be used later to use WhatsApp Cloud API, so keep it handy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication Token
&lt;/h3&gt;

&lt;p&gt;The final piece of configuration is generation of an authentication token which will be used while communicating with Meta APIs. &lt;/p&gt;

&lt;p&gt;Log on to &lt;a href="https://business.facebook.com/" rel="noopener noreferrer"&gt;https://business.facebook.com/&lt;/a&gt; and open your Business Settings.&lt;/p&gt;

&lt;p&gt;Navigate to the &lt;strong&gt;System Users&lt;/strong&gt; section from left-hand menu&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7cvkdj1a34b77skacgv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7cvkdj1a34b77skacgv.png" alt="Image description" width="434" height="339"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;You can add a user or if it already exists, click on &lt;strong&gt;Generate New Token&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0r8zum32vrtgm4lvjwuv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0r8zum32vrtgm4lvjwuv.png" alt="Image description" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the app you created earlier and check &lt;strong&gt;whatsapp_business_management&lt;/strong&gt; and &lt;strong&gt;whatsapp_business_messaging&lt;/strong&gt; permissions and then copy this token.&lt;/p&gt;

&lt;h2&gt;
  
  
  Application
&lt;/h2&gt;

&lt;p&gt;So we will develop our application using &lt;strong&gt;NodeJS and Express&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will install basic dependencies like &lt;code&gt;express&lt;/code&gt; &lt;code&gt;morgan&lt;/code&gt; &lt;code&gt;helmet&lt;/code&gt; &lt;code&gt;cors&lt;/code&gt; &lt;code&gt;axios&lt;/code&gt; &lt;code&gt;dotenv&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We will create two API routes one for verification of the webhook (this will be only used once) and one to receive messages/updates from WhatsApp&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GET &lt;code&gt;/api/webhook&lt;/code&gt; - To verify this webhook&lt;/li&gt;
&lt;li&gt;POST &lt;code&gt;/api/webhook&lt;/code&gt; - To receive messages from WhatsApp&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, we can configure a webhook in WhatsApp so that every time a message or update comes we will get notified of that and we can respond accordingly.&lt;/p&gt;

&lt;p&gt;This GET API of &lt;code&gt;/api/webhook&lt;/code&gt; will be used for verification of this webhook where WhatsApp will send a token and a couple of parameters and we will verify if all those matches whatever is configured on our server. It is called a Verification Token. We create a random long verification token and store it in the environment variables of our server.&lt;/p&gt;

&lt;p&gt;This will be our API route for GET &lt;code&gt;/api/webhook&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/webhook&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;VERIFY_TOKEN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VERIFY_TOKEN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Parse params from the webhook verification request&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hub.mode&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hub.verify_token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;challenge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hub.challenge&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="c1"&gt;// Check if a token and mode were sent&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Missing mode or token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Check the mode and token sent are correct&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;subscribe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;VERIFY_TOKEN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Respond with 200 OK and challenge token from the request&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;WEBHOOK_VERIFIED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Responds with '403 Forbidden' if verify tokens do not match&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To verify our webhook we go to &lt;strong&gt;WhatsApp Configuration&lt;/strong&gt; from the Meta App page&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa2m3j0gr4uw34dydamo4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa2m3j0gr4uw34dydamo4.png" alt="Image description" width="420" height="323"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Add the &lt;strong&gt;Webhook API URL&lt;/strong&gt; and the &lt;strong&gt;Verification token&lt;/strong&gt; and click on &lt;strong&gt;Verify and Save&lt;/strong&gt;. You can use a proxy like &lt;strong&gt;ngrok&lt;/strong&gt; if you are still in development. Webhook URL must be an HTTPS one with no Self-signed certificate in the chain.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Webhook fields&lt;/strong&gt;, Subscribe to &lt;strong&gt;messages&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85eazr6civwi974zsp70.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F85eazr6civwi974zsp70.png" alt="Image description" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now for the receiving messages webhook, POST &lt;code&gt;/api/webhook&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/webhook&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Parse the request body from the POST&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Check the Incoming webhook message&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Incoming webhook: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// Validate the webhook&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Handle the event&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;whatsapp_business_account&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="c1"&gt;// Handle the message&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;change&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
              &lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;messages&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
              &lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contacts&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
              &lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="c1"&gt;// Handle the value&lt;/span&gt;
              &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

              &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

              &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

              &lt;span class="c1"&gt;// Handle messages&lt;/span&gt;
              &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
                  &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
                  &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;waid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;msgId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Message from &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;waid&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; - &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;userName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;
                  &lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error occured &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how we will extract messages from the incoming webhook when the user sends a Text message on the configured number. We can use this text message and then reply accordingly. &lt;/p&gt;

&lt;p&gt;For our application, we pass this as a prompt to an OpenAPI model and then get a response from the AI and respond to the user. We are using &lt;code&gt;openai&lt;/code&gt; package for this.&lt;/p&gt;

&lt;p&gt;For responding to the user, we will use the &lt;code&gt;https://graph.facebook.com/v13.0/&amp;lt;phonenumberid&amp;gt;/messages&lt;/code&gt; API endpoint with the authentication token we collected earlier in Headers like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WHATSAPP_SEND_MESSAGE_API&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;messaging_product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;whatsapp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;recipient_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;individual&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;waid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;preview_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bearer &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WHATSAPP_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By this response will be send to the user.&lt;/p&gt;

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

&lt;p&gt;This is how we will use WhatsApp Cloud API and integrate WhatsApp with your application. There are endless possibilities since Meta recently made this API available to all, which was earlier only available to business owners or BSP (Business Service Partners). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="https://developers.facebook.com/docs/whatsapp/cloud-api/reference" rel="noopener noreferrer"&gt;https://developers.facebook.com/docs/whatsapp/cloud-api/reference&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>How to speed up a Web App loading time by 10x faster!</title>
      <dc:creator>Amit Wani</dc:creator>
      <pubDate>Mon, 16 May 2022 05:40:38 +0000</pubDate>
      <link>https://dev.to/mtwn105/how-to-speed-up-a-web-app-loading-time-by-10x-faster-1oke</link>
      <guid>https://dev.to/mtwn105/how-to-speed-up-a-web-app-loading-time-by-10x-faster-1oke</guid>
      <description>&lt;p&gt;Hello folks, Today I will discuss, how I speeded up the loading time of my Web App built using Angular or any SPA (Single Page Application).&lt;/p&gt;

&lt;p&gt;Before diving into the article, let's first understand how a Single Page Application (SPA) works be it developed using any web framework (Angular, React, etc.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Single Page Application
&lt;/h2&gt;

&lt;p&gt;The single-page application is a web application that interacts with the user by dynamically rewriting the current page, rather than loading entire new pages from the server.  &lt;/p&gt;

&lt;p&gt;In SPA, when the browser makes the first request to the server, the server sends back the &lt;code&gt;index.html&lt;/code&gt; file. and that's basically it. that's the only time an HTML file is served. the HTML file has a script tag for the &lt;code&gt;.js&lt;/code&gt; file which is going to take control of the &lt;code&gt;index.html&lt;/code&gt; page. All subsequent calls return just the data, usually in JSON format. the application uses this JSON data to update the page dynamically. However, the page never reloads.&lt;/p&gt;

&lt;p&gt;The client (and not the server) handles the job of transforming data to HTML once the application has started. basically, most of the modern SPA frameworks like Angular, React, and Vue has a templating engine of sorts running in your browser to generate the HTML.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fewmtm9j9oyxxmrjaqfo1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fewmtm9j9oyxxmrjaqfo1.png" alt="SPA" width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Now let's come to the problem or one of the drawbacks of using a SPA. Since the initial &lt;code&gt;index.html&lt;/code&gt; is very lightweight, most hard work is being done by the subsequent Javascript files fetched from the server and the client executing that JS in the browser. &lt;/p&gt;

&lt;p&gt;As our project starts to become complex with a lot of components and dependencies, the bundled JS file sizes get bigger with time. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3b5unhueqglzvjexbize.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3b5unhueqglzvjexbize.png" alt="FileSizeBefore" width="693" height="25"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Here you can see this is a bundled JS generated by the building of an Angular App which is more than 1 MB 🤯. This file has to get loaded in browsers which takes a good amount of time and the user has to wait for the first painting of the webpage.&lt;/p&gt;

&lt;p&gt;Though React is much lighter weight, one can definitely reduce this size by compressing these JS files. That's what we will do next.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;We will discuss one of the ways to deal with this problem, which is to compress the bundle JS files and serve their compressed versions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compress Bundled JS files
&lt;/h3&gt;

&lt;p&gt;In Angular, to generate a compressed version of these JS files, we can use &lt;code&gt;gzipper&lt;/code&gt; to compress files to &lt;code&gt;gzip&lt;/code&gt; format. &lt;/p&gt;

&lt;p&gt;We add a dev dependency in &lt;code&gt;package.json&lt;/code&gt; for &lt;code&gt;gzipper&lt;/code&gt;.&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="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&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="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"gzipper"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^7.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="err"&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;We also update our build script in &lt;code&gt;package.json&lt;/code&gt; to gzip the files after building using &lt;code&gt;gzipper&lt;/code&gt;.&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="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng build &amp;amp;&amp;amp; gzipper compress --verbose ./dist/client/"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when we build our application using &lt;code&gt;npm run build&lt;/code&gt; we will get two versions of that JS file. One is a non-compressed one and one is compressed with the &lt;code&gt;.js.gz&lt;/code&gt; extension.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F090c2bekkwyb9w2baev8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F090c2bekkwyb9w2baev8.png" alt="FileSizeAfter" width="724" height="26"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see the gzipped version of the Javascript file is almost 4 times smaller (1.2 MB to 300 KB)&lt;br&gt;
Along with JS, all HTML, CSS and asset files are also gzipped reducing their sizes by more than 50%.&lt;/p&gt;
&lt;h3&gt;
  
  
  Nginx
&lt;/h3&gt;

&lt;p&gt;Now comes the role of Nginx, we need something to serve these compressed versions of Javascript files, we will be using Nginx for this. &lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;nginx.conf&lt;/code&gt; - The configuration file for Nginx we will these four lines to the &lt;code&gt;server&lt;/code&gt; object&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    gzip on;
    gzip_min_length 1000;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will enable the gzip compression and when serving the files, if the gzip compression is supported by the browser, Nginx will serve the smaller gzip version thus reducing the loading time by up to 10X.&lt;/p&gt;

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

&lt;p&gt;This marks the end of this article. This was of the many ways to speed up the loading time of a Single Page Application. As your app gets to production-grade at scale, this will be very useful. &lt;/p&gt;

&lt;p&gt;For React, you can refer to &lt;a href="https://codetoart.com/blog/how-to-load-react-web-app-faster" rel="noopener noreferrer"&gt;this&lt;/a&gt; article to see how to generate build files in gzipped version.&lt;/p&gt;

&lt;p&gt;If you like this article, keep in touch with me on my socials or support me if you want. &lt;br&gt;
If you have any feedback, do let me know in the comments.&lt;/p&gt;

&lt;p&gt;Till next time, Peace.! &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>angular</category>
    </item>
    <item>
      <title>Read your Favorite Podcasts - PodText</title>
      <dc:creator>Amit Wani</dc:creator>
      <pubDate>Mon, 11 Apr 2022 11:58:59 +0000</pubDate>
      <link>https://dev.to/mtwn105/read-your-favorite-podcasts-podtext-4f0p</link>
      <guid>https://dev.to/mtwn105/read-your-favorite-podcasts-podtext-4f0p</guid>
      <description>&lt;p&gt;Hello folks, this post is regarding my submission for &lt;strong&gt;Deepgram Hackathon&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Idea
&lt;/h3&gt;

&lt;p&gt;So many of us wants to listen to various amazing podcasts out there, but due to time constraints we are not able to give so much time and attention to listen to them. What if its possible to read the transcript of the podcast in a text version, that's struck my mind. &lt;br&gt;
I decided to create an web app to &lt;strong&gt;Read the podcasts - PodText&lt;/strong&gt;. &lt;/p&gt;


&lt;h3&gt;
  
  
  Overview of My Submission
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;PodText&lt;/strong&gt; will allow us to browse through &lt;strong&gt;Top Podcasts&lt;/strong&gt; of various genres and read transcripts for each episode of a podcast.&lt;br&gt;
Podcast metadata and audio has been fetched using Podcast API by &lt;strong&gt;Listennotes&lt;/strong&gt;. Audio to Text transcription is done using &lt;strong&gt;Deepgram&lt;/strong&gt;'s API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link:&lt;/strong&gt; &lt;a href="//podtext.amitwani.dev"&gt;podtext.amitwani.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Currently, Podcasts are served from Mock server of Listennotes to avoid exhaustion of API quota&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Submission Category
&lt;/h3&gt;

&lt;p&gt;Accessibility Advocates &lt;/p&gt;


&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;NextJS&lt;/li&gt;
&lt;li&gt;NextUI&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Railway.app&lt;/li&gt;
&lt;li&gt;Listennotes&lt;/li&gt;
&lt;li&gt;Deepgram&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Details
&lt;/h3&gt;

&lt;p&gt;I have created a NextJS app along with NextUI as a UI library.&lt;br&gt;
Created pages for showing Genres (&lt;code&gt;genres/[id]&lt;/code&gt;), Podcasts (&lt;code&gt;podcasts/[id]&lt;/code&gt;), Episodes (&lt;code&gt;episodes/[id]&lt;/code&gt;) details. &lt;br&gt;
Created an API route &lt;code&gt;api/transcribe&lt;/code&gt; which is used to transcribe the audio of Podcast to text using Deepgram. Podcast audio will be fetched from Listennotes' CDN on the fly itself.&lt;/p&gt;


&lt;h3&gt;
  
  
  Link to Code on GitHub
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mtwn105" rel="noopener noreferrer"&gt;
        mtwn105
      &lt;/a&gt; / &lt;a href="https://github.com/mtwn105/podtext" rel="noopener noreferrer"&gt;
        podtext
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      View Text Versions of your favorite podcasts!
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Podtext&lt;/h1&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Read your favorite podcasts&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Link:&lt;/strong&gt; &lt;a href="https://github.com/mtwn105/podtextpodtext.up.railway.app" rel="noopener noreferrer"&gt;podtext.amitwani.dev&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Idea&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;So many of us wants to listen to various amazing podcasts out there, but due to time constraints we are not able to give so much time and attention to listen to them. What if its possible to read the transcript of the podcast in a text version, that's struck my mind.
I decided to create an web app to &lt;strong&gt;Read the podcasts - PodText&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Tech Stack&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;NextJS&lt;/li&gt;
&lt;li&gt;NextUI&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Railway.app&lt;/li&gt;
&lt;li&gt;Listennotes&lt;/li&gt;
&lt;li&gt;Deepgram&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mtwn105/podtext" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h3&gt;
  
  
  Screenshots/Demo
&lt;/h3&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/46c09374980f4bc28c5cb983373e75ac"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Future Improvements
&lt;/h3&gt;

&lt;p&gt;There's always room for improvement, here are some things which can be added or done better in this&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better UI/UX&lt;/li&gt;
&lt;li&gt;Ability to Play Podcast&lt;/li&gt;
&lt;li&gt;Ability to search podcasts&lt;/li&gt;
&lt;li&gt;Caching podcast transcriptions&lt;/li&gt;
&lt;li&gt;Improved SEO&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I have learned a lot while making this project. This has been my first proper project on NextJS, still much improvement is needed on this front. Had fun with using Deepgram's API very easy to use and straight forward. &lt;br&gt;
Looking forward to everyone's submissions and more such hackathons.&lt;/p&gt;

&lt;p&gt;Till next time, peace!&lt;/p&gt;

</description>
      <category>hackwithdg</category>
      <category>nextjs</category>
      <category>react</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Manage your GitHub Starred Repositories</title>
      <dc:creator>Amit Wani</dc:creator>
      <pubDate>Tue, 05 Apr 2022 04:22:26 +0000</pubDate>
      <link>https://dev.to/mtwn105/manage-your-github-starred-repositories-16po</link>
      <guid>https://dev.to/mtwn105/manage-your-github-starred-repositories-16po</guid>
      <description>&lt;p&gt;Hello folks, this is a quick article about how you can manage your &lt;strong&gt;GitHub's starred repositories&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;You must have come across hundreds of awesome GitHub repositories but the problem is it's very hard to find the one you want at that moment in time.&lt;/p&gt;

&lt;p&gt;For this, we usually &lt;strong&gt;star&lt;/strong&gt; our GitHub repositories, but we forget about them.&lt;/p&gt;

&lt;p&gt;To solve this, I came across this feature in GitHub (still in beta), where you can &lt;strong&gt;create lists&lt;/strong&gt; to &lt;strong&gt;organize&lt;/strong&gt; your starred repositories.&lt;/p&gt;

&lt;p&gt;To do this you just click on the &lt;strong&gt;arrow icon&lt;/strong&gt; next to &lt;strong&gt;Star&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasic2yg6xgkopfxjicew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasic2yg6xgkopfxjicew.png" alt="Star" width="484" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will be presented with a dropdown to &lt;strong&gt;select&lt;/strong&gt; an existing list or &lt;strong&gt;create&lt;/strong&gt; a new list&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjtpj59q371kdb0ygq22w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjtpj59q371kdb0ygq22w.png" alt="List" width="393" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you select a list, it will be saved in that list.&lt;br&gt;
You can revisit it by going to &lt;strong&gt;Your Stars&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa7bupeen3cqy3uaikzm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa7bupeen3cqy3uaikzm.png" alt="YourStars" width="246" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And you can see all your lists, you can go through them, search in them, etc.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwetnpntw5tszya1dx9u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwetnpntw5tszya1dx9u.png" alt="StarList" width="800" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for this article. Hope you found it useful. Share your thoughts down below.&lt;/p&gt;

&lt;p&gt;Till next time, peace.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>opensource</category>
      <category>github</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Journal CLI - Write Journal in Notion using CLI</title>
      <dc:creator>Amit Wani</dc:creator>
      <pubDate>Sun, 20 Mar 2022 07:03:22 +0000</pubDate>
      <link>https://dev.to/mtwn105/journal-cli-write-journal-in-notion-using-cli-5071</link>
      <guid>https://dev.to/mtwn105/journal-cli-write-journal-in-notion-using-cli-5071</guid>
      <description>&lt;p&gt;Hello folks, today I tried to play around with Notion API and NodeJS to create a CLI which can write Journal for you and store it in a Notion Database.&lt;/p&gt;

&lt;p&gt;These days, there is a lot of stuff going on in our lives and we want to focus on the ones which matter most to us. One way to solve this is by writing a journal and sorting this chaotic mess. &lt;/p&gt;

&lt;p&gt;Using &lt;a href="https://notion.so" rel="noopener noreferrer"&gt;Notion&lt;/a&gt;, we can create beautiful interactive notes and much more. Using the power of notion and efficiency of CLI, I developed this quick way, you can start journaling, by answering just 5 questions at the end of the day and the Journal will be saved in a database in Notion.!&lt;/p&gt;

&lt;p&gt;NPM Link - &lt;a href="https://www.npmjs.com/package/journal-notion-cli" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/journal-notion-cli&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Duplicate Template
&lt;/h3&gt;

&lt;p&gt;To Get Started Duplicate this &lt;a href="https://amit-wani.notion.site/amit-wani/Journal-a19377f6b17d47768e03d4ffe62a030d" rel="noopener noreferrer"&gt;Notion Template&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;Then Install Journal CLI from NPM using&lt;br&gt;
&lt;code&gt;npm i -g journal-notion-cli&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Connect to Notion
&lt;/h3&gt;

&lt;p&gt;Connect to the notion by running &lt;code&gt;journal connect&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Write Journal
&lt;/h3&gt;

&lt;p&gt;Write a journal every day using &lt;code&gt;journal write&lt;/code&gt; and answer a few questions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Demo
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa5qe9ss6lze48a2yz5ko.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa5qe9ss6lze48a2yz5ko.gif" alt="Demo" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Source Code
&lt;/h3&gt;

&lt;p&gt;If you like it and want to know more, do check out the GitHub repo at &lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mtwn105" rel="noopener noreferrer"&gt;
        mtwn105
      &lt;/a&gt; / &lt;a href="https://github.com/mtwn105/journal-cli" rel="noopener noreferrer"&gt;
        journal-cli
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A CLI to write journal for you and save it to a Notion database!
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Journal CLI&lt;/h1&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;&lt;a href="https://www.npmjs.com/package/journal-notion-cli" rel="nofollow noopener noreferrer"&gt;NPM Link&lt;/a&gt;&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;A CLI to write journal for you and save it to a Notion database!&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://www.producthunt.com/posts/journal-cli?utm_source=badge-featured&amp;amp;utm_medium=badge&amp;amp;utm_souce=badge-journal-cli" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/05ecfc6c6c1cefa93729217c2ffb2f3cde523bb56b8a515a3aee4cb3557cd4b4/68747470733a2f2f6170692e70726f6475637468756e742e636f6d2f776964676574732f656d6265642d696d6167652f76312f66656174757265642e7376673f706f73745f69643d333337393332267468656d653d6c69676874" alt="Journal CLI - Write daily journal in notion using CLI | Product Hunt" width="250" height="54"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/12975481/159121193-9ffe743c-352e-48c4-b43b-a577190ae658.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F12975481%2F159121193-9ffe743c-352e-48c4-b43b-a577190ae658.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Demo&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/62e127b009b446898d58b8100523d9a4c07e2d52d998ebf7af1ff63619700893/68747470733a2f2f6d65646961342e67697068792e636f6d2f6d656469612f5a6666716158696c434d6c66454b48335a462f67697068792e6769663f6369643d373930623736313163663139633034306364386132306666313163363165363237343539363966316363636662633762267269643d67697068792e6769662663743d67"&gt;&lt;img src="https://camo.githubusercontent.com/62e127b009b446898d58b8100523d9a4c07e2d52d998ebf7af1ff63619700893/68747470733a2f2f6d65646961342e67697068792e636f6d2f6d656469612f5a6666716158696c434d6c66454b48335a462f67697068792e6769663f6369643d373930623736313163663139633034306364386132306666313163363165363237343539363966316363636662633762267269643d67697068792e6769662663743d67" alt="demo"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Installation&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Run &lt;code&gt;npm i -g journal-notion-cli&lt;/code&gt; to install the cli.&lt;/p&gt;
&lt;p&gt;Start using by &lt;code&gt;journal connect&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Help Command &lt;code&gt;journal --help&lt;/code&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Duplicate this page to your notion&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://amit-wani.notion.site/amit-wani/Journal-a19377f6b17d47768e03d4ffe62a030d" rel="nofollow noopener noreferrer"&gt;https://amit-wani.notion.site/amit-wani/Journal-a19377f6b17d47768e03d4ffe62a030d&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/12975481/159122439-d5a9aa76-0648-441d-8376-ab9262108b38.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F12975481%2F159122439-d5a9aa76-0648-441d-8376-ab9262108b38.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Connect to notion &lt;code&gt;journal connect&lt;/code&gt;
&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/12975481/159121300-df0be909-9ec9-4ab8-82e1-ef669eee0d20.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F12975481%2F159121300-df0be909-9ec9-4ab8-82e1-ef669eee0d20.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/12975481/159121314-9396644f-e288-4334-8640-1317af6b671d.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F12975481%2F159121314-9396644f-e288-4334-8640-1317af6b671d.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/12975481/159121372-95cf0824-7cba-40b9-a876-7eea6737b51b.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F12975481%2F159121372-95cf0824-7cba-40b9-a876-7eea6737b51b.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/12975481/159121402-31dac731-6139-41af-a8a5-d4653b5ae395.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F12975481%2F159121402-31dac731-6139-41af-a8a5-d4653b5ae395.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Write journal every day using &lt;code&gt;journal write&lt;/code&gt;
&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/12975481/159121444-939ed87b-1ae1-412d-955e-c8bc1a8327bb.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F12975481%2F159121444-939ed87b-1ae1-412d-955e-c8bc1a8327bb.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/12975481/159121477-b0809f0b-205c-449c-8239-54d984986350.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F12975481%2F159121477-b0809f0b-205c-449c-8239-54d984986350.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/12975481/159121481-fa9020b0-aff2-4449-9df7-af869410461a.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F12975481%2F159121481-fa9020b0-aff2-4449-9df7-af869410461a.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Buy me a coffee&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/mtwn105" rel="nofollow noopener noreferrer"&gt;coffee&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mtwn105/journal-cli" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;If you like this tool, do support me by using the "Buy me a coffee" button, and keep reading my content by subscribing to newsletters. Till next time, peace.&lt;/p&gt;

&lt;h3&gt;
  
  
  Buy me a coffee
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/mtwn105" rel="noopener noreferrer"&gt;https://www.buymeacoffee.com/mtwn105&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>opensource</category>
      <category>showdev</category>
      <category>bash</category>
    </item>
    <item>
      <title>Correlation Analysis Between Stocks using Python</title>
      <dc:creator>Amit Wani</dc:creator>
      <pubDate>Thu, 17 Mar 2022 05:43:22 +0000</pubDate>
      <link>https://dev.to/mtwn105/correlation-analysis-between-stocks-using-python-1mk3</link>
      <guid>https://dev.to/mtwn105/correlation-analysis-between-stocks-using-python-1mk3</guid>
      <description>&lt;p&gt;Hello everyone, this article is about the tutorial on how to do the correlation analysis of Indian Bank stocks. We will compare major private and public banking stocks listed on the stock exchange. &lt;/p&gt;

&lt;p&gt;I will be using Python for data analysis for this one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Dependencies
&lt;/h2&gt;

&lt;p&gt;First, we need to install the required dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;pandas
pip &lt;span class="nb"&gt;install &lt;/span&gt;numpy
pip &lt;span class="nb"&gt;install &lt;/span&gt;yfinance
pip &lt;span class="nb"&gt;install &lt;/span&gt;seaborn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Import Dependencies
&lt;/h2&gt;

&lt;p&gt;Now, we will import these required dependencies into our code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yfinance&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;yf&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;seaborn&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sns&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fetching Stock Price Data
&lt;/h2&gt;

&lt;p&gt;I have taken the below stocks for correlation analysis and stored them in a list. You can see I have added their ticker symbols ending with ".NS" these are picked up from Yahoo Finance since we will be fetching data from Yahoo Finance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tickers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;HDFCBANK.NS&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ICICIBANK.NS&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AXISBANK.NS&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SBIN.NS&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;KOTAKBANK.NS&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;INDUSINDBK.NS&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;BANKBARODA.NS&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will fetch data for these stocks from Yahoo Finance using &lt;code&gt;yfinance&lt;/code&gt;. I am fetching data of 10 years with &lt;code&gt;auto_adjust=True&lt;/code&gt; for getting close price data adjusted for corporate actions. Then storing them into another list called &lt;code&gt;data&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ticker&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tickers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;ytick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Ticker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticker&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ytick&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;history&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;period&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10y&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auto_adjust&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;threads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Close&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Manipulating Data
&lt;/h2&gt;

&lt;p&gt;Now, we have a list with multiple panda data frames. For creating a correlation matrix, we need to merge them into a single data frame with only the closing price data of all the stocks.&lt;/p&gt;

&lt;p&gt;For this to achieve, we will first use the &lt;code&gt;zip&lt;/code&gt; function to zip all the data frames and then use a dictionary to associate the data frame with the stock using the &lt;code&gt;dict&lt;/code&gt; function. Finally, we will use the &lt;code&gt;concat&lt;/code&gt; function of pandas to concatenate all these data frames from &lt;code&gt;dict&lt;/code&gt; with appropriate columns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;mergedDf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tickers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The new data frame should look something like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz16fp7eq28qs65ixjmbd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz16fp7eq28qs65ixjmbd.png" alt="image.png" width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now since here we have multiple columns of data, but we don't need it, that's why we will only keep &lt;code&gt;Close&lt;/code&gt; column data. &lt;br&gt;
We will get the Level 1 values and filter only with the &lt;code&gt;Close&lt;/code&gt; column.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;closeDf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mergedDf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt;&lt;span class="n"&gt;mergedDf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_level_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;isin&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Close&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will now look like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7c85y6hd8dkyx3s2cw1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7c85y6hd8dkyx3s2cw1.png" alt="image.png" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But we also don't need these two levels of headers now. So we can drop Level 1 and only keep symbol tickers as the column header.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;closeDf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;closeDf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;droplevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will now look like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa84sxv6ch7dskp1043yl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa84sxv6ch7dskp1043yl.png" alt="image.png" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Correlation Analysis
&lt;/h2&gt;

&lt;p&gt;Now we have close price data for all stocks in a single data frame. We now need to calculate daily returns so that we can then create a correlation matrix from that data. But, simple &lt;code&gt;pct_change&lt;/code&gt; returns won't work as every stock has a different base as well, so we will need to calculate daily log-returns of all stocks. We can do this by doing the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;logretDf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;closeDf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pct_change&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will now look like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ml4ro7c3uqkbqgouox9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ml4ro7c3uqkbqgouox9.png" alt="image.png" width="800" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we have a data frame from which we can get various insights regarding correlation, standard variation etc.&lt;br&gt;
We can show the correlation matrix by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;logretDf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;corr&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see something like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zdd49mmv2lh2rhyiq12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zdd49mmv2lh2rhyiq12.png" alt="image.png" width="800" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This shows us the correlation percentage of all stocks with each other over the past 10 years of data.&lt;br&gt;
To visualize this better we can use &lt;code&gt;seaborn&lt;/code&gt; to plot it in a graphical fashion like below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;sns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;heatmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logretDf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;corr&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see something like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1d57rfzm9jt1497zdlql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1d57rfzm9jt1497zdlql.png" alt="image.png" width="427" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will show us a much easier view of the correlation between various banking stocks.&lt;/p&gt;

&lt;p&gt;If you got this far, means now you can do correlation analysis of any number of stocks. If you like what I write, please do share it on social media. Till next time, peace.!  &lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>python</category>
      <category>datascience</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
