I built an agent with Claude Code that’s hosted on AgentCore and connected to a local Telegram bot. It has memory, CloudWatch, X-ray tracing, search tools, email sending, and scheduled task execution.
I wanted to connect it to AWS via Lambda so it wouldn’t depend on running locally. I talked to Claude Code and it explained what needed to be done. It’s not complicated, but I wanted to understand the system first.
Event Delivery Patterns
When System A needs to know something happened in System B, how does it find out?
There are several approaches to event delivery:
- Polling - constantly asking “anything new?” - inefficient
- Long polling - keeping the request open until there’s a response - less wasteful
- Webhook - one side notifies when something happens - efficient, one-way
- WebSocket - open connection - efficient, bidirectional
- Server-Sent Events (SSE) - server-to-client only (news feeds, live updates)
- Message Queues - Service A drops a message, Service B picks it up when ready. Good for async processing.
- gRPC streaming - bidirectional over HTTP/2, popular for microservices
For web applications, Webhook, WebSocket, and SSE are most common.
Deep Dive: Webhook vs WebSocket
WebSocket: Always-on bidirectional connection
Think phone call - both sides stay connected and can talk whenever they want without dialing again.
Example: Google Docs. When multiple people edit a document, everyone sees changes in real-time. The server maintains an open connection per user and pushes updates instantly. 100 editors = 100 open connections.
Another example: Slack. Messages appear immediately without refreshing. The server pushes new messages through the open connection.
WebSocket requires a server running continuously - someone needs to “hold the line open” and track who’s connected. It’s stateful: the server remembers “I have 50 users connected right now.”
Webhook: One-time “knock on the door”
Think SMS - someone sends you a message, there’s no connection between you, they don’t know if you read it.
Example: GitHub webhooks. When you push to a repo, GitHub sends a POST request to your configured URL. It sends the message and moves on - doesn’t wait for a response, doesn’t care what you do with it.
Another example: Stripe payments. When a payment succeeds, Stripe POSTs transaction details to your server.
Webhooks are stateless: each request stands alone. If you need memory, store it elsewhere (database, AgentCore memory, etc.).
Bottom line:
- Webhook = “call me when there’s news”
- WebSocket = “let’s stay on the line together”
For a Telegram bot, webhook fits perfectly - POST when someone messages the bot, Lambda wakes up, handles it, goes back to sleep.
Why Webhook Works for Cloud-Based Telegram Bots
A Telegram bot doesn’t need to send messages proactively - it just responds to users. Why pay for a server running 24/7 waiting? Better to let Telegram “wake up” the Lambda only when needed.
The practical difference:
With WebSocket (Gmail): Connection stays open, so incoming emails trigger notifications instantly. Google’s servers maintain millions of open connections.
With Webhook (Telegram bot): Telegram knocks on the door only when there’s a new message. Lambda can sleep in between - no cost.
Case Study: AI Agent on AgentCore with Telegram Bot
How it works:
- User messages the Telegram bot
- Request goes through API Gateway to Lambda
- Lambda forwards to the agent running on AgentCore
- Agent responds back through Lambda to Telegram
Key components:
Lambda - Cloud function. Code that runs only when called, no server management.
Traditional model: Server (EC2/VPS) runs 24/7. Even at 3 AM with zero users, it’s on and someone’s paying. Cost: ~$10-30/month even with no usage.
Lambda model: Code “sleeps” somewhere in AWS. When a request arrives (HTTP, EventBridge trigger, Telegram message) - AWS wakes the code, runs it, returns a response. You pay only for actual execution time. Cost: pennies for low usage.
API Gateway - The gatekeeper. Every external request (from Telegram, apps, websites) passes through it first.
What it does:
- Provides a fixed public URL
- Routes requests to the right Lambda
- Basic security (rate limiting, authentication)
- Logging
Without it, Lambda isn’t accessible from outside - it has no public address.
SSM Parameter - AWS service for storing configs and secrets. Instead of putting Telegram tokens in code or .env files, store them encrypted in AWS. Lambda reads them at runtime. Benefits: security, central management, no secrets in code.
Polling vs Webhook comparison:
Polling:
- Bot runs constantly asking Telegram “any new messages?”
- Requires 24/7 process
- Doesn’t fit Lambda (Lambda only runs when called)
Webhook:
- Telegram sends messages when something’s new
- Lambda sleeps until a message arrives
- Pay only for actual use
This is the standard way to run bots in the cloud.
Telegram Bot: From Local to Cloud
Initially the bot ran locally - I had to start it from the terminal. I connected it to AWS via Lambda so it wouldn’t depend on running locally.
The bot itself isn’t hosted in the cloud - it lives on Telegram’s servers. What runs on Lambda is the code that handles messages (the webhook handler). Bot lives in Telegram, logic lives in Lambda.
What this includes:
- Webhook handler in Lambda
- API Gateway
- SSM Parameter - AWS service for storing configs and secrets. Instead of putting the Telegram token in code or .env, it’s stored encrypted in AWS. Lambda reads it at runtime. Benefits: security, central management, no secrets in code.
How the agent communicates through Telegram:
Incoming message (webhook): User sends to Telegram → API Gateway → Lambda → AgentCore
Outgoing message (HTTP call): AgentCore → Lambda → Telegram
Agent’s tools: search, send email, send Telegram message.
What was missing: ability for the agent to schedule on its own - a tool to create EventBridge rules or DynamoDB entries.
Adding Scheduling: EventBridge vs DynamoDB
The agent needed to schedule reminders on its own.
DynamoDB: Regular database table, flexible, needs a Lambda scanning every minute, pay per read.
EventBridge: Built-in AWS scheduler, more rigid, cheaper.
For dynamic reminders, DynamoDB is simpler - save a row, Lambda checks every minute what’s due, sends and deletes.
You can create EventBridge rules dynamically via AWS SDK, but:
- Default limit of 300 rules
- Need to clean up rules after they run
- Additional IAM permissions
For small scale - EventBridge works great. For many reminders - DynamoDB is better.
Why does DynamoDB need Lambda running every minute? Isn’t polling inefficient?
DynamoDB is just a database - it can’t “wake something up” at a specific time. So you need a Lambda checking every minute “is anything due now?” It’s polling, but internal to AWS (cheap and reasonable).
EventBridge, on the other hand, is a scheduler - it knows how to say “run this at X.”
What I Built
I chose EventBridge and added:
schedule_remindertool for one-time remindersschedule_recurringtool for recurring ones- Reminder Lambda triggered by EventBridge
- IAM permissions for managing EventBridge rules
Now the agent can:
- Receive a request like “remind me tomorrow at 10 to check emails”
- Parse the time to ISO format
- Create a one-time or recurring EventBridge rule
- When the time comes - send a Telegram message and delete the rule if needed
Two Lambdas:
- EventBridge wakes the reminder Lambda on schedule, which calls the agent to execute actions
- Webhook Lambda passes incoming Telegram messages to the agent
Summary
- Agent is hosted on AgentCore runtime
- Telegram bot is a communication layer - a pipe passing messages to/from the agent. The same agent could receive messages from Web UI, Slack, WhatsApp - doesn’t matter. Logic and memory live in AgentCore, not the bot.
- Scheduling is handled by EventBridge
- Two Lambdas: one for scheduling, one for the Telegram webhook
- AgentCore responds to Telegram via regular API calls
Before: User messages via Telegram, local machine constantly polls for requests and forwards to AgentCore.
After: User messages via Telegram, request goes through API Gateway via webhook to Lambda only when needed, then to AgentCore.