DEV Community

Cover image for Part 4: Going Fully Autonomous: EventBridge, DynamoDB, and Automated Publishing
Ashley Armstrong
Ashley Armstrong

Posted on

Part 4: Going Fully Autonomous: EventBridge, DynamoDB, and Automated Publishing

Generating content is interesting. Generating content, creating artwork, and publishing it without human intervention is where things start to get fun.


The Final Challenge

By this point, WizardThoughts had come a long way.

The platform could:

✅ Generate content using Amazon Bedrock

✅ Generate matching image prompts

✅ Create original artwork using Stability AI

✅ Store assets in Amazon S3

✅ Track everything in DynamoDB

The individual pieces worked.

The problem was coordination.

I was still manually triggering parts of the workflow.

The system wasn't autonomous.

It was semi-automated.

There is an important difference.


The Goal

My original vision was simple:

Create a social media account capable of generating and publishing its own content without human involvement.

To achieve that, every component needed to operate independently.

The complete workflow looked like this:

EventBridge
      ↓
GenerateContent
      ↓
Amazon Bedrock
      ↓
DynamoDB
      ↓
GenerateImage
      ↓
Stability AI
      ↓
Amazon S3
      ↓
PublishToX
      ↓
WizardThoughts
Enter fullscreen mode Exit fullscreen mode

Once that pipeline was running, the system would effectively become self-managing.


DynamoDB Becomes the Brain

Originally, DynamoDB was simply a storage layer.

As the project evolved, it became much more than that.

It became the central source of truth.

Every piece of content moved through a series of states.

For example:

{
  "PostId": "post-123",
  "Status": "Pending",
  "ImageStatus": "Pending"
}
Enter fullscreen mode Exit fullscreen mode

Then:

{
  "PostId": "post-123",
  "Status": "Pending",
  "ImageStatus": "Complete",
  "ImageUrl": "..."
}
Enter fullscreen mode Exit fullscreen mode

And finally:

{
  "PostId": "post-123",
  "Status": "Published",
  "TweetId": "123456789"
}
Enter fullscreen mode Exit fullscreen mode

This simple approach eliminated enormous amounts of complexity.

Rather than services talking directly to each other, they only needed to understand state.


Building a State Machine Without a State Machine

Technically, I wasn't using AWS Step Functions.

But the architecture behaved like one.

Each Lambda function had a single responsibility.

GenerateContent

Creates:

Quote
Image Prompt
Database Record
Enter fullscreen mode Exit fullscreen mode

GenerateImage

Looks for:

Status = Pending
ImageStatus = Pending
Enter fullscreen mode Exit fullscreen mode

Generates artwork and updates the record.


PublishToX

Looks for:

Status = Pending
ImageStatus = Complete
Enter fullscreen mode Exit fullscreen mode

Then publishes the post.


The beauty of this approach is simplicity.

Every service operates independently.

Every service knows exactly what work it needs to perform.


EventBridge: The Invisible Conductor

The final piece of the puzzle was scheduling.

Without EventBridge, nothing happened automatically.

With EventBridge, the entire pipeline came to life.

I created three schedules.

Content Generation

Every 6 hours
Enter fullscreen mode Exit fullscreen mode

This generated fresh content throughout the day.


Image Generation

Every 6 hours
Enter fullscreen mode Exit fullscreen mode

This checked DynamoDB for content requiring artwork.


Publishing

Every 6 hours
Enter fullscreen mode Exit fullscreen mode

This checked for completed posts ready to publish.


The result was a continuous workflow that required zero manual intervention.


Publishing Images to X

Getting text published was relatively straightforward.

Images were another story.

The publishing workflow became:

Retrieve Post
        ↓
Load Image From S3
        ↓
Upload Media To X
        ↓
Attach Media To Tweet
        ↓
Publish
Enter fullscreen mode Exit fullscreen mode

Simple in theory.

Less simple in reality.


Authentication: The Sequel

Just when I thought I'd finally escaped authentication issues, another surprise appeared.

Text tweeting worked.

Image uploads didn't.

The logs repeatedly returned:

401 Unauthorized
Enter fullscreen mode Exit fullscreen mode

and

403 Unsupported Authentication
Enter fullscreen mode Exit fullscreen mode

After far more debugging than I would like to admit, I discovered the issue.

Different X endpoints preferred different authentication methods.

The solution was moving to OAuth 1.0a credentials:

CONSUMER_KEY
CONSUMER_SECRET
ACCESS_TOKEN
ACCESS_TOKEN_SECRET
Enter fullscreen mode Exit fullscreen mode

