Mastadon Bot with AWS Lambda, S3, CloudWatch, and SSM
Tags: python, devops, cloud, productivity
Published: 2023-03-23 13:08:57

In this post I show you how I set up the MastadonBot to share random frames from the movie Taxi Driver.
This bot was created by taking inspiration from [Cameron Ezell](https://www.cameronezell.com/creating-a-mastodon-bot-with-aws-lambda/).

I also created this bot using Terraform. You can browse [Github MastadonBot_AWS](https://github.com/tahayagizguler/MastadonBot_AWS).

## **How I got the frames?**

Python script "[ExtractImagesFromVideoFile](https://github.com/tahayagizguler/ExtractImagesFromVideoFile)"  I wrote for capturing screenshots at specified intervals from a video file using ffmpeg. This Python script captures screenshots from a video file at specified intervals (e.g., 1 second) using ffmpeg.

## **Uploading frames!**

First of all, I created an S3 bucket and uploaded the screenshots I wanted to share to this bucket and used the following path while uploading the screenshots.

After saving about 7000 screenshots it would take quite a while to upload them to the S3 bucket so I created an EC2 instance and uploaded the files via FTP then copied the S3 bucket via the aws cli > `aws s3 cp ./ s3://your-bucket/ --recursive`.

## **Create your Application**

For anyone interested in building a Mastodon bot, make sure the instance you create your bot on is fine with automated accounts.

After signing up, create an app from Preferences > Development.  
 ([botsin.space](https://botsin.space/about))

![App](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b1vefcuicab5zsofxg1c.png)
Enter a name for your application and default values for now.
![Keys](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8zjdeqlnimla4aqswpa5.jpg)

**I keep the access token as SecureString type using the AWS Systems Manager Parameter Store. This is an important step for security.**

## **Lambda Function**
Boto3(AWS Lambda) script for randomly selects screenshots stored in S3 and enables sharing.

```
import mastodon
from mastodon import Mastodon
import boto3
import os
import random
import re

def lambda_handler(event, context):
    BASE_URL = "https://botsin.space"
    BUCKET_NAME = "movieframebucket" # XXXXXXX
    keyArray = []
    ssm = boto3.client("ssm")

    auth_keys = ssm.get_parameters(
        Names=["my_consumer_key"], WithDecryption=True) # XXXXXXX
    access_token = auth_keys["Parameters"][0]["Value"]

    m = Mastodon(access_token=access_token, api_base_url=BASE_URL)

    s3 = boto3.resource("s3")
    s3bucket = s3.Bucket(BUCKET_NAME)

    try:
        for obj in s3bucket.objects.filter(Prefix="taxi_driver_frames/"): # XXXXXXX
            # add all frame key values from episode to an array
            keyArray.append("{0}".format(obj.key))
    except Exception as e:
        # If there is an error, raise the exception and stop the function
        raise e

    numFrames = len(keyArray)
    randomFrame = random.randint(0, numFrames)
    KEY = keyArray[randomFrame]
    print("frame from second # " + str(randomFrame))
    s3.Bucket(BUCKET_NAME).download_file(KEY, "/tmp/local.jpg")
    
    random_objectNumber = re.search(r'\d+', KEY).group()
    time_in_seconds = int(random_objectNumber)
    minutes, seconds = divmod(time_in_seconds, 60)
    hours, minutes = divmod(minutes, 60)
    time_format = "{:02d}:{:02d}:{:02d}".format(hours, minutes, seconds)
    frameInfo = "Taxi Driver | {:02d}:{:02d}:{:02d}".format(hours, minutes, seconds) 

    # We have to first create a media ID when uploading an image
    media = m.media_post("/tmp/local.jpg")
    # Then we can reference this media ID in our status post
    m.status_post(status=frameInfo, media_ids=media)


    os.remove("/tmp/local.jpg")
    return None
```
I installed the Mastadon package locally and zipped it with this code I wrote then uploaded it to Lambda.

## **CloudWatch Event for Lambda**

I created a CloudWatch Event for Lambda to publish a post every 30 minutes.
![Im](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xs5utxgrcw7xzfbv3mre.png)**And here is our [Mastadon bot](https://botsin.space/@taxidriverframes) ready!**

**I may have missed a few parts, don't hesitate to reach out to me if you need help. I would like to help you as much as I can!**