<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Roshdy's blog]]></title><description><![CDATA[Roshdy's blog]]></description><link>https://blog.roshdy.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 12 Apr 2026 02:51:20 GMT</lastBuildDate><atom:link href="https://blog.roshdy.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[I built an AWS Lambda function to prepare my meals using AI]]></title><description><![CDATA[This is Day#2 of the #*ServerlessChallenge **challenge, where I'm creating/building serverless apps using different AWS services.*

Short description: An API that accepts a list of food/ingredients that I have and returns meal ideas that I can prepar...]]></description><link>https://blog.roshdy.dev/i-built-an-aws-lambda-function-to-prepare-my-meals-using-ai</link><guid isPermaLink="true">https://blog.roshdy.dev/i-built-an-aws-lambda-function-to-prepare-my-meals-using-ai</guid><category><![CDATA[AWS]]></category><category><![CDATA[Amazon Bedrock]]></category><category><![CDATA[aws lambda]]></category><category><![CDATA[aws-apigateway]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Mohammed Roshdy]]></dc:creator><pubDate>Fri, 27 Oct 2023 14:57:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1698415413334/7c5a996d-6502-4af4-8c04-c7b934392ed8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><strong><em>This is Day#2 of the #*</em></strong>ServerlessChallenge<em> **</em>challenge, where I'm creating/building serverless apps using different AWS services.<em>*</em></p>
</blockquote>
<p><strong>Short description</strong>: An API that accepts a list of food/ingredients that I have and returns meal ideas that I can prepare.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698417770181/676b71bb-1af8-49d0-aa98-0bb2006b55e7.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-the-longtech-description"><strong>The long/tech description</strong></h3>
<p>Using Amazon Bedrock (Jurassic-2 Mid model) to generate some meal ideas and the steps for preparing it after getting the input of the available ingredients and the number of needed meals:</p>
<p>The prompt text is so simple but it's enough to make sure that the output will be as I want, also the max number of tokens is limited to 200 which is enough <s>Don't want to be surprised by the invoice </s> <a target="_blank" href="https://emojipedia.org/person-running"><s>🏃</s></a><s>-</s></p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">const</span> command: InvokeModelCommand = <span class="hljs-keyword">new</span> InvokeModelCommand({
    modelId: process.env.BEDROCK_TEXT_MODEL,
    contentType: <span class="hljs-string">"application/json"</span>,
    accept: <span class="hljs-string">"*/*"</span>,
    body: <span class="hljs-built_in">JSON</span>.stringify(
      {
        prompt: <span class="hljs-string">`Recommend only <span class="hljs-subst">${numberOfMeals}</span> meal(s) Which i can make only by using <span class="hljs-subst">${ingredients.join(<span class="hljs-string">','</span>)}</span>`</span>,
        maxTokens: <span class="hljs-number">200</span>,
        temperature: <span class="hljs-number">0.7</span>,
        topP: <span class="hljs-number">1</span>
      }
    )
  });
</code></pre>
<p>The trigger of the lambda function is the endpoint <code>/meals</code> (API Gateway) with the following event schema which has the list of the ingredients &amp; the needed number of meals:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">default</span> {
  <span class="hljs-keyword">type</span>: <span class="hljs-string">"object"</span>,
  properties: {
    ingredients: {<span class="hljs-keyword">type</span>: <span class="hljs-string">'string'</span>},
    count: {<span class="hljs-keyword">type</span>: <span class="hljs-string">'number'</span>}
  },
  required: [<span class="hljs-string">'ingredients'</span>, <span class="hljs-string">'count'</span>]
} <span class="hljs-keyword">as</span> <span class="hljs-keyword">const</span>;
</code></pre>
<pre><code class="lang-typescript">  events: [
    {
      http: {
        method: <span class="hljs-string">'get'</span>,
        path: <span class="hljs-string">'meals'</span>,
        request: {
          schemas: {
            <span class="hljs-string">'application/json'</span>: schema,
          },
        },
      },
    },
  ]
