Inspiration
A Korean beverage company sells wine online, but Korean law does not allow alcohol bought online to be shipped. Every order ends at a store counter: the buyer must come in person and show their own ID. Today that last step is a paper slip or a bare SMS link. When plans change there is no one to talk to, and once the bottle leaves the counter the relationship ends.
We asked: what if the pickup were a conversation instead of a receipt? One that starts on the customer's phone, adapts when plans change, enforces the rules politely, and continues after pickup with something worth reading.
What it does
Wine Pickup Concierge turns ID-checked pickup into one continuous, multilingual conversation across RCS, SMS and email:
- RCS pickup card: When stock arrives, the customer gets a branded RCS rich card in their own language with a signed QR code, the store, the pickup window and one-tap actions: Open pickup QR, Store location, Change pickup, Wine info, Talk to staff. Phones without RCS get the same pass link through SMS fallback.
- An agent that acts, not just answers: Customers simply reply. An Amazon Bedrock agent answers pairing and serving questions. It also takes action: "Can I pick it up on Saturday at the Pangyo store instead?" changes the order, revokes the old QR and sends a fresh card. It refuses what the rules forbid, such as proxy pickup ("Can my sister pick it up?") or another customer's order, and offers an alternative instead.
- In-store handover: Staff scan the QR and check the buyer's own ID in person: name, birth year, photo, ID type and Korean legal age. An ID with a different name is refused on the spot. The ID is never photographed or stored; only the result is logged.
- SES wine guide: Seconds after pickup, a thank-you arrives in the same RCS thread, and Amazon SES delivers a wine guide in the customer's language. It has the bottle image embedded inline, tasting notes, the story behind the wine, a serving guide, food pairings and a personal note written by the AI sommelier. The RCS thread stays open for follow-up questions.
- Korean, English and Japanese end to end: The RCS card, chips, chat, QR pass, SMS fallback and email all follow the customer's language. It is stored per order and switches automatically when the customer writes in another language.
How we built it
AWS Communication Developer Services as the backbone
- AWS End User Messaging (RCS + SMS):
SendRcsMessagerich cards and suggestion chips,FallbackConfigurationto SMS, and a dedicated RCS agent with its own brand assets, privacy policy and terms pages. QR images are served from a private S3 bucket that only the messaging service can read, with a 7-day lifecycle. - Two-way messaging: RCS replies and chip taps flow through an Amazon SNS topic to the pickup service. The service verifies every SNS signature (certificate host pinned to
sns.*.amazonaws.com) and de-duplicates message IDs, because SNS delivers at least once. An SQS bridge lets us receive real inbound traffic during local development. - Amazon SES: a raw MIME email with the bottle image embedded inline (CID), so it renders in Gmail and Outlook without a public image host.
Agentic AI
- Amazon Bedrock Converse API tool loop on Claude Sonnet 5, In-Region in Seoul (ap-northeast-2), so prompts that contain personal data are processed in Korea.
- Tools:
change_pickup,resend_pickup_qr,send_wine_guide_email,handoff_to_staff. Every tool is bound to the sender's phone number taken from the SNS payload. The model never receives a customer identifier it could swap, so it cannot reach another customer's order even when asked to. - An entry point for Amazon Bedrock AgentCore Runtime is included.
Pickup service
- Python + FastAPI with an explicit state machine:
PAID → NOTIFIED → PICKED_UP → GUIDE_SENT. - The QR pass is a signed, single-use, rotating token:
$$ \text{token} = \text{order} \,|\, n \,|\, t_{\text{exp}} \,|\, \operatorname{HMAC\text{-}SHA256}K(\text{order} \,|\, n \,|\, t{\text{exp}}) $$
Every reschedule or reissue rotates the nonce $n$, so a screenshot of an old QR stops working, and a token cannot be reused after pickup.
- Dry-run and live modes build identical AWS requests. The web phone simulator renders exactly the
SendRcsMessagebody that AWS would receive. - Graceful degradation: SMS fallback covers RCS delivery failures, and a deterministic intent router answers in all three languages if Bedrock is unavailable.
The demo video was made programmatically with Remotion, using real screenshots of the running app and live Bedrock replies.
Challenges we ran into
- RCS isn't available in Korea yet. Korean numbers can't be registered as RCS test devices (
COUNTRY_NOT_ENABLED). We still created a real RCS agent and validated every payload, rich card and text with chips alike, against the live API withDryRun=True. We built a phone simulator that renders the exact request body, and kept SMS fallback as a first-class path. - Letting an AI change orders safely. A prompt can't be trusted to enforce authorization. We moved authorization out of the model into tool binding, and tested refusals for other customers' orders and forged postbacks.
- Compliance without friction. Buyer-only pickup and legal-age checks had to be strict at the counter yet explained kindly in chat. The agent knows the rules, and the server enforces them.
- Multilingual everywhere. Localizing the RCS card and chips, the SMS fallback, the agent's replies, the staff screen and the email, while keeping Korea's mandatory alcohol health warning in Korean in every email, plus a translation.
Accomplishments that we're proud of
- A real end-to-end agentic workflow across channels: RCS card → chat that changes the order → in-store QR + ID check → SES guide → follow-up in the same thread.
- Verified on AWS: the Bedrock agent ran live and its tool calls changed real orders. SES delivered real emails from ap-northeast-2. Both RCS payload types passed
SendRcsMessagevalidation. - Privacy and compliance by design: buyer-only pickup, legal-age check, no ID storage, and personal data processed In-Region in Seoul.
- Three languages supported end to end, with automatic switching.
What we learned
- Conversation is the missing piece in regulated retail. The same rules that make pickup painful (in person, own ID, no proxy) can be explained and enforced politely by an agent instead of a paper notice.
- The moment right after pickup is the best time to engage. The customer has the bottle in hand, so a wine guide is content they actually read.
- For agents that act, authorization belongs in the tools, not the prompt.
- Designing for channel fallback from day one (RCS → SMS, Bedrock → rules) is what makes a messaging experience production-ready.
What's next for Wine Pickup Concierge
- Deploy as Lambda + DynamoDB + API Gateway with CDK, with the agent on AgentCore Runtime and AgentCore Memory so conversations pick up where they left off.
- Add WhatsApp (AWS End User Messaging Social) for overseas and duty-free buyers, and let customers choose their preferred channel.
- Delivery and engagement analytics through SES/EUM configuration sets → EventBridge, to measure no-show rates and guide engagement.
- Mobile ID verification at the counter.
- Package it as a repeatable offering for any age-restricted or ID-checked pickup: wine and spirits, pharmacy, tobacco, rentals and ticketing.
Built With
- ai-???
- amazon-bedrock
- amazon-bedrock-agentcore
- amazon-ses
- amazon-sns
- amazon-web-services
- aws-end-user-messaging
- aws-lambda
- fastapi
- javascript
- python
- rcs
- sms