<?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: Atharva Sharma</title>
    <description>The latest articles on DEV Community by Atharva Sharma (@atharva_sharma_8b4cb9669d).</description>
    <link>https://dev.to/atharva_sharma_8b4cb9669d</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3410210%2Fe804e7d8-3f67-4563-8f97-675439289eb8.png</url>
      <title>DEV Community: Atharva Sharma</title>
      <link>https://dev.to/atharva_sharma_8b4cb9669d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/atharva_sharma_8b4cb9669d"/>
    <language>en</language>
    <item>
      <title>How did the world reach microservices?</title>
      <dc:creator>Atharva Sharma</dc:creator>
      <pubDate>Wed, 13 Aug 2025 23:08:15 +0000</pubDate>
      <link>https://dev.to/atharva_sharma_8b4cb9669d/how-did-the-world-reach-microservices-57pm</link>
      <guid>https://dev.to/atharva_sharma_8b4cb9669d/how-did-the-world-reach-microservices-57pm</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Imagine a small team in a cramped office, working on a single piece of software. Everything lived in one big package the code, the build scripts, the tests were all tied together in a neat bundle. Deployments were simple: one pipeline, one click, and voilà, the product was live. Back then, it was efficient, even comforting.&lt;/p&gt;

&lt;p&gt;But the company grew. The team doubled, then tripled. Suddenly, that “neat bundle” became a battlefield. Developers stepped on each other’s toes, merge conflicts piled up, and one person’s tiny change could bring the whole system crashing down. Releases turned into high-stakes events. “Did we break anything this time?” became the office’s unofficial catchphrase.&lt;/p&gt;

&lt;p&gt;So, we tried a fix. We broke the giant package into smaller ones, giving each team their own corner to work in. It helped… for a while. But we were still tied together at the hip during deployments. The real breakthrough came when we started splitting not just code, but responsibility — separate builds, separate deployments, even separate infrastructure. And just like that, the path to microservices had begun.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Monolith Days
&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%2Feuf8wbkjeecw35p5zq5a.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%2Feuf8wbkjeecw35p5zq5a.png" alt="monolith" width="746" height="461"&gt;&lt;/a&gt;&lt;br&gt;
In Monolith architecture all developers contribute to a single, unified code package. Developer1, Developer2, and Developer3 each make their commits directly into the same shared codebase. Once all changes are merged, the entire application is built and deployed as a single unit — first to a beta environment, and then to production. This approach means that any change, no matter how small, requires rebuilding and redeploying the whole system. While simple in setup, it creates a high risk of conflicts, slows down release cycles, and increases the blast radius of failures since every update affects the entire application.&lt;/p&gt;

&lt;p&gt;Now imagine, the team grows to 150 developers. All the developers are now committing to the same package, some of them to the same files. After a point it becomes extremely difficult for the developers to keep pulling each other's changes and resolving conflicts. &lt;/p&gt;

&lt;h2&gt;
  
  
  Modularization
&lt;/h2&gt;

&lt;p&gt;One easy solution to the problem is to divide the code base into multiple packages and give ownership of each package to individual teams. For eg: For an ecommerce platform code for Orders, Inventory, Returns etc. can be split into different packages. All the packages are the built together in the end to be deployed to beta and prod environments. &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%2Fxknl5uhob93ed5ulcio4.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%2Fxknl5uhob93ed5ulcio4.png" alt="modular" width="796" height="961"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now imagine the team grows to a 1000 people. It might happen that there is a certain feature in the returns package that needs to be deployed whereas the orders team is not ready to deploy changes to prod. In this case, returns team needs to wait for orders team to be ready for prod deployment or the orders team will need to revert their changes. &lt;/p&gt;

&lt;p&gt;Also, you would need a separate team just to maintain the deployment pipeline and for building consensus between multiple teams. &lt;/p&gt;

&lt;h2&gt;
  
  
  Microservices