The moment I switched:

const client = new TwitterApi({
  appKey: process.env.CONSUMER_KEY,
  appSecret: process.env.CONSUMER_SECRET,
  accessToken: process.env.ACCESS_TOKEN,
  accessSecret: process.env.ACCESS_TOKEN_SECRET
});
Enter fullscreen mode Exit fullscreen mode

everything finally started working consistently.


The Moment It Became Real

The first fully automated post felt different.

Not because the content was exceptional.

Not because the image was perfect.

Because nobody touched anything.

The workflow executed entirely on its own.

EventBridge Trigger
       ↓
Bedrock Generated Quote
       ↓
Stability Generated Artwork
       ↓
S3 Stored Asset
       ↓
DynamoDB Updated State
       ↓
X Published Content
Enter fullscreen mode Exit fullscreen mode

No buttons.

No manual deployments.

No intervention.

The system simply did what it had been designed to do.

That was the moment the project stopped feeling like a collection of Lambda functions and started feeling like a product.


Operational Lessons

Building something is one thing.

Keeping it running is something else entirely.

Several operational challenges appeared almost immediately.

Timeouts

Image generation takes time.

A three-second Lambda timeout might be fine for a simple API call.

It's not fine for image generation.

Increasing:

Timeout
Memory
Enter fullscreen mode Exit fullscreen mode

became essential.


Region Mismatches

The number of issues caused by regions was surprising.

Examples included:

  • Missing models
  • Invalid model identifiers
  • S3 redirects
  • Bedrock availability issues

The lesson:

Always verify the region before assuming anything else is broken.


State Matters

State-driven systems are incredibly forgiving.

If something fails:

Status = Pending
Enter fullscreen mode Exit fullscreen mode

remains unchanged.

The workflow can simply retry later.

This made the platform significantly more resilient.


Cost Considerations

One of the most interesting discoveries was how inexpensive the system remained.

Most usage came from:

  • Amazon Bedrock
  • Stability AI
  • Lambda executions
  • S3 storage

Because everything was serverless:

No servers
No virtual machines
No containers
Enter fullscreen mode Exit fullscreen mode

The system only incurred costs when it was actually doing work.

For a side project, this was ideal.


Future Improvements

Even though the system now functioned end-to-end, there are still plenty of opportunities for expansion.

Some ideas include:

Engagement Analytics

Track:

  • Likes
  • Replies
  • Reposts
  • Follower growth

and feed the results back into future content generation.


Trending Topics

Incorporate:

Current Events
Trending Conversations
Seasonal Topics
Enter fullscreen mode Exit fullscreen mode

while maintaining the wizarding theme.


Multiple Accounts

The architecture already supports additional social accounts.

Future versions could publish to:

  • TikTok
  • LinkedIn
  • Instagram
  • Threads

from the same content pipeline.


AI-Generated Threads

Instead of publishing individual posts:

1 Quote
↓
5 Related Ideas
↓
Thread
Enter fullscreen mode Exit fullscreen mode

This would open entirely new content formats.


What I Learned

Looking back, the project taught me three important lessons.

1. Small Systems Compound

The final architecture looks impressive.

The reality is much simpler.

It was built one small component at a time.

First authentication.

Then content.

Then images.

Then automation.

Each step was manageable.

Together they became something much larger.


2. Simplicity Scales

The most valuable design decision wasn't an AI model.

It wasn't a specific AWS service.

It was keeping each component focused on a single responsibility.

Simple systems are easier to build.

They are also easier to debug.


3. AI Is Infrastructure Now

A few years ago, building something like this would have required significant machine learning expertise.

Today, foundation models and managed services allow developers to focus on the problem instead of the infrastructure.

That's a profound shift.


Conclusion

WizardThoughts started as an experiment.

Could a collection of cloud services create and manage a social media account without human involvement?

The answer turned out to be yes.

What began as a single Lambda function evolved into a complete content pipeline capable of:

✅ Generating original content

✅ Creating custom artwork

✅ Managing workflow state

✅ Scheduling its own execution

✅ Publishing automatically to X

More importantly, it demonstrated something larger.

Modern cloud platforms are no longer just hosting environments.

Combined with foundation models, they are becoming autonomous execution environments capable of generating, creating, and distributing content with minimal human involvement.

And in many ways, we're only just getting started.


From a single automated tweet to a fully autonomous content engine, WizardThoughts became proof that a handful of serverless services, a few AI models, and a lot of persistence can build something genuinely magical.

Top comments (0)