A personal AI voice assistant for Alexa, powered by OpenAI's GPT models. Have natural conversations - just ask questions like "what is the moon" or "tell me about dinosaurs".
- Natural conversation - Just ask "what is X" or "tell me about Y" - no special commands needed
- Conversation memory - Remembers context for follow-up questions ("tell me more", "why is that")
- Smart summarization - Older messages are summarized to allow longer conversations
- Voice AI assistant - Talk to "Snowball" through Alexa
- Fast responses - Uses gpt-4o-mini optimized for voice (1-2 second responses)
- Kid-friendly - Great for children's questions, safe and educational
- Daily token limit - Configurable per-user limits to control costs
- Automatic reset - Token usage resets at midnight (timezone-aware)
- Retry logic - Automatic retries for reliable responses
- Serverless - AWS Lambda + DynamoDB, minimal cost (~$0.60/month max)
User (Alexa) → Lambda → OpenAI API
↓
DynamoDB (token tracking)
- AWS CLI configured with credentials
- AWS SAM CLI
- Node.js 18.x or later
- OpenAI API key
- Amazon Developer Account for Alexa skill
# Install Homebrew (if not installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install required tools
brew install awscli aws-sam-cli node
# Verify installations
aws --version
sam --version
node --versionFor other platforms, see AWS CLI Install Guide and SAM CLI Install Guide.
Note: OpenAI API is separate from ChatGPT Plus subscription. API access requires separate billing.
- Go to platform.openai.com (not chat.openai.com)
- Sign up or log in
- Go to Settings → Billing → Add payment method and add credits (minimum $5)
- Go to API Keys → Click Create new secret key
- Copy the key (starts with
sk-) - it's only shown once!
This skill uses gpt-4o-mini by default - fast and reliable. You can change the model in lambda/services/openaiService.js:
| Model | Best For | Speed | Cost (per 1M tokens) |
|---|---|---|---|
gpt-4o-mini |
Recommended - fast, reliable, good quality | Fast | $0.15 / $0.60 |
gpt-4o |
Better quality | Medium | $2.50 / $10.00 |
gpt-4-turbo |
Complex reasoning | Slower | $10.00 / $30.00 |
For voice assistants, faster is better - Alexa has an 8-second timeout.
git clone https://github.com/iamwhatever/alexaSpeaker.git
cd alexaSpeaker
npm installIf you haven't configured AWS CLI yet, run:
aws configureEnter your AWS credentials:
- AWS Access Key ID: Your IAM user access key
- AWS Secret Access Key: Your IAM user secret key
- Default region:
us-east-1(required for Alexa skills) - Default output format:
json
To get AWS access keys, create an IAM user in AWS Console with AdministratorAccess permission.
Copy the example config and fill in your credentials:
cp samconfig.example.toml samconfig.tomlEdit samconfig.toml with your OpenAI API key (get one from OpenAI Platform):
parameter_overrides = [
"OpenAIApiKey=sk-your-actual-openai-api-key",
"DailyTokenLimit=50000",
"UserTimezone=America/Los_Angeles"
]| Parameter | Description | Default |
|---|---|---|
OpenAIApiKey |
Your OpenAI API key (get one here) | (required) |
DailyTokenLimit |
Max tokens per user per day | 50000 |
UserTimezone |
Timezone for daily reset | America/Los_Angeles |
sam build
sam deployAfter deployment, note the output:
Key AlexaSpeakerFunctionArn
Value arn:aws:lambda:us-east-1:123456789:function:alexa-chatgpt-skill-AlexaSpeakerFunction-AbCdEfGh
Save both:
- Lambda ARN: The full
arn:aws:lambda:...value (for Alexa endpoint) - Function name: The part after
function:(e.g.,alexa-chatgpt-skill-AlexaSpeakerFunction-AbCdEfGh)
- Go to Alexa Developer Console
- Create a new Custom skill (name: "Chat Assistant", model: Custom, hosting: Provision your own)
- In JSON Editor, paste contents of
skill-package/interactionModels/custom/en-US.json - Click Save Model then Build Model
- Go to Endpoint, select AWS Lambda ARN, paste your Lambda ARN
- Copy your Skill ID (click "View Skill ID" at top)
- Add Alexa permission to invoke your Lambda (run this locally - it updates AWS):
aws lambda add-permission \
--function-name alexa-chatgpt-skill-AlexaSpeakerFunction-AbCdEfGh \
--statement-id alexa-skill \
--action lambda:InvokeFunction \
--principal alexa-appkit.amazon.com \
--event-source-token amzn1.ask.skill.xxxx-xxxx-xxxxReplace:
alexa-chatgpt-skill-AlexaSpeakerFunction-AbCdEfGh→ your function name from step 4amzn1.ask.skill.xxxx-xxxx-xxxx→ your Skill ID from step 6
- Test in the Alexa Developer Console Test tab
See DEPLOYMENT.md for detailed step-by-step instructions.
├── lambda/
│ ├── index.js # Lambda entry point
│ ├── handlers/ # Alexa intent handlers
│ │ ├── chatHandler.js # Main chat logic
│ │ ├── launchHandler.js # Skill launch
│ │ └── helpHandler.js # Help/Stop/Cancel
│ ├── services/
│ │ ├── openaiService.js # OpenAI API integration
│ │ └── tokenTracker.js # DynamoDB token tracking
│ └── utils/
│ └── responses.js # Response helpers
├── skill-package/ # Alexa skill definition
├── template.yaml # AWS SAM template
├── samconfig.example.toml # Config template (copy to samconfig.toml)
└── DEPLOYMENT.md # Detailed deployment guide
| File | Purpose | Git |
|---|---|---|
samconfig.example.toml |
Template - copy and fill in | Tracked |
samconfig.toml |
Your actual config with credentials | Ignored |
template.yaml |
AWS infrastructure definition | Tracked |
Once deployed, say to your Alexa device:
"Alexa, open chat assistant"
→ "Hi, I'm Snowball. What would you like to know?"
"What is the capital of France"
→ "The capital of France is Paris..."
"Tell me about dinosaurs"
→ "Dinosaurs were..."
"Why is the sky blue"
→ "The sky appears blue because..."
"Stop"
→ "Goodbye."
Speak naturally with these patterns:
| Pattern | Example |
|---|---|
what is {topic} |
"what is the moon" |
what are {topic} |
"what are black holes" |
tell me about {topic} |
"tell me about Paris" |
who is {person} |
"who is Einstein" |
where is {place} |
"where is Tokyo" |
when was {event} |
"when was World War 2" |
why is {question} |
"why is the sky blue" |
how do {question} |
"how do airplanes fly" |
how to {action} |
"how to make pancakes" |
explain {topic} |
"explain gravity" |
can you {request} |
"can you tell me a joke" |
Snowball, {question} |
"Snowball, what's the weather" |
Snowball remembers your conversation context, allowing natural follow-ups:
"What is the Great Wall of China"
→ "The Great Wall is a series of fortifications..."
"How long is it" ← Knows "it" = Great Wall
→ "It stretches about 13,000 miles..."
"When was it built" ← Still has context
→ "Construction began in the 7th century BC..."
| Messages | What Happens |
|---|---|
| 1-9 | All messages kept in full |
| 10+ | Older messages summarized, recent 4 kept |
| Ongoing | Summary updated, recent context preserved |
| Scope | Memory Kept? |
|---|---|
| Same session | Yes - full context with summarization |
| After "Stop" | No - resets |
| After timeout | No - resets |
No publishing needed! Development mode skills are available on your personal devices:
- Your Echo/Alexa device must use the same Amazon account as your developer account
- Skill must be set to Development in the Test tab
- Just say: "Alexa, open chat assistant"
To verify, open the Alexa app → More → Skills & Games → Your Skills → Dev tab
Important: Keep this skill in Development mode permanently. Do NOT publish it.
If published:
- Anyone could use your OpenAI API key (your money!)
- Your AWS resources would serve the public
- Unexpected bills
Development mode = Only your Amazon account can use it.
| Limitation | How We Handle It |
|---|---|
| 8-second timeout | Use fast model (gpt-5-nano), retry logic |
| ~8000 char speech limit | System prompt asks for short responses, truncation safety net |
| Utterance patterns | Need carrier phrases like "what is", "tell me about" |
Alexa requires utterance patterns with "carrier phrases" - you can't just say anything freeform. We support many natural patterns like "what is X", "tell me about X", "why is X", etc. You can also use "Snowball, X" as a catch-all.
| Factor | Impact |
|---|---|
| Model choice | Biggest impact - gpt-5-nano is fastest |
| System prompt | Tells GPT to keep answers short |
max_completion_tokens |
Cost control only, doesn't speed up responses |
samconfig.tomlis in.gitignore- never commit credentials- For production, consider using AWS Secrets Manager
- OpenAI API key is stored as a Lambda environment variable with
NoEchoenabled - Never share your API key - if exposed, regenerate immediately at platform.openai.com/api-keys
| Service | Free Tier | Typical Cost |
|---|---|---|
| AWS Lambda | 1M requests/month | $0 |
| DynamoDB | 25 GB storage | $0 |
| OpenAI gpt-4o-mini | None | ~$0.50-2.00/month |
Cost estimate with default settings (50,000 tokens/day limit):
- Light usage: ~$0.30/month
- Heavy usage (hitting daily limit): ~$2.00/month
After code changes:
sam build && sam deploy-
Check CloudWatch logs:
aws logs tail /aws/lambda/<your-function-name> --since 10m
-
Common causes:
- OpenAI API key invalid → Regenerate and update
- Response too long → System prompt should limit this
- Timeout → Model might be slow, consider gpt-5-nano
- Try a different browser (Chrome works best)
- Open in new tab: developer.amazon.com/alexa/console/ask
- Make sure Development mode is selected (not "Off")
- Verify endpoint ARN is saved in Alexa Console
- Verify Lambda permission was added:
aws lambda get-policy --function-name <your-function-name>
- Skill ID in permission must match your actual skill
aws lambda invoke \
--function-name <your-function-name> \
--payload '{"version":"1.0","session":{"new":true,"sessionId":"test","application":{"applicationId":"test"},"user":{"userId":"test"}},"request":{"type":"LaunchRequest","requestId":"test","timestamp":"2024-01-01T00:00:00Z","locale":"en-US"}}' \
--cli-binary-format raw-in-base64-out \
response.json && cat response.jsonaws dynamodb scan --table-name AlexaChatTokenUsagesam delete --stack-name alexa-chatgpt-skillThen delete the Alexa skill from the Developer Console.
MIT