&lt;/h2&gt;

&lt;p&gt;This is where Microservices comes into picture. Along with separate packages, what if we split the deployment pipelines and infrastructure between multiple teams? The combination of a separate package + pipeline + infrastructure is called as a microservice. &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%2Ful9r6uj3ac1b6d7gq2rp.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%2Ful9r6uj3ac1b6d7gq2rp.png" alt="microservice" width="756" height="971"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each microservice then interacts with other microservices through APIs. &lt;/p&gt;

&lt;p&gt;This gives a team freedom to deploy their own changes whenever they want, without any conflicts. Individual teams manage their own infra and pipelines. Any blockers or failures don't block other teams. The huge code package and build created in Monolith also becomes smaller leading to easier code maintenance, faster builds and deployment times. &lt;/p&gt;

&lt;p&gt;The downside of this approach is that there is higher latency between service interactions when compared to a monolith as the infrastructure is separate and services interact via API calls which are network calls. &lt;/p&gt;

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

&lt;p&gt;Microservices aren’t the inevitable destiny of every software project but they’re the result of scaling pains that monoliths and modularization can no longer solve. As teams grow and products become more complex, the need for independent ownership, faster releases, and reduced blast radius pushes organizations toward breaking systems into smaller, autonomous parts.&lt;/p&gt;

&lt;p&gt;But with that freedom comes new responsibilities: managing more infrastructure, handling inter-service communication, and keeping an eye on performance overhead. The real lesson? Architecture is a journey. Start simple, evolve as you grow, and choose the approach that best matches your team’s size, culture, and goals not just what’s trending in the industry.&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>devops</category>
      <category>distributedsystems</category>
      <category>microservices</category>
    </item>
    <item>
      <title>Letting AI Narrate My Past: A Telegram Bot with Google Drive and GenAI Magic</title>
      <dc:creator>Atharva Sharma</dc:creator>
      <pubDate>Mon, 04 Aug 2025 00:21:49 +0000</pubDate>
      <link>https://dev.to/atharva_sharma_8b4cb9669d/letting-ai-narrate-my-past-a-telegram-bot-with-google-drive-and-genai-magic-240m</link>
      <guid>https://dev.to/atharva_sharma_8b4cb9669d/letting-ai-narrate-my-past-a-telegram-bot-with-google-drive-and-genai-magic-240m</guid>
      <description>&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;In the age of cloud storage and AI, our digital memories often remain buried in folders, rarely revisited or shared meaningfully. This project bridges that gap by combining the capabilities of the Google Drive API, Generative AI, and Telegram Bot API to create a personal assistant that not only surfaces photos from your Google Drive but also generates thoughtful, human-like captions for them.&lt;/p&gt;

&lt;p&gt;The assistant is designed to automatically pull a random image from a specified Google Drive folder every 24 hours (with modifiable frequency) and send it to a Telegram group. Each photo is accompanied by an AI-generated caption that attempts to interpret or narrate the memory behind the image in a relatable and engaging way.&lt;/p&gt;

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

&lt;p&gt;We make use of the following AWS services to implement this assistant:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt; Lambda: &lt;/strong&gt; &lt;br&gt;
AWS Lambda is a serverless compute service that lets you run code without provisioning or managing servers. You simply upload your function, and Lambda automatically scales and executes it in response to events such as HTTP requests, file uploads, or scheduled triggers. You only pay for the compute time your code consumes, making it a cost-effective and scalable way to build backend logic or automation tasks. &lt;br&gt;&lt;br&gt;
AWS Lambda is the preferred compute choice for this project because the assistant doesn’t need to run continuously. It only needs to execute once every 24 hours (or at a defined frequency). With Lambda’s serverless model, we can trigger the function on a schedule without worrying about server uptime or manual scaling. This makes it highly efficient and cost-effective, as we only pay when the code runs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt; Event Bridge: &lt;/strong&gt;&lt;br&gt;
Amazon EventBridge is a serverless event bus service that makes it easy to connect and trigger actions based on time-based schedules or events from AWS services. In this project, EventBridge is used to invoke the Lambda function every 24 hours, acting like a cloud-based cron scheduler. It’s reliable, scalable, and requires no infrastructure management—perfect for automating periodic tasks.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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%2Fj59oy7nqrku9fab92r17.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%2Fj59oy7nqrku9fab92r17.png" alt="Architecture diagram" width="490" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up AWS Lambda and EventBridge
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: Create the Lambda Function
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Go to the &lt;a href="https://console.aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;AWS Lambda Console&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;“Create function”&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Choose:

