Overview
This is a part II of Blog Amazon SES configuration for SAP ABAP Systems
In part I, we covered the Outbound emails from SAP systems to external recipients. In this blog, we will cover Inbound email from external recipients to SAP users.
Services Used
-
- Amazon Simple Email Service
- AWS Lambda
- Amazon CloudWatch Logs
- Amazon S3
Introduction
In previous blog, we showed how AWS Native services can be leveraged for outbound mail notifications from SAP systems. In this blog we will guide you through the required steps to configure inbound mail to an SAP ABAP system using Amazon SES (Simple Email Service) service.
Amazon Simple Email Service (SES) is a cost-effective, flexible, and scalable email service that enables customers to send mail from within any application. You can configure Amazon SES quickly to support several email use cases, including transactional, marketing, or mass email communications
For a detailed list of SES service capabilities specific to inbound email processing see documentation. In our example we will call a Lambda function to process and deliver the mail (including any attachment) to a named SAP user.
Architecture
RISE with SAP
SAP on AWS Native
Workflow
- End user sends email to the target system e.g. x12@people.aws.dev
- The request is handled by inbound-smtp.eu-central-1.amazonaws.com (Amazon SES SMTP endpoint for inbound requests for the specific region e.g. eu-central-1 in this case)
- Email is saved in Amazon S3 bucket
- Lambda function is invoked. This function will send the email saved in Amazon S3 bucket to the local SMTP service for the target SAP system
- SAP system will receive the email
Prerequisites
As documented in this page, the following steps need to be performed
S3 bucket and its permissions
This bucket is required for storing mails which will be forwarded to target SAP system. Below is an example bucket policy to be linked to this bucket. Please find some example in the AWS documentation. In our example we grant SES service access to an S3 bucket for copying mail objects.
You can set lifecycle policy on the S3 bucket used to store the incoming emails, for management. For example, after 10 days, move them to Infrequent Access storage class OR after 30 days, delete them.
{ "Version": "2012-10-17", "Statement": [ { "Sid": "sid1", "Effect": "Allow", "Principal": { "Service": "ses.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::<s3-bucket-name>/*", "Condition": { "StringEquals": { "AWS:SourceAccount": "<AWS Account Number>" }, "StringLike": { "AWS:SourceArn": "arn:aws:ses:*" } } } ] }Domain verification
Amazon SES domain verification is done via identity creation under the configuration identities menu; ensure the Identity Status is “Verified”
Publishing MX record
In this case we are using Amazon Route53 as dns, and created a MX record which points our domain to the Amazon SES endpoint
Validate SAP system connection details
SAP system hostname/IP address and SMTP port. This last information can be extracted from SAP transaction smicm → active services. In our solution, Amazon SES will be communicating with the SAP system on this SMTP port. This port needs to be whitelisted to allow Amazon SES to communicate.
Lambda function
Please create the Lambda function with VPC access in order to connect to the target SAP system (see screenshot for reference).
Security group should allow outgoing traffic on the SMTP configured port in SAP and outgoing traffic to S3 endpoints. For example, in below diagram, SMTP services on SAP system is configured to listen on port 25000 and S3 endpoint on port 443.
Also ensure that this function has access to write Cloudwatch logs and access to read contents from S3 bucket, where emails are stored
Lambda code which will be invoked by SES service upon receiving an inbound message (code has been adjusted for SAP from original SES blog)
# Copyright 2010-2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # This file is licensed under the Apache License, Version 2.0 (the "License"). # You may not use this file except in compliance with the License. A copy of the # License is located at # # http://aws.amazon.com/apache2.0/ # # This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS # OF ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. import smtplib import os import boto3 import re import email from email.message import EmailMessage from email.parser import BytesParser, Parser from email.policy import default from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication host = "<hostname or IP of SAP target system>" port = "<port of SAP SMTP service>" region = os.environ['AWS_REGION'] def lambda_handler(event, context): # Get the unique ID of the message. This corresponds to the name of the file # in S3. message_id = event['Records'][0]['ses']['mail']['messageId'] # Retrieve the file from the S3 bucket. file_dict = get_message_from_s3(message_id) # Create the message. message = create_message(file_dict) # Send the email and print the result. smtp = smtplib.SMTP(host, port) smtp.ehlo() result = smtp.send_message(message) smtp.close() def get_message_from_s3(message_id): incoming_email_bucket = "<bucket name to store the messages>" incoming_email_prefix = "ses" if incoming_email_prefix: object_path = (incoming_email_prefix + "/" + message_id) else: object_path = message_id object_http_path = (f"http://s3.console.aws.amazon.com/s3/object/{incoming_email_bucket}/{object_path}?region={region}") # Create a new S3 client. client_s3 = boto3.client("s3") # Get the email object from the S3 bucket. object_s3 = client_s3.get_object(Bucket=incoming_email_bucket, Key=object_path) # Read the content of the message. file = object_s3['Body'].read() file_dict = { "file": file, "path": object_http_path } return file_dict def create_message(file_dict): separator = ";" # Parse the email body. mailobject = email.message_from_string(file_dict['file'].decode('utf-8'), policy=email.policy.default) #print(mailobject) # Extract sender,receiver and subject. sender = mailobject['From'] receiver = mailobject['To'] subject = mailobject['Subject'] # Create body text of the email for sending as attachment body_text = ("The attached message was received from " + separator.join(mailobject.get_all('From')) + ". This message is archived at " + file_dict['path']) # Extract body text of the email. body = mailobject.get_body(preferencelist=('related', 'html', 'plain')) attachment = mailobject.get_payload()[1] # The file name to use for the attached message. Uses regex to remove all # non-alphanumeric characters, and appends a file extension. filename = re.sub('[^0-9a-zA-Z]+', '_', subject) + ".eml" # Create a MIME container. msg = MIMEMultipart() # Create a MIME text part. text_part = MIMEText(body_text, _subtype="html") # Attach the text part to the MIME message. msg.attach(body) # Add subject, from and to lines. msg['Subject'] = subject msg['From'] = sender msg['To'] = receiver # Attach the file object to the message. msg.attach(attachment) message = msg return messageSES Rule Set
In SES console, under configuration → mail receiving, add a new rule which will first store the message in S3 bucket and then invoke the Lambda function which was just created to process the message and send it to SAP (including any attachment).
SAP ABAP Inbound Email Configuration
Test inbound email
For inbound email testing, write an email to the recipient which was just configured in the rule set above.
Once sent, we can check in SAP system’s user inbox (which needs proper mail address setup in user master data – transaction su01) using transaction so01
Costs
Below are the services and relevant monthly costs associated with the use of those services for this solution. Let us assume every month 40,000 emails are received by the system with each email of size 40KB (Public link is here)
- Amazon SES – 8 USD
- Amazon Route 53 – 0.52 USD
- Amazon S3 Bucket – 0.27 USD
- Amazon CloudWatch Logs – 0.95 USD
- AWS Transit Gateway (optional, in case of SAP RISE deployments) – 43.83 USD
- Amazon Lambda – 6.69 USD
Total cost is estimated at 60.26 USD per month for Frankfurt region.
Conclusion
In this blog, we have shown how to configure SAP ABAP systems for receiving inbound emails, a very common requirement, both from Business processes and Basis operations perspectives. More information can be found in the SES documentation.
Let us know if you have any comments or questions — we value your feedback.