</code></pre>
<p>So, to wrap that up, simple the function is:</p>
<ul>
<li><p>Receiving a list of ingredients and the number of meals</p>
</li>
<li><p>Invoking the model to get some meal ideas</p>
</li>
<li><p>Responding with the ai response</p>
</li>
</ul>
<p>GitHub repo: <a target="_blank" href="https://github.com/Rochdy/mealsRecommender"><strong>https://github.com/Rochdy/mealsRecommender</strong></a></p>
<p>That was the app of Day#2! looking forward to posting soon about the next app</p>
]]></content:encoded></item><item><title><![CDATA[I wrote an AWS Lambda function to teach me Spanish]]></title><description><![CDATA[This is Day#1 of the #ServerlessChallenge, where I'm creating/building serverless apps using different AWS services.

The short description: an app sends me a WhatsApp message every day to teach me a random Spanish word with its meaning.

The long/te...]]></description><link>https://blog.roshdy.dev/i-wrote-an-aws-lambda-function-to-teach-me-spanish</link><guid isPermaLink="true">https://blog.roshdy.dev/i-wrote-an-aws-lambda-function-to-teach-me-spanish</guid><category><![CDATA[AWS]]></category><category><![CDATA[aws lambda]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[AWS EventBridge]]></category><dc:creator><![CDATA[Mohammed Roshdy]]></dc:creator><pubDate>Sun, 22 Oct 2023 21:53:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1698003644043/f5babe41-8c39-4cdf-8a9d-a425b378209b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><em>This is Day#1 of the #ServerlessChallenge, where I'm creating/building serverless apps using different AWS services.</em></p>
</blockquote>
<p><strong>The short description:</strong> an app sends me a WhatsApp message every day to teach me a random Spanish word with its meaning.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1698010595799/5c6dd7da-7708-4c7f-aaec-1d182e6740f6.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-the-longtech-description">The long/tech description</h3>
<p>Using the <a target="_blank" href="https://www.serverless.com/">serverless framework,</a> I've built a simple lambda function that is being triggered with an EventBridge rule:</p>
<pre><code class="lang-typescript">events: [
  {
    schedule: {
      rate: [<span class="hljs-string">"rate(1 day)"</span>]
    }
  }
]
</code></pre>
<p>EventBridge rules are so simple and interesting to write, as example if you want to write a rule that triggers an event on only the work days at 9 am, it will be like this: <code>cron(0 9 ? MON-FRI )</code></p>
<p>The lambda function is so small, what it does:</p>
<ul>
<li><p>Getting a random Spanish word using <a target="_blank" href="https://www.npmjs.com/package/@paunovic/random-words">paunovic/random-words</a></p>
</li>
<li><p>Translate this word using <a target="_blank" href="https://www.npmjs.com/package/bing-translate-api">bing-translate-api</a></p>
</li>
<li><p>Send a good-formatted WhatsApp every day with the word and its translation using <a target="_blank" href="https://www.twilio.com/en-us">Twilio</a></p>
</li>
</ul>
<pre><code class="lang-typescript">        <span class="hljs-comment">// src/functions/teach/index.ts</span>

        <span class="hljs-keyword">const</span> word = RANDOM.word();
        <span class="hljs-keyword">const</span> translation = <span class="hljs-keyword">await</span> translate(word, 
            <span class="hljs-string">'process.env.LANGUAGE_TO'</span>,
            <span class="hljs-string">'process.env.LANGUAGE_FROM'</span>
        );
        <span class="hljs-keyword">const</span> message = {
            <span class="hljs-keyword">from</span>: <span class="hljs-string">`whatsapp:<span class="hljs-subst">${process.env.TWILIO_SENDER}</span>`</span>,
            body: <span class="hljs-string">`Hola! 🙋 \n
                   Today's word is: *<span class="hljs-subst">${translation.text}</span>* \n
                   Which means: *<span class="hljs-subst">${translation.translation}</span>*`</span>,
            to: <span class="hljs-string">`whatsapp:<span class="hljs-subst">${process.env.TWILIO_RECEIVER}</span>`</span>
        };

        <span class="hljs-keyword">await</span> client.messages.create(message);
</code></pre>
<p>And as my favorite song says: ♫ Don't place the API key/secrets &amp; configs in the code directly, my friend ♫</p>
<p>You can safely store any keys/secrets/configs inside the serverless configuration <code>provider.environment</code> and they will be added as env variables for the lambda function<s><br /></s></p>
<pre><code class="lang-typescript"><span class="hljs-comment">// serverless.ts</span>
<span class="hljs-keyword">const</span> serverlessConfiguration: AWS = {
  <span class="hljs-comment">//..</span>
  provider: {
    environment: {
      TWILIO_ACCOUNT_SID: <span class="hljs-string">'xx'</span>,
      TWILIO_AUTH_TOKEN: <span class="hljs-string">'xx'</span>,
      TWILIO_SENDER: <span class="hljs-string">'xx'</span>,
      TWILIO_RECEIVER: <span class="hljs-string">'xx'</span>,
      LANGUAGE_TO: <span class="hljs-string">'es'</span>,
      LANGUAGE_FROM: <span class="hljs-string">'en'</span>
    },
  },
}
</code></pre>
<p>the github repo: <a target="_blank" href="https://github.com/Rochdy/teachMeSpanish">https://github.com/Rochdy/teachMeSpanish</a></p>
<p>That was the app of Day#1! looking forward to posting soon about the next app of the challenge.</p>
]]></content:encoded></item></channel></rss>