&lt;ul&gt;
&lt;li&gt;Author from scratch&lt;/li&gt;
&lt;li&gt;Function name: &lt;code&gt;MemoryBotFunction&lt;/code&gt; (or your preferred name)&lt;/li&gt;
&lt;li&gt;Runtime: Choose your language (e.g., Python 3.x or Node.js)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;Create Function&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Step 2: Create a Scheduled Rule in EventBridge
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Go to the &lt;a href="https://console.aws.amazon.com/events/" rel="noopener noreferrer"&gt;Amazon EventBridge Console&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;"Create rule"&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Name&lt;/em&gt;: &lt;code&gt;DailyMemoryBotTrigger&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Description&lt;/em&gt;: “Triggers Lambda every 24 hours”&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Event bus&lt;/em&gt;: Leave as &lt;code&gt;default&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Rule type&lt;/em&gt;: Choose &lt;em&gt;“Schedule”&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Under &lt;em&gt;Schedule pattern&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select &lt;em&gt;“Rate expression”&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Example: &lt;code&gt;rate(1 day)&lt;/code&gt; for once every 24 hours
&lt;em&gt;(You can modify this to &lt;code&gt;rate(6 hours)&lt;/code&gt;, &lt;code&gt;cron(0 8 * * ? *)&lt;/code&gt;, etc.)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In &lt;em&gt;Target&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose &lt;em&gt;Lambda function&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Select your Lambda (&lt;code&gt;MemoryBotFunction&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;em&gt;Next&lt;/em&gt;, then &lt;em&gt;Create Rule&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Integrating with Google Drive
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: Create a Google Cloud Project and Enable Drive API
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Go to the &lt;a href="https://console.cloud.google.com/" rel="noopener noreferrer"&gt;Google Cloud Console&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;Select a project&lt;/em&gt; → &lt;em&gt;New Project&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Enter a project name (e.g., &lt;code&gt;MemoryBotProject&lt;/code&gt;) and click &lt;em&gt;Create&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Navigate to &lt;em&gt;APIs &amp;amp; Services&lt;/em&gt; → &lt;em&gt;Library&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Search for &lt;em&gt;Google Drive API&lt;/em&gt; and click &lt;em&gt;Enable&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Step 2: Set Up OAuth 2.0 Credentials
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;In the Cloud Console, go to &lt;em&gt;APIs &amp;amp; Services&lt;/em&gt; → &lt;em&gt;Credentials&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;Create Credentials&lt;/em&gt; → &lt;em&gt;OAuth client ID&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Configure the &lt;em&gt;OAuth consent screen&lt;/em&gt; if prompted.&lt;/li&gt;
&lt;li&gt;Choose &lt;em&gt;Application type&lt;/em&gt;:

&lt;ul&gt;
&lt;li&gt;For a backend app, select &lt;em&gt;Web application&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Add authorized redirect URIs if needed (for OAuth flow).&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;Create&lt;/em&gt; and download the &lt;code&gt;credentials.json&lt;/code&gt; file. &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Intregrating with Gemini API
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: Get Access to Gemini API
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Sign up or log in to the &lt;a href="https://aistudio.google.com" rel="noopener noreferrer"&gt;Google AI studio&lt;/a&gt; .&lt;/li&gt;
&lt;li&gt;Create a new API key or obtain your access credentials (API key, client ID, secret, etc.).&lt;/li&gt;
&lt;li&gt;Make sure to securely store these credentials.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Intregrating with Telegram API
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: Create a Telegram Bot
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Open Telegram and search for &lt;em&gt;BotFather&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Start a chat with BotFather and send the command &lt;code&gt;/newbot&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Follow the prompts to:

&lt;ul&gt;
&lt;li&gt;Name your bot.&lt;/li&gt;
&lt;li&gt;Choose a unique username ending with &lt;code&gt;bot&lt;/code&gt; (e.g., &lt;code&gt;MemoryBot&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;After creation, BotFather will provide a &lt;em&gt;bot token&lt;/em&gt;. Save this token securely — you will need it to access the Telegram Bot API.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Step 2: Get your group ChatId
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Add your bot to the group or start a private chat with it.&lt;/li&gt;
&lt;li&gt;Send any message in that chat (or group).&lt;/li&gt;
&lt;li&gt;Open this URL in your browser (replace &lt;code&gt;&amp;lt;YOUR_BOT_TOKEN&amp;gt;&lt;/code&gt; with your bot token):
&lt;code&gt;https://api.telegram.org/bot&amp;lt;YOUR_BOT_TOKEN&amp;gt;/getUpdates&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Look for the &lt;code&gt;"chat":{"id":...}&lt;/code&gt; field in the JSON response — that number is your chat ID.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  It's time to write code!
&lt;/h3&gt;

&lt;p&gt;Add the following code to the lambda by navigating to the code tab in lambda console. Make sure to replace the &lt;code&gt;systemPrompt&lt;/code&gt; with context for your bot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { GoogleGenerativeAI } = require('@google/generative-ai');
const fs = require('fs');
const path = require('path');
const { google } = require('googleapis');
const TelegramBot = require('node-telegram-bot-api');

exports.handler = async (event) =&amp;gt; {
    const botToken = process.env.TELEGRAM_BOT_TOKEN;
    const chatId = process.env.CHAT_ID;
    const geminiApiKey = process.env.GEMINI_API_KEY;

    const bot = new TelegramBot(botToken, { polling: false });

    const SCOPES = ['https://www.googleapis.com/auth/drive.readonly'];
    const credentialsPath = '/tmp/credentials.json';
    const rootFolderId = process.env.GOOGLE_DRIVE_FOLDER_ID;

    const credentials = JSON.parse(process.env.GOOGLE_CREDENTIALS_JSON);
    fs.writeFileSync(credentialsPath, JSON.stringify(credentials));

    async function authenticateGoogleDrive() {
        const auth = new google.auth.GoogleAuth({
            keyFile: credentialsPath,
            scopes: SCOPES,
        });
        return google.drive({ version: 'v3', auth });
    }

    async function getSubfolders(drive, parentFolderId) {
        const res = await drive.files.list({
            q: `'${parentFolderId}' in parents and mimeType = 'application/vnd.google-apps.folder' and name != 'videos' and name != 'Bannerghatta'`,
            fields: 'files(id, name)',
        });
        return res.data.files;
    }

    async function getImagesFromFolder(drive, folderId) {
        const res = await drive.files.list({
            q: `'${folderId}' in parents and mimeType contains 'image/'`,
            fields: 'files(id, name, mimeType)',
        });
        return res.data.files;
    }

    async function downloadFile(drive, fileId, filePath) {
        const dest = fs.createWriteStream(filePath);
        await drive.files.get({ fileId, alt: 'media' }, { responseType: 'stream' })
            .then(res =&amp;gt; {
                return new Promise((resolve, reject) =&amp;gt; {
                    res.data
                        .on('end', () =&amp;gt; resolve())
                        .on('error', err =&amp;gt; reject(err))
                        .pipe(dest);
                });
            });
    }

    async function generateCaptionWithGemini(imagePath) {
        const genAI = new GoogleGenerativeAI(geminiApiKey);
        const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });

        const imageBuffer = fs.readFileSync(imagePath);
        const imageData = {
            inlineData: {
                data: imageBuffer.toString('base64'),
                mimeType: 'image/jpeg',
            }
        };

        // Add your prompt here
        const systemPrompt = ""

        const result = await model.generateContent([
            { text: systemPrompt},
            imageData,
            { text: "Give a short and warm caption for this photo."},
        ]);

        const response = await result.response;
        const caption = response.text();
        return caption;
    }

    async function sendRandomImage() {
        try {
            const drive = await authenticateGoogleDrive();
            const folders = await getSubfolders(drive, rootFolderId);

            if (folders.length === 0) {
                console.log('No folders found.');
                return;
            }

            let selectedImage = null;

            while (!selectedImage) {
                const randomFolder = folders[Math.floor(Math.random() * folders.length)];
                console.log(`Selected folder: ${randomFolder.name}`);

                const images = await getImagesFromFolder(drive, randomFolder.id);

                if (images.length === 0) {
                    console.log(`No images found in folder: ${randomFolder.name}`);
                    continue;
                }

                selectedImage = images[Math.floor(Math.random() * images.length)];

                if (selectedImage.mimeType.startsWith('video/')) {
                    console.log(`Skipping video: ${selectedImage.name}`);
                    selectedImage = null;
                }
            }

            const filePath = path.join('/tmp', selectedImage.name);
            await downloadFile(drive, selectedImage.id, filePath);

            const caption = await generateCaptionWithGemini(filePath);

            await bot.sendPhoto(chatId, filePath, { caption });
            console.log(`Sent image with caption: ${caption}`);

            fs.unlinkSync(filePath);
        } catch (error) {
            console.error('Error sending image:', error);
        }
    }

    await sendRandomImage();

    return {
        statusCode: 200,
        body: JSON.stringify('Image sent successfully!'),
    };
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following code to package.json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "your-project-name",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@google/generative-ai": "^0.24.1",
    "dotenv": "^16.4.5",
    "googleapis": "^140.0.1",
    "node-telegram-bot-api": "^0.66.0"
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add envrionment variables
&lt;/h3&gt;

&lt;p&gt;This is the final step where we add all the environment variables required for our app to function. &lt;/p&gt;

&lt;p&gt;Navigate to: &lt;code&gt;Configuration -&amp;gt; Environment Variables&lt;/code&gt; from the AWS console and add the following environment variables:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;CHAT_ID&lt;/code&gt; - Chat Id received in this step
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GEMINI_API_KEY&lt;/code&gt; - Gemini API key generated in this step
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GOOGLE_CREDENTIALS_JSON&lt;/code&gt; - Content of the JSON file downloaded in this step
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GOOGLE_DRIVE_FOLDER_ID&lt;/code&gt; - Open the google drive folder you want to fetch memories from. The part after &lt;code&gt;/folders/&lt;/code&gt; in the URL is the &lt;em&gt;folder ID&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TELEGRAM_BOT_TOKEN&lt;/code&gt; - Telegram BOT token generated in this step
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Building a Telegram bot that seamlessly integrates Google Drive and Gemini AI to share personalized memories is a powerful way to combine cloud storage, AI, and messaging platforms. By leveraging AWS Lambda and EventBridge, you can automate the process efficiently without keeping the bot running 24/7.&lt;/p&gt;

&lt;p&gt;This project not only showcases how APIs can work together to create unique user experiences but also provides a solid foundation to explore more advanced AI-powered automation.&lt;/p&gt;

&lt;p&gt;Feel free to customize the bot’s frequency, add more AI capabilities, or expand it to other platforms. The possibilities are endless!&lt;/p&gt;

&lt;p&gt;Happy coding and memory sharing! 🚀&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>gemini</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
