Navigate to Amazon Web Services, log in, and select Lambda. Then create a function:

I’m using Python3.6, but feel free to substitute with your language of choice.

I named my function “send-telegram-message”, and kept the default permissions. With our basic functionality, we won’t need any permissions outside the Lambda Basic Execution Role.

I am a fan of test-driven development for peace-of-mind, and the AWS Lambda console makes it easy. Click on the test button near the top right, then create a test that matches the format of our contact us form.

Since we have not implemented our Lambda function yet, when we run the test it returns a 200 status code and “Welcome from Lambda” in the body.

Let’s start by accessing our incoming data.

If you are not familiar with Lambda, our incoming data is stored in the event object. It is a typical key value mapping, and we can access it with Python’s dictionary syntax. So, let’s grab the data and format it for a Telegram message.

import json def lambda_handler(event, context):

name = event['name']

email = event['email']

message = event['message']

telegram_msg =

f'From: {name}

Email: {email}

Message:{message}'



return {

'statusCode': 200,

'body': json.dumps(telegram_msg)

}

But what if a user does not provide a name or email or message? Let’s create another test case called emptyStrings with empty values to simulate an empty form submission:

{

"name": "",

"email": "",

"message": ""

}

Well, we run this and it succeeds, but we would receive a meaningless message. How about we provide some feedback by validating the form, and by raising an error if it’s not up to our standards.

We should also provide feedback with our form on the client side to provide a good user experience and to limit unnecessary API calls, but the client side validation can always be bypassed.

Three more test cases for invalid inputs…

emptyTest:

{}

whitespaceOnly:

{

“name”: “ “,

“email”: “ “,

“message”: “ “

}

and nullEmail:

{

"name": "FirstName LastName",

"email": null,

"message": "Example message!"

}

If we can handle all of these cases, we should be pretty good. We might still receive some nonsense input, but at least it’s something we can examine.

Lets initialize a field_errors dictionary and do some form validation. I want all fields to be required, so let’s make a function that ensures the key and value both exist, and then adds an error for the field if there is an issue.

def check_param(event:dict, param:str, field_errors:dict)->str:

# checks for key and if val is null or an empty string

if param in event and event[param] and str(event[param]).strip():

return str(event[param])

else:

field_errors[param] = "Required"

return None

If we have any field errors, they will be accumulated and we will raise an exception.

def lambda_handler(event, context):

field_errors = {} # ignore event parameters other than these 3

name = check_param(event, 'name', field_errors)

email = check_param(event, 'email', field_errors)

message = check_param(event, 'message', field_errors)



if field_errors:

raise Exception(json.dumps({'field_errors': field_errors}))



telegram_msg = f'From: {name}

Email: {email}

Message:{message}' return {

'statusCode': 200,

'body': json.dumps(telegram_msg)

}

Now if you run the above test cases, they should return an expected result.