With work and private life blending more than ever, managing an overflowing inbox can be overwhelming. But what if a tool could draft replies for you, only needing your review? Meet AutoResponder AI: a serverless email assistant on AWS that uses AI to streamline communication. This article will break down how it works and how it can make handling emails easier. What is AutoResponder AI? AutoResponder AI is an intelligent Gmail add-on that can help you manage emails and prevent inbox overload. It scans unread emails, detects sentiment, and drafts replies for those that need a response, saving them for your review. Once drafts are ready, it notifies you via email or SMS, keeping you updated. Built on a secure, cost-effective serverless system, it's ideal for busy professionals, customer service teams, or anyone who wants to stay responsive with less hassle. Why AutoResponder AI? Boosts Productivity – Automates responses for unread emails, saving time and effort. Optimizes Time Management – Uses AI to prioritize and generate context-aware replies. Ensures Security – Protects credentials with AWS Secrets Manager. Improves Communication – Crafts professional, well-structured replies tailored to each recipient. AutoResponder AI is useful for business professionals, executives, sales teams, and customer service departments because it brings the might of AI-driven automation to your inbox management effort. Step-by-Step Guide to Develop and Deploy AutoResponder AI #Step 1: Get Gmail OAuth Credentials from Google Console To access Gmail via API, you need OAuth credentials from Google Cloud Console. Create a Google Cloud Project Open the Google Cloud Console website -> Select New Project -> You may name it GmailAutoReply or whatever you choose -> Click on Create. Enable Gmail API Go to APIs & Services. Enable APIs and Services, search for Gmail API and enable it. Create OAuth Credentials Navigate to APIs & Services -> Credentials -> Create Credentials -> OAuth client ID. Choose the Application type: Desktop app and name it Lambda Gmail Client. Click on Create and download client_secret_xxx.json file. Generate Access and Refresh Tokens: Make sure you have the right Python libraries installed on your local machine:: pip install google-auth-oauthlib google-api-python-client Use the following Python script to generate tokens (replace 'path/to/your/client_secret.json' with the path to your downloaded JSON file): Run this Python script to generate access and refresh tokens: from google_auth_oauthlib.flow import InstalledAppFlow scopes = ['https://mail.google.com/'] flow = InstalledAppFlow.from_client_secrets_file( 'path/to/your/client_secret.json', scopes) credentials = flow.run_local_server(port=0) print(f"Access Token: {credentials.token}") print(f"Refresh Token: {credentials.refresh_token}") When you run the script, It will ask you to log in to your Gmail account and authorize the app in a browser window after running the script. Copy the access_token and refresh_token for later use. Step 2: Store Gmail OAuth Credentials in AWS Secrets Manager To store Gmail credentials securely, use AWS Secrets Manager. To do this, follow these steps: Go to AWS Console and select Secrets Manager. Click on Store a new secret and select Choose Other Type of secret. Copy and paste the following key-value pairs: gmail_client_id (from client_secret.json) gmail_client_secret (from client_secret.json) access_token (from the Python script) refresh_token (from the Python script) Click Next, enter the secret name as GmailOAuthSecrets and click on Store. Remember the Secret ARN which will be used in Lambda. Step 3: Create an SNS Topic for Notifications To notify users when email drafts are created, set up Amazon SNS. To do this, follow these steps: Go to AWS Console and select SNS from the search bar. Choose Standard and then click Create topic. The name of the new topic is EmailDraftsCreated and click Create topic. The Topic ARN is copied for later use. Click Create Subscription, select Protocol and then select Email, and then enter your email and confirm. Step 4: Create an IAM Role for Lambda For Lambda to work, it requires permission to work with other AWS services. Go to AWS Console and select IAM from the search. Click on Roles and select Create role, then choose AWS Service and then Lambda. Attach the following policies: AWSLambdaBasicExecutionRole (for logging) AmazonSNSFullAccess (for notifications) SecretsManagerReadWrite (for storing Gmail credentials) AmazonComprehendFullAccess (for sentiment analysis) AmazonBedrockFullAccess (For AI generated replies) The role is named as LambdaEmailProcessor and then click create role. Step 5: Prepare Amazon Amazon Bedrock for the AI Response First check that Amazon Bedrock is turned on in us-east-1 region. Go to Amazon Bedrock in the AWS Console. In Model Access, enable Amazon Titan Text G1 - Premier or any other model you prefer. Accept the access request. Step 6: Create and Deploy the AWS Lambda Function This Lambda function will process emails, analyze sentiment, generate replies, and save drafts. Navigate to AWS Console; select Lambda from search and Create Function. Choose Author from Scratch, name it "EmailAutoReplyProcessor" and select Python 3.9. Assign the IAM role “LambdaEmailProcessor". Install required dependencies: pip install boto3 google-auth-oauthlib google-auth-httplib2 google-api-python-client -t lambda_package/ Save the Lambda code (provided below) as lambda_package/lambda_function.py. import json import os import boto3 from google.oauth2.credentials import Credentials from googleapiclient.discovery import build from google.auth.transport.requests import Request import base64 import re from googleapiclient.errors import HttpError # AWS Clients secrets_manager = boto3.client('secretsmanager') comprehend = boto3.client('comprehend') bedrock = boto3.client('bedrock-runtime') sns = boto3.client('sns') def extract_sender_name(sender_email): """ Extracts the sender's name from the email 'From' field. Example: - 'John Doe <john.doe@example.com>' → 'John Doe' - 'john.doe@example.com' → 'John' """ match = re.match(r'(.+?)\s*<.*?>', sender_email) if match: return match.group(1).strip() # Extract name from 'John Doe <email>' else: return sender_email.split('@')[0].capitalize() # Fallback: Extract name from 'email@domain.com' def lambda_handler(event, context): try: # Retrieve OAuth credentials from AWS Secrets Manager secret_arn = os.environ['SECRET_ARN'] secret = secrets_manager.get_secret_value(SecretId=secret_arn) secret_json = json.loads(secret['SecretString']) creds = Credentials( token=secret_json.get('access_token'), refresh_token=secret_json['refresh_token'], client_id=secret_json['gmail_client_id'], client_secret=secret_json['gmail_client_secret'], token_uri='https://oauth2.googleapis.com/token' ) if creds.expired and creds.refresh_token: print("Refreshing token...") creds.refresh(Request()) secret_json['access_token'] = creds.token secrets_manager.put_secret_value(SecretId=secret_arn, SecretString=json.dumps(secret_json)) print("Token refreshed") # Build Gmail API client service = build('gmail', 'v1', credentials=creds) print("Gmail API client built") # Fetch unread emails results = service.users().messages().list(userId='me', labelIds=['UNREAD']).execute() messages = results.get('messages', []) print(f"Found {len(messages)} unread emails") if not messages: print("No unread emails found.") return {'statusCode': 200, 'body': 'No unread emails'} drafts_created = 0 for msg in messages: message = service.users().messages().get(userId='me', id=msg['id'], format='full').execute() headers = {h['name']: h['value'] for h in message['payload']['headers']} subject = headers.get('Subject', 'No Subject') sender = headers.get('From', 'Unknown Sender') # Extract sender's name sender_name = extract_sender_name(sender) print(f"Extracted sender name: {sender_name}") body_data = message['payload'].get('body', {}).get('data', '') text = base64.urlsafe_b64decode(body_data).decode('utf-8', errors='ignore') if body_data else message.get('snippet', '') print(f"Processing email from {sender}: {subject}") print(f"Email content: {text}") # Perform Sentiment Analysis sentiment_response = comprehend.detect_sentiment(Text=text[:5000], LanguageCode='en') sentiment = sentiment_response['Sentiment'] print(f"Sentiment: {sentiment}") if sentiment in ['POSITIVE', 'NEGATIVE']: # Enhanced AI Prompt for Titan Model prompt = f""" You are an AI email assistant drafting a professional reply to an unread email received by the user. You are replying as the recipient of the email to the sender, whose name is '{sender_name}'. **Rules:** - Maintain a **formal and professional tone**. - Address the sender’s intent directly (e.g., respond to offers or questions). - Do not include a greeting (e.g., 'Dear {sender_name}') or closing (e.g., 'Best regards')—focus only on the response body. - Do not copy the sender’s words; write an original response. - Adapt tone based on sentiment: - If positive, keep it warm and appreciative. - If negative, be empathetic and professional. - Confirm interest in opportunities and ask about next steps if applicable. **Email Received:** From: {sender} Subject: {subject} Content: --- {text[:1000]} --- **Draft the response body:** """ try: # Invoke Amazon Bedrock bedrock_response = bedrock.invoke_model( modelId='amazon.titan-text-lite-v1', body=json.dumps({ "inputText": prompt, "textGenerationConfig": { "maxTokenCount": 300, "temperature": 0.5, "topP": 0.9 } }) ) reply_body = json.loads(bedrock_response['body'].read())['results'][0]['outputText'].strip() print(f"Generated AI Reply: {reply_body}") except Exception as e: print(f"Bedrock error: {str(e)}") raise # Check for any greeting or closing in the AI response (case-insensitive) reply_body_lower = reply_body.lower() greeting_patterns = [f"dear {sender_name.lower()}", f"hello {sender_name.lower()}", f"hi {sender_name.lower()}", "dear", "hello", "hi"] closing_patterns = ["best regards", "sincerely", "kind regards", "thank you", "regards"] reply_has_greeting = any(pattern in reply_body_lower for pattern in greeting_patterns) reply_has_closing = any(pattern in reply_body_lower for pattern in closing_patterns) # Add greeting and closing only if missing if not reply_has_greeting: reply_body = f"Dear {sender_name},\n\n{reply_body}" if not reply_has_closing: reply_body += "\n\nBest regards,\nYour Name" try: # Create draft email draft_message = f"To: {sender}\nSubject: Re: {subject}\n\n{reply_body}" draft = { 'message': { 'raw': base64.urlsafe_b64encode(draft_message.encode('utf-8')).decode('utf-8') } } print(f"Creating draft: {draft_message}") service.users().drafts().create(userId='me', body=draft).execute() drafts_created += 1 print("Draft created successfully") except HttpError as e: print(f"Draft creation failed: {e}") # Send SNS Notification if drafts_created > 0: sns.publish( TopicArn=os.environ['SNS_TOPIC_ARN'], Message=f"{drafts_created} new email drafts created. Please review in Gmail." ) print("SNS notification sent") return {'statusCode': 200, 'body': f'Processed {len(messages)} emails, created {drafts_created} drafts'} except HttpError as error: print(f"Gmail API error: {error}") return {'statusCode': 500, 'body': f'Gmail API error: {error}'} except Exception as e: print(f"Error: {str(e)}") return {'statusCode': 500, 'body': f'An error occurred: {str(e)}'} Deploy the Code: Compress/ZIP the lambda_package folder: cd lambda_package zip -r ../lambda_function.zip . In the Lambda console, select the Code tab, click Upload from and select .zip file, and upload lambda_function.zip. Set Environment Variables: Go to Configuration; select Environment variables and click on Edit. Add the following values:SECRET_ARN: Your Secrets Manager ARN (from Step 2) SNS_TOPIC_ARN: Your SNS topic ARN (from Step 3) Click on save button. Set Timeout:Under Configuration, select the General configuration and click on Edit button then set the timeout to 5 minutes to accommodate processing multiple emails. Step 7: Learn To Execute The Workflow Automating Execution Using Amazon EventBridge Go to AWS Console and select EventBridge and Create Rule. Name it as Gmail-AutoReply-Schedule. For Schedule Expression, put: rate(2 hours) For Targets, choose Lambda function and select EmailAutoReplyProcessor. Click Create Rule. Step 8: Review Draft and Send Emails in Gmail Review the final outputs of AutoResponder AI in your Gmail account at the end of the process. Sign in to your Gmail account. Go to the Drafts folder. Read through each of the AI-generated drafts, make any necessary changes, and then manually send each when you are finished. What You’ve Built These steps have been checked and you have successfully created AutoResponder AI, an AI-based email assistant that: It checks your Gmail inbox every two hours for new messages that are unread. Utilizes Amazon Comprehend to determine the sentiment of these emails. To edit emails that need your attention, it prepares professional replies with the help of Amazon Bedrock. It also organizes the drafts for you in Gmail. It informs you through Amazon SNS when there are new drafts. This is a secure, cost-effective, and fully customizable serverless solution. Get a better and more efficient way of working with emails with AutoResponder AI! Enjoy! With work and private life blending more than ever, managing an overflowing inbox can be overwhelming. But what if a tool could draft replies for you, only needing your review? Meet AutoResponder AI: a serverless email assistant on AWS that uses AI to streamline communication. This article will break down how it works and how it can make handling emails easier. What is AutoResponder AI? What is AutoResponder AI? AutoResponder AI is an intelligent Gmail add-on that can help you manage emails and prevent inbox overload. It scans unread emails, detects sentiment, and drafts replies for those that need a response, saving them for your review. Once drafts are ready, it notifies you via email or SMS, keeping you updated. Built on a secure, cost-effective serverless system, it's ideal for busy professionals, customer service teams, or anyone who wants to stay responsive with less hassle. Why AutoResponder AI? Why AutoResponder AI? Boosts Productivity – Automates responses for unread emails, saving time and effort. Optimizes Time Management – Uses AI to prioritize and generate context-aware replies. Ensures Security – Protects credentials with AWS Secrets Manager. Improves Communication – Crafts professional, well-structured replies tailored to each recipient. Boosts Productivity – Automates responses for unread emails, saving time and effort. Boosts Productivity Optimizes Time Management – Uses AI to prioritize and generate context-aware replies. Optimizes Time Management Ensures Security – Protects credentials with AWS Secrets Manager. Ensures Security Improves Communication – Crafts professional, well-structured replies tailored to each recipient. Improves Communication AutoResponder AI is useful for business professionals, executives, sales teams, and customer service departments because it brings the might of AI-driven automation to your inbox management effort. Step-by-Step Guide to Develop and Deploy AutoResponder AI Step-by-Step Guide to Develop and Deploy AutoResponder AI #Step 1: Get Gmail OAuth Credentials from Google Console #Step 1: Get Gmail OAuth Credentials from Google Console To access Gmail via API, you need OAuth credentials from Google Cloud Console. Create a Google Cloud Project Open the Google Cloud Console website -> Select New Project -> You may name it GmailAutoReply or whatever you choose -> Click on Create. Enable Gmail API Go to APIs & Services. Enable APIs and Services, search for Gmail API and enable it. Create OAuth Credentials Navigate to APIs & Services -> Credentials -> Create Credentials -> OAuth client ID. Choose the Application type: Desktop app and name it Lambda Gmail Client. Click on Create and download client_secret_xxx.json file. Generate Access and Refresh Tokens: Make sure you have the right Python libraries installed on your local machine:: pip install google-auth-oauthlib google-api-python-client Use the following Python script to generate tokens (replace 'path/to/your/client_secret.json' with the path to your downloaded JSON file): Run this Python script to generate access and refresh tokens: from google_auth_oauthlib.flow import InstalledAppFlow scopes = ['https://mail.google.com/'] flow = InstalledAppFlow.from_client_secrets_file( 'path/to/your/client_secret.json', scopes) credentials = flow.run_local_server(port=0) print(f"Access Token: {credentials.token}") print(f"Refresh Token: {credentials.refresh_token}") When you run the script, It will ask you to log in to your Gmail account and authorize the app in a browser window after running the script. Copy the access_token and refresh_token for later use. Create a Google Cloud Project Open the Google Cloud Console website -> Select New Project -> You may name it GmailAutoReply or whatever you choose -> Click on Create. Create a Google Cloud Project Open the Google Cloud Console website -> Select New Project -> You may name it GmailAutoReply or whatever you choose -> Click on Create. Open the Google Cloud Console website -> Select New Project -> You may name it GmailAutoReply or whatever you choose -> Click on Create. Open the Google Cloud Console website -> Select New Project -> You may name it GmailAutoReply or whatever you choose -> Click on Create. Enable Gmail API Go to APIs & Services. Enable APIs and Services, search for Gmail API and enable it. Enable Gmail API Go to APIs & Services. Enable APIs and Services, search for Gmail API and enable it. Go to APIs & Services. Go to APIs & Services. Enable APIs and Services, search for Gmail API and enable it. Enable APIs and Services, search for Gmail API and enable it. Create OAuth Credentials Navigate to APIs & Services -> Credentials -> Create Credentials -> OAuth client ID. Choose the Application type: Desktop app and name it Lambda Gmail Client. Click on Create and download client_secret_xxx.json file. Create OAuth Credentials Navigate to APIs & Services -> Credentials -> Create Credentials -> OAuth client ID. Choose the Application type: Desktop app and name it Lambda Gmail Client. Click on Create and download client_secret_xxx.json file. Navigate to APIs & Services -> Credentials -> Create Credentials -> OAuth client ID. Navigate to APIs & Services -> Credentials -> Create Credentials -> OAuth client ID. Choose the Application type: Desktop app and name it Lambda Gmail Client. Choose the Application type: Desktop app and name it Lambda Gmail Client . Lambda Gmail Client Click on Create and download client_secret_xxx.json file. Click on Create and download client_secret_xxx.json file. client_secret_xxx.json Generate Access and Refresh Tokens: Make sure you have the right Python libraries installed on your local machine:: pip install google-auth-oauthlib google-api-python-client Use the following Python script to generate tokens (replace 'path/to/your/client_secret.json' with the path to your downloaded JSON file): Run this Python script to generate access and refresh tokens: from google_auth_oauthlib.flow import InstalledAppFlow scopes = ['https://mail.google.com/'] flow = InstalledAppFlow.from_client_secrets_file( 'path/to/your/client_secret.json', scopes) credentials = flow.run_local_server(port=0) print(f"Access Token: {credentials.token}") print(f"Refresh Token: {credentials.refresh_token}") When you run the script, It will ask you to log in to your Gmail account and authorize the app in a browser window after running the script. Copy the access_token and refresh_token for later use. Generate Access and Refresh Tokens: Make sure you have the right Python libraries installed on your local machine:: pip install google-auth-oauthlib google-api-python-client Use the following Python script to generate tokens (replace 'path/to/your/client_secret.json' with the path to your downloaded JSON file): Run this Python script to generate access and refresh tokens: from google_auth_oauthlib.flow import InstalledAppFlow scopes = ['https://mail.google.com/'] flow = InstalledAppFlow.from_client_secrets_file( 'path/to/your/client_secret.json', scopes) credentials = flow.run_local_server(port=0) print(f"Access Token: {credentials.token}") print(f"Refresh Token: {credentials.refresh_token}") When you run the script, It will ask you to log in to your Gmail account and authorize the app in a browser window after running the script. Copy the access_token and refresh_token for later use. Make sure you have the right Python libraries installed on your local machine:: pip install google-auth-oauthlib google-api-python-client Make sure you have the right Python libraries installed on your local machine:: pip install google-auth-oauthlib google-api-python-client pip install google-auth-oauthlib google-api-python-client Use the following Python script to generate tokens (replace 'path/to/your/client_secret.json' with the path to your downloaded JSON file): Use the following Python script to generate tokens (replace 'path/to/your/client_secret.json' with the path to your downloaded JSON file): Run this Python script to generate access and refresh tokens: from google_auth_oauthlib.flow import InstalledAppFlow scopes = ['https://mail.google.com/'] flow = InstalledAppFlow.from_client_secrets_file( 'path/to/your/client_secret.json', scopes) credentials = flow.run_local_server(port=0) print(f"Access Token: {credentials.token}") print(f"Refresh Token: {credentials.refresh_token}") Run this Python script to generate access and refresh tokens: from google_auth_oauthlib.flow import InstalledAppFlow scopes = ['https://mail.google.com/'] flow = InstalledAppFlow.from_client_secrets_file( 'path/to/your/client_secret.json', scopes) credentials = flow.run_local_server(port=0) print(f"Access Token: {credentials.token}") print(f"Refresh Token: {credentials.refresh_token}") from google_auth_oauthlib.flow import InstalledAppFlow scopes = ['https://mail.google.com/'] flow = InstalledAppFlow.from_client_secrets_file( 'path/to/your/client_secret.json', scopes) credentials = flow.run_local_server(port=0) print(f"Access Token: {credentials.token}") print(f"Refresh Token: {credentials.refresh_token}") When you run the script, It will ask you to log in to your Gmail account and authorize the app in a browser window after running the script. When you run the script, It will ask you to log in to your Gmail account and authorize the app in a browser window after running the script. Copy the access_token and refresh_token for later use. Copy the access_token and refresh_token for later use. Step 2: Store Gmail OAuth Credentials in AWS Secrets Manager Step 2: To store Gmail credentials securely, use AWS Secrets Manager. To do this, follow these steps: To store Gmail credentials securely, use AWS Secrets Manager. To do this, follow these steps: Go to AWS Console and select Secrets Manager. Click on Store a new secret and select Choose Other Type of secret. Copy and paste the following key-value pairs: gmail_client_id (from client_secret.json) gmail_client_secret (from client_secret.json) access_token (from the Python script) refresh_token (from the Python script) Click Next, enter the secret name as GmailOAuthSecrets and click on Store. Remember the Secret ARN which will be used in Lambda. Go to AWS Console and select Secrets Manager. Go to AWS Console and select Secrets Manager. Click on Store a new secret and select Choose Other Type of secret. Click on Store a new secret and select Choose Other Type of secret. Copy and paste the following key-value pairs: gmail_client_id (from client_secret.json) gmail_client_secret (from client_secret.json) access_token (from the Python script) refresh_token (from the Python script) Copy and paste the following key-value pairs: gmail_client_id (from client_secret.json) gmail_client_secret (from client_secret.json) access_token (from the Python script) refresh_token (from the Python script) gmail_client_id (from client_secret.json) gmail_client_secret (from client_secret.json) access_token (from the Python script) refresh_token (from the Python script) Click Next, enter the secret name as GmailOAuthSecrets and click on Store. Click Next, enter the secret name as GmailOAuthSecrets and click on Store. Remember the Secret ARN which will be used in Lambda. Remember the Secret ARN which will be used in Lambda. Step 3: Create an SNS Topic for Notifications Step 3: To notify users when email drafts are created, set up Amazon SNS. To do this, follow these steps: Go to AWS Console and select SNS from the search bar. Choose Standard and then click Create topic. The name of the new topic is EmailDraftsCreated and click Create topic. The Topic ARN is copied for later use. Click Create Subscription, select Protocol and then select Email, and then enter your email and confirm. Go to AWS Console and select SNS from the search bar. Choose Standard and then click Create topic. The name of the new topic is EmailDraftsCreated and click Create topic. EmailDraftsCreated The Topic ARN is copied for later use. Click Create Subscription, select Protocol and then select Email, and then enter your email and confirm. Step 4: Step 4: Create an IAM Role for Lambda For Lambda to work, it requires permission to work with other AWS services. Go to AWS Console and select IAM from the search. Click on Roles and select Create role, then choose AWS Service and then Lambda. Attach the following policies: AWSLambdaBasicExecutionRole (for logging) AmazonSNSFullAccess (for notifications) SecretsManagerReadWrite (for storing Gmail credentials) AmazonComprehendFullAccess (for sentiment analysis) AmazonBedrockFullAccess (For AI generated replies) The role is named as LambdaEmailProcessor and then click create role. Go to AWS Console and select IAM from the search. Go to AWS Console and select IAM from the search. Click on Roles and select Create role, then choose AWS Service and then Lambda. Click on Roles and select Create role, then choose AWS Service and then Lambda. Attach the following policies: AWSLambdaBasicExecutionRole (for logging) AmazonSNSFullAccess (for notifications) SecretsManagerReadWrite (for storing Gmail credentials) AmazonComprehendFullAccess (for sentiment analysis) AmazonBedrockFullAccess (For AI generated replies) Attach the following policies: AWSLambdaBasicExecutionRole (for logging) AmazonSNSFullAccess (for notifications) SecretsManagerReadWrite (for storing Gmail credentials) AmazonComprehendFullAccess (for sentiment analysis) AmazonBedrockFullAccess (For AI generated replies) AWSLambdaBasicExecutionRole (for logging) AmazonSNSFullAccess (for notifications) SecretsManagerReadWrite (for storing Gmail credentials) AmazonComprehendFullAccess (for sentiment analysis) AmazonBedrockFullAccess (For AI generated replies) The role is named as LambdaEmailProcessor and then click create role. The role is named as LambdaEmailProcessor and then click create role. Step 5: Prepare Amazon Amazon Bedrock for the AI Response Step 5: Prepare Amazon Amazon Bedrock for the AI Response First check that Amazon Bedrock is turned on in us-east-1 region. Go to Amazon Bedrock in the AWS Console. In Model Access, enable Amazon Titan Text G1 - Premier or any other model you prefer. Accept the access request. Go to Amazon Bedrock in the AWS Console. Go to Amazon Bedrock in the AWS Console. In Model Access, enable Amazon Titan Text G1 - Premier or any other model you prefer. In Model Access, enable Amazon Titan Text G1 - Premier or any other model you prefer. Accept the access request. Accept the access request. Step 6: Create and Deploy the AWS Lambda Function Step 6: Create and Deploy the AWS Lambda Function This Lambda function will process emails, analyze sentiment, generate replies, and save drafts. Navigate to AWS Console; select Lambda from search and Create Function. Choose Author from Scratch, name it "EmailAutoReplyProcessor" and select Python 3.9. Assign the IAM role “LambdaEmailProcessor". Install required dependencies: Navigate to AWS Console; select Lambda from search and Create Function. Choose Author from Scratch, name it "EmailAutoReplyProcessor" and select Python 3.9. Assign the IAM role “LambdaEmailProcessor". Install required dependencies: pip install boto3 google-auth-oauthlib google-auth-httplib2 google-api-python-client -t lambda_package/ pip install boto3 google-auth-oauthlib google-auth-httplib2 google-api-python-client -t lambda_package/ Save the Lambda code (provided below) as lambda_package/lambda_function.py. import json import os import boto3 from google.oauth2.credentials import Credentials from googleapiclient.discovery import build from google.auth.transport.requests import Request import base64 import re from googleapiclient.errors import HttpError # AWS Clients secrets_manager = boto3.client('secretsmanager') comprehend = boto3.client('comprehend') bedrock = boto3.client('bedrock-runtime') sns = boto3.client('sns') def extract_sender_name(sender_email): """ Extracts the sender's name from the email 'From' field. Example: - 'John Doe <john.doe@example.com>' → 'John Doe' - 'john.doe@example.com' → 'John' """ match = re.match(r'(.+?)\s*<.*?>', sender_email) if match: return match.group(1).strip() # Extract name from 'John Doe <email>' else: return sender_email.split('@')[0].capitalize() # Fallback: Extract name from 'email@domain.com' def lambda_handler(event, context): try: # Retrieve OAuth credentials from AWS Secrets Manager secret_arn = os.environ['SECRET_ARN'] secret = secrets_manager.get_secret_value(SecretId=secret_arn) secret_json = json.loads(secret['SecretString']) creds = Credentials( token=secret_json.get('access_token'), refresh_token=secret_json['refresh_token'], client_id=secret_json['gmail_client_id'], client_secret=secret_json['gmail_client_secret'], token_uri='https://oauth2.googleapis.com/token' ) if creds.expired and creds.refresh_token: print("Refreshing token...") creds.refresh(Request()) secret_json['access_token'] = creds.token secrets_manager.put_secret_value(SecretId=secret_arn, SecretString=json.dumps(secret_json)) print("Token refreshed") # Build Gmail API client service = build('gmail', 'v1', credentials=creds) print("Gmail API client built") # Fetch unread emails results = service.users().messages().list(userId='me', labelIds=['UNREAD']).execute() messages = results.get('messages', []) print(f"Found {len(messages)} unread emails") if not messages: print("No unread emails found.") return {'statusCode': 200, 'body': 'No unread emails'} drafts_created = 0 for msg in messages: message = service.users().messages().get(userId='me', id=msg['id'], format='full').execute() headers = {h['name']: h['value'] for h in message['payload']['headers']} subject = headers.get('Subject', 'No Subject') sender = headers.get('From', 'Unknown Sender') # Extract sender's name sender_name = extract_sender_name(sender) print(f"Extracted sender name: {sender_name}") body_data = message['payload'].get('body', {}).get('data', '') text = base64.urlsafe_b64decode(body_data).decode('utf-8', errors='ignore') if body_data else message.get('snippet', '') print(f"Processing email from {sender}: {subject}") print(f"Email content: {text}") # Perform Sentiment Analysis sentiment_response = comprehend.detect_sentiment(Text=text[:5000], LanguageCode='en') sentiment = sentiment_response['Sentiment'] print(f"Sentiment: {sentiment}") if sentiment in ['POSITIVE', 'NEGATIVE']: # Enhanced AI Prompt for Titan Model prompt = f""" You are an AI email assistant drafting a professional reply to an unread email received by the user. You are replying as the recipient of the email to the sender, whose name is '{sender_name}'. **Rules:** - Maintain a **formal and professional tone**. - Address the sender’s intent directly (e.g., respond to offers or questions). - Do not include a greeting (e.g., 'Dear {sender_name}') or closing (e.g., 'Best regards')—focus only on the response body. - Do not copy the sender’s words; write an original response. - Adapt tone based on sentiment: - If positive, keep it warm and appreciative. - If negative, be empathetic and professional. - Confirm interest in opportunities and ask about next steps if applicable. **Email Received:** From: {sender} Subject: {subject} Content: --- {text[:1000]} --- **Draft the response body:** """ try: # Invoke Amazon Bedrock bedrock_response = bedrock.invoke_model( modelId='amazon.titan-text-lite-v1', body=json.dumps({ "inputText": prompt, "textGenerationConfig": { "maxTokenCount": 300, "temperature": 0.5, "topP": 0.9 } }) ) reply_body = json.loads(bedrock_response['body'].read())['results'][0]['outputText'].strip() print(f"Generated AI Reply: {reply_body}") except Exception as e: print(f"Bedrock error: {str(e)}") raise # Check for any greeting or closing in the AI response (case-insensitive) reply_body_lower = reply_body.lower() greeting_patterns = [f"dear {sender_name.lower()}", f"hello {sender_name.lower()}", f"hi {sender_name.lower()}", "dear", "hello", "hi"] closing_patterns = ["best regards", "sincerely", "kind regards", "thank you", "regards"] reply_has_greeting = any(pattern in reply_body_lower for pattern in greeting_patterns) reply_has_closing = any(pattern in reply_body_lower for pattern in closing_patterns) # Add greeting and closing only if missing if not reply_has_greeting: reply_body = f"Dear {sender_name},\n\n{reply_body}" if not reply_has_closing: reply_body += "\n\nBest regards,\nYour Name" try: # Create draft email draft_message = f"To: {sender}\nSubject: Re: {subject}\n\n{reply_body}" draft = { 'message': { 'raw': base64.urlsafe_b64encode(draft_message.encode('utf-8')).decode('utf-8') } } print(f"Creating draft: {draft_message}") service.users().drafts().create(userId='me', body=draft).execute() drafts_created += 1 print("Draft created successfully") except HttpError as e: print(f"Draft creation failed: {e}") # Send SNS Notification if drafts_created > 0: sns.publish( TopicArn=os.environ['SNS_TOPIC_ARN'], Message=f"{drafts_created} new email drafts created. Please review in Gmail." ) print("SNS notification sent") return {'statusCode': 200, 'body': f'Processed {len(messages)} emails, created {drafts_created} drafts'} except HttpError as error: print(f"Gmail API error: {error}") return {'statusCode': 500, 'body': f'Gmail API error: {error}'} except Exception as e: print(f"Error: {str(e)}") return {'statusCode': 500, 'body': f'An error occurred: {str(e)}'} Deploy the Code: Compress/ZIP the lambda_package folder: cd lambda_package zip -r ../lambda_function.zip . In the Lambda console, select the Code tab, click Upload from and select .zip file, and upload lambda_function.zip. Set Environment Variables: Go to Configuration; select Environment variables and click on Edit. Add the following values:SECRET_ARN: Your Secrets Manager ARN (from Step 2) SNS_TOPIC_ARN: Your SNS topic ARN (from Step 3) Click on save button. Set Timeout:Under Configuration, select the General configuration and click on Edit button then set the timeout to 5 minutes to accommodate processing multiple emails. Save the Lambda code (provided below) as lambda_package/lambda_function.py. import json import os import boto3 from google.oauth2.credentials import Credentials from googleapiclient.discovery import build from google.auth.transport.requests import Request import base64 import re from googleapiclient.errors import HttpError # AWS Clients secrets_manager = boto3.client('secretsmanager') comprehend = boto3.client('comprehend') bedrock = boto3.client('bedrock-runtime') sns = boto3.client('sns') def extract_sender_name(sender_email): """ Extracts the sender's name from the email 'From' field. Example: - 'John Doe <john.doe@example.com>' → 'John Doe' - 'john.doe@example.com' → 'John' """ match = re.match(r'(.+?)\s*<.*?>', sender_email) if match: return match.group(1).strip() # Extract name from 'John Doe <email>' else: return sender_email.split('@')[0].capitalize() # Fallback: Extract name from 'email@domain.com' def lambda_handler(event, context): try: # Retrieve OAuth credentials from AWS Secrets Manager secret_arn = os.environ['SECRET_ARN'] secret = secrets_manager.get_secret_value(SecretId=secret_arn) secret_json = json.loads(secret['SecretString']) creds = Credentials( token=secret_json.get('access_token'), refresh_token=secret_json['refresh_token'], client_id=secret_json['gmail_client_id'], client_secret=secret_json['gmail_client_secret'], token_uri='https://oauth2.googleapis.com/token' ) if creds.expired and creds.refresh_token: print("Refreshing token...") creds.refresh(Request()) secret_json['access_token'] = creds.token secrets_manager.put_secret_value(SecretId=secret_arn, SecretString=json.dumps(secret_json)) print("Token refreshed") # Build Gmail API client service = build('gmail', 'v1', credentials=creds) print("Gmail API client built") # Fetch unread emails results = service.users().messages().list(userId='me', labelIds=['UNREAD']).execute() messages = results.get('messages', []) print(f"Found {len(messages)} unread emails") if not messages: print("No unread emails found.") return {'statusCode': 200, 'body': 'No unread emails'} drafts_created = 0 for msg in messages: message = service.users().messages().get(userId='me', id=msg['id'], format='full').execute() headers = {h['name']: h['value'] for h in message['payload']['headers']} subject = headers.get('Subject', 'No Subject') sender = headers.get('From', 'Unknown Sender') # Extract sender's name sender_name = extract_sender_name(sender) print(f"Extracted sender name: {sender_name}") body_data = message['payload'].get('body', {}).get('data', '') text = base64.urlsafe_b64decode(body_data).decode('utf-8', errors='ignore') if body_data else message.get('snippet', '') print(f"Processing email from {sender}: {subject}") print(f"Email content: {text}") # Perform Sentiment Analysis sentiment_response = comprehend.detect_sentiment(Text=text[:5000], LanguageCode='en') sentiment = sentiment_response['Sentiment'] print(f"Sentiment: {sentiment}") if sentiment in ['POSITIVE', 'NEGATIVE']: # Enhanced AI Prompt for Titan Model prompt = f""" You are an AI email assistant drafting a professional reply to an unread email received by the user. You are replying as the recipient of the email to the sender, whose name is '{sender_name}'. **Rules:** - Maintain a **formal and professional tone**. - Address the sender’s intent directly (e.g., respond to offers or questions). - Do not include a greeting (e.g., 'Dear {sender_name}') or closing (e.g., 'Best regards')—focus only on the response body. - Do not copy the sender’s words; write an original response. - Adapt tone based on sentiment: - If positive, keep it warm and appreciative. - If negative, be empathetic and professional. - Confirm interest in opportunities and ask about next steps if applicable. **Email Received:** From: {sender} Subject: {subject} Content: --- {text[:1000]} --- **Draft the response body:** """ try: # Invoke Amazon Bedrock bedrock_response = bedrock.invoke_model( modelId='amazon.titan-text-lite-v1', body=json.dumps({ "inputText": prompt, "textGenerationConfig": { "maxTokenCount": 300, "temperature": 0.5, "topP": 0.9 } }) ) reply_body = json.loads(bedrock_response['body'].read())['results'][0]['outputText'].strip() print(f"Generated AI Reply: {reply_body}") except Exception as e: print(f"Bedrock error: {str(e)}") raise # Check for any greeting or closing in the AI response (case-insensitive) reply_body_lower = reply_body.lower() greeting_patterns = [f"dear {sender_name.lower()}", f"hello {sender_name.lower()}", f"hi {sender_name.lower()}", "dear", "hello", "hi"] closing_patterns = ["best regards", "sincerely", "kind regards", "thank you", "regards"] reply_has_greeting = any(pattern in reply_body_lower for pattern in greeting_patterns) reply_has_closing = any(pattern in reply_body_lower for pattern in closing_patterns) # Add greeting and closing only if missing if not reply_has_greeting: reply_body = f"Dear {sender_name},\n\n{reply_body}" if not reply_has_closing: reply_body += "\n\nBest regards,\nYour Name" try: # Create draft email draft_message = f"To: {sender}\nSubject: Re: {subject}\n\n{reply_body}" draft = { 'message': { 'raw': base64.urlsafe_b64encode(draft_message.encode('utf-8')).decode('utf-8') } } print(f"Creating draft: {draft_message}") service.users().drafts().create(userId='me', body=draft).execute() drafts_created += 1 print("Draft created successfully") except HttpError as e: print(f"Draft creation failed: {e}") # Send SNS Notification if drafts_created > 0: sns.publish( TopicArn=os.environ['SNS_TOPIC_ARN'], Message=f"{drafts_created} new email drafts created. Please review in Gmail." ) print("SNS notification sent") return {'statusCode': 200, 'body': f'Processed {len(messages)} emails, created {drafts_created} drafts'} except HttpError as error: print(f"Gmail API error: {error}") return {'statusCode': 500, 'body': f'Gmail API error: {error}'} except Exception as e: print(f"Error: {str(e)}") return {'statusCode': 500, 'body': f'An error occurred: {str(e)}'} Save the Lambda code (provided below) as lambda_package/lambda_function.py. import json import os import boto3 from google.oauth2.credentials import Credentials from googleapiclient.discovery import build from google.auth.transport.requests import Request import base64 import re from googleapiclient.errors import HttpError # AWS Clients secrets_manager = boto3.client('secretsmanager') comprehend = boto3.client('comprehend') bedrock = boto3.client('bedrock-runtime') sns = boto3.client('sns') def extract_sender_name(sender_email): """ Extracts the sender's name from the email 'From' field. Example: - 'John Doe <john.doe@example.com>' → 'John Doe' - 'john.doe@example.com' → 'John' """ match = re.match(r'(.+?)\s*<.*?>', sender_email) if match: return match.group(1).strip() # Extract name from 'John Doe <email>' else: return sender_email.split('@')[0].capitalize() # Fallback: Extract name from 'email@domain.com' def lambda_handler(event, context): try: # Retrieve OAuth credentials from AWS Secrets Manager secret_arn = os.environ['SECRET_ARN'] secret = secrets_manager.get_secret_value(SecretId=secret_arn) secret_json = json.loads(secret['SecretString']) creds = Credentials( token=secret_json.get('access_token'), refresh_token=secret_json['refresh_token'], client_id=secret_json['gmail_client_id'], client_secret=secret_json['gmail_client_secret'], token_uri='https://oauth2.googleapis.com/token' ) if creds.expired and creds.refresh_token: print("Refreshing token...") creds.refresh(Request()) secret_json['access_token'] = creds.token secrets_manager.put_secret_value(SecretId=secret_arn, SecretString=json.dumps(secret_json)) print("Token refreshed") # Build Gmail API client service = build('gmail', 'v1', credentials=creds) print("Gmail API client built") # Fetch unread emails results = service.users().messages().list(userId='me', labelIds=['UNREAD']).execute() messages = results.get('messages', []) print(f"Found {len(messages)} unread emails") if not messages: print("No unread emails found.") return {'statusCode': 200, 'body': 'No unread emails'} drafts_created = 0 for msg in messages: message = service.users().messages().get(userId='me', id=msg['id'], format='full').execute() headers = {h['name']: h['value'] for h in message['payload']['headers']} subject = headers.get('Subject', 'No Subject') sender = headers.get('From', 'Unknown Sender') # Extract sender's name sender_name = extract_sender_name(sender) print(f"Extracted sender name: {sender_name}") body_data = message['payload'].get('body', {}).get('data', '') text = base64.urlsafe_b64decode(body_data).decode('utf-8', errors='ignore') if body_data else message.get('snippet', '') print(f"Processing email from {sender}: {subject}") print(f"Email content: {text}") # Perform Sentiment Analysis sentiment_response = comprehend.detect_sentiment(Text=text[:5000], LanguageCode='en') sentiment = sentiment_response['Sentiment'] print(f"Sentiment: {sentiment}") if sentiment in ['POSITIVE', 'NEGATIVE']: # Enhanced AI Prompt for Titan Model prompt = f""" You are an AI email assistant drafting a professional reply to an unread email received by the user. You are replying as the recipient of the email to the sender, whose name is '{sender_name}'. **Rules:** - Maintain a **formal and professional tone**. - Address the sender’s intent directly (e.g., respond to offers or questions). - Do not include a greeting (e.g., 'Dear {sender_name}') or closing (e.g., 'Best regards')—focus only on the response body. - Do not copy the sender’s words; write an original response. - Adapt tone based on sentiment: - If positive, keep it warm and appreciative. - If negative, be empathetic and professional. - Confirm interest in opportunities and ask about next steps if applicable. **Email Received:** From: {sender} Subject: {subject} Content: --- {text[:1000]} --- **Draft the response body:** """ try: # Invoke Amazon Bedrock bedrock_response = bedrock.invoke_model( modelId='amazon.titan-text-lite-v1', body=json.dumps({ "inputText": prompt, "textGenerationConfig": { "maxTokenCount": 300, "temperature": 0.5, "topP": 0.9 } }) ) reply_body = json.loads(bedrock_response['body'].read())['results'][0]['outputText'].strip() print(f"Generated AI Reply: {reply_body}") except Exception as e: print(f"Bedrock error: {str(e)}") raise # Check for any greeting or closing in the AI response (case-insensitive) reply_body_lower = reply_body.lower() greeting_patterns = [f"dear {sender_name.lower()}", f"hello {sender_name.lower()}", f"hi {sender_name.lower()}", "dear", "hello", "hi"] closing_patterns = ["best regards", "sincerely", "kind regards", "thank you", "regards"] reply_has_greeting = any(pattern in reply_body_lower for pattern in greeting_patterns) reply_has_closing = any(pattern in reply_body_lower for pattern in closing_patterns) # Add greeting and closing only if missing if not reply_has_greeting: reply_body = f"Dear {sender_name},\n\n{reply_body}" if not reply_has_closing: reply_body += "\n\nBest regards,\nYour Name" try: # Create draft email draft_message = f"To: {sender}\nSubject: Re: {subject}\n\n{reply_body}" draft = { 'message': { 'raw': base64.urlsafe_b64encode(draft_message.encode('utf-8')).decode('utf-8') } } print(f"Creating draft: {draft_message}") service.users().drafts().create(userId='me', body=draft).execute() drafts_created += 1 print("Draft created successfully") except HttpError as e: print(f"Draft creation failed: {e}") # Send SNS Notification if drafts_created > 0: sns.publish( TopicArn=os.environ['SNS_TOPIC_ARN'], Message=f"{drafts_created} new email drafts created. Please review in Gmail." ) print("SNS notification sent") return {'statusCode': 200, 'body': f'Processed {len(messages)} emails, created {drafts_created} drafts'} except HttpError as error: print(f"Gmail API error: {error}") return {'statusCode': 500, 'body': f'Gmail API error: {error}'} except Exception as e: print(f"Error: {str(e)}") return {'statusCode': 500, 'body': f'An error occurred: {str(e)}'} import json import os import boto3 from google.oauth2.credentials import Credentials from googleapiclient.discovery import build from google.auth.transport.requests import Request import base64 import re from googleapiclient.errors import HttpError # AWS Clients secrets_manager = boto3.client('secretsmanager') comprehend = boto3.client('comprehend') bedrock = boto3.client('bedrock-runtime') sns = boto3.client('sns') def extract_sender_name(sender_email): """ Extracts the sender's name from the email 'From' field. Example: - 'John Doe <john.doe@example.com>' → 'John Doe' - 'john.doe@example.com' → 'John' """ match = re.match(r'(.+?)\s*<.*?>', sender_email) if match: return match.group(1).strip() # Extract name from 'John Doe <email>' else: return sender_email.split('@')[0].capitalize() # Fallback: Extract name from 'email@domain.com' def lambda_handler(event, context): try: # Retrieve OAuth credentials from AWS Secrets Manager secret_arn = os.environ['SECRET_ARN'] secret = secrets_manager.get_secret_value(SecretId=secret_arn) secret_json = json.loads(secret['SecretString']) creds = Credentials( token=secret_json.get('access_token'), refresh_token=secret_json['refresh_token'], client_id=secret_json['gmail_client_id'], client_secret=secret_json['gmail_client_secret'], token_uri='https://oauth2.googleapis.com/token' ) if creds.expired and creds.refresh_token: print("Refreshing token...") creds.refresh(Request()) secret_json['access_token'] = creds.token secrets_manager.put_secret_value(SecretId=secret_arn, SecretString=json.dumps(secret_json)) print("Token refreshed") # Build Gmail API client service = build('gmail', 'v1', credentials=creds) print("Gmail API client built") # Fetch unread emails results = service.users().messages().list(userId='me', labelIds=['UNREAD']).execute() messages = results.get('messages', []) print(f"Found {len(messages)} unread emails") if not messages: print("No unread emails found.") return {'statusCode': 200, 'body': 'No unread emails'} drafts_created = 0 for msg in messages: message = service.users().messages().get(userId='me', id=msg['id'], format='full').execute() headers = {h['name']: h['value'] for h in message['payload']['headers']} subject = headers.get('Subject', 'No Subject') sender = headers.get('From', 'Unknown Sender') # Extract sender's name sender_name = extract_sender_name(sender) print(f"Extracted sender name: {sender_name}") body_data = message['payload'].get('body', {}).get('data', '') text = base64.urlsafe_b64decode(body_data).decode('utf-8', errors='ignore') if body_data else message.get('snippet', '') print(f"Processing email from {sender}: {subject}") print(f"Email content: {text}") # Perform Sentiment Analysis sentiment_response = comprehend.detect_sentiment(Text=text[:5000], LanguageCode='en') sentiment = sentiment_response['Sentiment'] print(f"Sentiment: {sentiment}") if sentiment in ['POSITIVE', 'NEGATIVE']: # Enhanced AI Prompt for Titan Model prompt = f""" You are an AI email assistant drafting a professional reply to an unread email received by the user. You are replying as the recipient of the email to the sender, whose name is '{sender_name}'. **Rules:** - Maintain a **formal and professional tone**. - Address the sender’s intent directly (e.g., respond to offers or questions). - Do not include a greeting (e.g., 'Dear {sender_name}') or closing (e.g., 'Best regards')—focus only on the response body. - Do not copy the sender’s words; write an original response. - Adapt tone based on sentiment: - If positive, keep it warm and appreciative. - If negative, be empathetic and professional. - Confirm interest in opportunities and ask about next steps if applicable. **Email Received:** From: {sender} Subject: {subject} Content: --- {text[:1000]} --- **Draft the response body:** """ try: # Invoke Amazon Bedrock bedrock_response = bedrock.invoke_model( modelId='amazon.titan-text-lite-v1', body=json.dumps({ "inputText": prompt, "textGenerationConfig": { "maxTokenCount": 300, "temperature": 0.5, "topP": 0.9 } }) ) reply_body = json.loads(bedrock_response['body'].read())['results'][0]['outputText'].strip() print(f"Generated AI Reply: {reply_body}") except Exception as e: print(f"Bedrock error: {str(e)}") raise # Check for any greeting or closing in the AI response (case-insensitive) reply_body_lower = reply_body.lower() greeting_patterns = [f"dear {sender_name.lower()}", f"hello {sender_name.lower()}", f"hi {sender_name.lower()}", "dear", "hello", "hi"] closing_patterns = ["best regards", "sincerely", "kind regards", "thank you", "regards"] reply_has_greeting = any(pattern in reply_body_lower for pattern in greeting_patterns) reply_has_closing = any(pattern in reply_body_lower for pattern in closing_patterns) # Add greeting and closing only if missing if not reply_has_greeting: reply_body = f"Dear {sender_name},\n\n{reply_body}" if not reply_has_closing: reply_body += "\n\nBest regards,\nYour Name" try: # Create draft email draft_message = f"To: {sender}\nSubject: Re: {subject}\n\n{reply_body}" draft = { 'message': { 'raw': base64.urlsafe_b64encode(draft_message.encode('utf-8')).decode('utf-8') } } print(f"Creating draft: {draft_message}") service.users().drafts().create(userId='me', body=draft).execute() drafts_created += 1 print("Draft created successfully") except HttpError as e: print(f"Draft creation failed: {e}") # Send SNS Notification if drafts_created > 0: sns.publish( TopicArn=os.environ['SNS_TOPIC_ARN'], Message=f"{drafts_created} new email drafts created. Please review in Gmail." ) print("SNS notification sent") return {'statusCode': 200, 'body': f'Processed {len(messages)} emails, created {drafts_created} drafts'} except HttpError as error: print(f"Gmail API error: {error}") return {'statusCode': 500, 'body': f'Gmail API error: {error}'} except Exception as e: print(f"Error: {str(e)}") return {'statusCode': 500, 'body': f'An error occurred: {str(e)}'} Deploy the Code: Compress/ZIP the lambda_package folder: cd lambda_package zip -r ../lambda_function.zip . In the Lambda console, select the Code tab, click Upload from and select .zip file, and upload lambda_function.zip. Deploy the Code: Compress/ZIP the lambda_package folder: cd lambda_package zip -r ../lambda_function.zip . In the Lambda console, select the Code tab, click Upload from and select .zip file, and upload lambda_function.zip. Compress/ZIP the lambda_package folder: cd lambda_package zip -r ../lambda_function.zip . Compress/ZIP the lambda_package folder: cd lambda_package zip -r ../lambda_function.zip . cd lambda_package zip -r ../lambda_function.zip . In the Lambda console, select the Code tab, click Upload from and select .zip file, and upload lambda_function.zip. In the Lambda console, select the Code tab, click Upload from and select .zip file, and upload lambda_function.zip. Set Environment Variables: Go to Configuration; select Environment variables and click on Edit. Add the following values:SECRET_ARN: Your Secrets Manager ARN (from Step 2) SNS_TOPIC_ARN: Your SNS topic ARN (from Step 3) Click on save button. Set Environment Variables: Go to Configuration; select Environment variables and click on Edit. Add the following values:SECRET_ARN: Your Secrets Manager ARN (from Step 2) SNS_TOPIC_ARN: Your SNS topic ARN (from Step 3) Click on save button. Go to Configuration; select Environment variables and click on Edit. Go to Configuration; select Environment variables and click on Edit. Add the following values:SECRET_ARN: Your Secrets Manager ARN (from Step 2) SNS_TOPIC_ARN: Your SNS topic ARN (from Step 3) Add the following values: SECRET_ARN: Your Secrets Manager ARN (from Step 2) SNS_TOPIC_ARN: Your SNS topic ARN (from Step 3) Click on save button. Click on save button. Set Timeout:Under Configuration, select the General configuration and click on Edit button then set the timeout to 5 minutes to accommodate processing multiple emails. Set Timeout: Under Configuration, select the General configuration and click on Edit button then set the timeout to 5 minutes to accommodate processing multiple emails. Step 7: Learn To Execute The Workflow Automating Execution Using Amazon EventBridge Step 7: Learn To Execute The Workflow Automating Execution Using Amazon EventBridge Go to AWS Console and select EventBridge and Create Rule. Name it as Gmail-AutoReply-Schedule. For Schedule Expression, put: rate(2 hours) For Targets, choose Lambda function and select EmailAutoReplyProcessor. Click Create Rule. Go to AWS Console and select EventBridge and Create Rule. Name it as Gmail-AutoReply-Schedule. For Schedule Expression, put: rate(2 hours) For Targets, choose Lambda function and select EmailAutoReplyProcessor. Click Create Rule. Step 8: Review Draft and Send Emails in Gmail Step 8: Review Draft and Send Emails in Gmail Review the final outputs of AutoResponder AI in your Gmail account at the end of the process. Sign in to your Gmail account. Go to the Drafts folder. Read through each of the AI-generated drafts, make any necessary changes, and then manually send each when you are finished. Sign in to your Gmail account. Go to the Drafts folder. Read through each of the AI-generated drafts, make any necessary changes, and then manually send each when you are finished. What You’ve Built What You’ve Built These steps have been checked and you have successfully created AutoResponder AI, an AI-based email assistant that: It checks your Gmail inbox every two hours for new messages that are unread. Utilizes Amazon Comprehend to determine the sentiment of these emails. To edit emails that need your attention, it prepares professional replies with the help of Amazon Bedrock. It also organizes the drafts for you in Gmail. It informs you through Amazon SNS when there are new drafts. It checks your Gmail inbox every two hours for new messages that are unread. Utilizes Amazon Comprehend to determine the sentiment of these emails. To edit emails that need your attention, it prepares professional replies with the help of Amazon Bedrock. It also organizes the drafts for you in Gmail. It informs you through Amazon SNS when there are new drafts. This is a secure, cost-effective, and fully customizable serverless solution. Get a better and more efficient way of working with emails with AutoResponder AI! Enjoy!