1부: 인증 지옥: AWS Lambda와 X의 대화 시작하기

작성자

카테고리:

← 피드로
DEV Community · Ashley Armstrong · 2026-07-12 개발(SW)

How a simple idea turned into a multi-day battle with APIs, OAuth, and enough authentication errors to fill a spellbook.

The Idea

Every project starts with a simple question.

For me, it was:

Could I build an autonomous Wizarding World content engine that generates its own content, creates its own artwork, and publishes directly to X without human involvement?

The concept seemed straightforward.

The vision was:

AI generates quote
        ↓
AI generates artwork
        ↓
AWS stores content
        ↓
X publishes post

Enter fullscreen mode Exit fullscreen mode

In theory, this looked like a weekend project.

In reality, it became an education in authentication systems, API permissions, OAuth flows, and the many ways technology can tell you “no”.

Building the Foundation

I decided to build everything on AWS.

The initial stack looked like this:

AWS Lambda
Amazon DynamoDB
Amazon Bedrock
Amazon S3
EventBridge
X API

Enter fullscreen mode Exit fullscreen mode

The first objective was intentionally small:

Post a single tweet from AWS Lambda.

Not an AI-generated tweet.

Not an image.

Just a tweet.

How hard could that be?

The First Lambda

The first Lambda function was incredibly simple.

Create Lambda
Install twitter-api-v2
Add environment variables
Call tweet endpoint

Enter fullscreen mode Exit fullscreen mode

Five minutes later everything was deployed.

I clicked Test.

It failed.

Welcome to OAuth.

The Authentication Rabbit Hole

If you’ve worked with X’s API before, you’ll know there isn’t just one way to authenticate.

There are several.

At first glance they all appear to do similar things:

Bearer Token
OAuth 2.0
OAuth 2.0 User Context
OAuth 1.0a

Enter fullscreen mode Exit fullscreen mode

The challenge is understanding which one works with which endpoint.

I made what seemed like the obvious choice.

I used the Bearer Token.

The result?

403 Forbidden

Enter fullscreen mode Exit fullscreen mode

Not very helpful.

After digging through the logs, I eventually found the real message:

Unsupported Authentication

Authenticating with OAuth 2.0 Application-Only is forbidden for this endpoint.

Enter fullscreen mode Exit fullscreen mode

This was my first major lesson.

Just because you’re authenticated doesn’t mean you’re authorised.

Understanding the Difference

The problem wasn’t my code.

The problem was the type of identity I was presenting to X.

A Bearer Token represents:

The application

Enter fullscreen mode Exit fullscreen mode

A User Context token represents:

The user

Enter fullscreen mode Exit fullscreen mode

Posting a tweet requires a user.

Not just an application.

In other words:

Application:
"Hello, I am WizardThoughts."

X:
"Great."

Application:
"I would like to tweet."

X:
"No."

Enter fullscreen mode Exit fullscreen mode

Chasing the Right Token

I spent hours moving between:

AWS Lambda
CloudWatch Logs
X Developer Portal

Enter fullscreen mode Exit fullscreen mode

Testing.

Deploying.

Testing again.

Every change seemed to produce a different error.

Sometimes:

401 Unauthorized

Enter fullscreen mode Exit fullscreen mode

Other times:

403 Forbidden

Enter fullscreen mode Exit fullscreen mode

And occasionally:

Unsupported Authentication

Enter fullscreen mode Exit fullscreen mode

At one point I genuinely believed I had broken the entire account configuration.

The reality was much simpler:

I was using the wrong type of token.

The First Real Breakthrough

Rather than trying to post tweets, I decided to verify authentication first.

Instead of:

client.v2.tweet(...)

Enter fullscreen mode Exit fullscreen mode

I switched to:

client.v2.me()

Enter fullscreen mode Exit fullscreen mode

This endpoint simply returns information about the currently authenticated user.

If that worked, I would know the authentication was correct.

If it failed, the token was wrong.

Suddenly I received:

{
  "username": "WizardThoughts"
}

Enter fullscreen mode Exit fullscreen mode

That was the first real victory.

For the first time, AWS Lambda had successfully authenticated with X.

No guessing.

No assumptions.

Proof.

The OAuth 2 Dead End

With authentication seemingly solved, I moved on to images.

That’s when another problem appeared.

The basic tweet APIs worked.

Media uploads did not.

The logs revealed a new pattern.

Every media upload attempt failed with:

403 Forbidden

Enter fullscreen mode Exit fullscreen mode

After more debugging, I discovered another important distinction.

Text posting could work using:

OAuth 2 User Context

Enter fullscreen mode Exit fullscreen mode

Media uploads were much happier with:

OAuth 1.0a User Context

Enter fullscreen mode Exit fullscreen mode

Which meant I needed four credentials:

CONSUMER_KEY
CONSUMER_SECRET
ACCESS_TOKEN
ACCESS_TOKEN_SECRET

Enter fullscreen mode Exit fullscreen mode

Suddenly the full picture started making sense.

The Moment Everything Clicked

The final authentication test looked like this:

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
});

const me = await client.v2.me();

Enter fullscreen mode Exit fullscreen mode

Response:

{
  "username": "WizardThoughts"
}

Enter fullscreen mode Exit fullscreen mode

Success.

Not a partial success.

Not a maybe.

A genuine, repeatable success.

The authentication layer was finally solved.

The First Automated Tweet

Once the OAuth issues were resolved, posting a tweet became almost trivial.

The same infrastructure that had spent days refusing to cooperate suddenly worked exactly as intended.

The first tweet appeared.

Not created manually.

Not posted from a browser.

Automatically.

Directly from AWS Lambda.

That single post represented far more than a tweet.

It proved the entire foundation was viable.

Lessons Learned

Three lessons stood out above everything else.

1. Authentication Is a Product Feature

Most developers treat authentication as setup.

It isn’t.

It’s part of the application.

Understanding identities, scopes, permissions, and token types is essential.

2. Trust Error Messages

Most of my mistakes came from ignoring what the logs were telling me.

Eventually every answer was in CloudWatch.

The challenge was learning how to read it.

3. Prove Identity First

Before attempting any complex API action:

Authenticate
↓
Verify user
↓
Then perform action

Enter fullscreen mode Exit fullscreen mode

Testing with v2.me() saved hours of debugging.

What’s Next?

At this point the bot could successfully:

✅ Authenticate with X

✅ Run in AWS Lambda

✅ Post automated tweets

But it still had one major limitation.

Every tweet had to be written manually.

In Part 2, we’ll teach the bot how to think for itself using Amazon Bedrock, prompt engineering, and growth-focused content generation.

Because a bot that can post is useful.

A bot that can create its own content is where the magic begins. ⚡🪄

Next: Part 2 — Prompt Engineering for Growth: Creating Viral Wizarding Content

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다