I Built a Hotel Concierge Line with Telnyx Voice, SMS, and Slack

I Built a Hotel Concierge Line with Telnyx Voice, SMS, and Slack

我利用 Telnyx 的语音、短信和 Slack 功能构建了一条酒店礼宾专线

Hotel guests do not care whether the front desk is staffed. They want to text or call one number and have their room service, housekeeping, concierge, or maintenance request handled. A concierge line is a good test case for voice AI because the workflow is familiar and the volume is real.

酒店客人并不关心前台是否有工作人员值班。他们只想通过拨打或发送短信到一个号码,就能处理客房服务、家政服务、礼宾服务或维修请求。礼宾专线是测试语音 AI 的绝佳案例,因为其工作流程非常直观,且业务量真实存在。

The Telnyx code example is: https://github.com/team-telnyx/telnyx-code-examples/tree/main/hotel-guest-services-python It is a Python Flask app that combines Telnyx Voice, AI Inference, Messaging, and Slack into a small demo you can clone and run in a few minutes.

Telnyx 代码示例地址:https://github.com/team-telnyx/telnyx-code-examples/tree/main/hotel-guest-services-python 这是一个基于 Python Flask 的应用程序,它将 Telnyx 语音、AI 推理、消息传递和 Slack 集成在一个小型演示中,你可以在几分钟内克隆并运行它。

The Flow

流程

A guest calls or texts the Telnyx number. The Flask app receives the webhook, looks up the room by caller ID, and either greets the guest by name or asks for the room number. Each request is sent to Telnyx AI Inference, which classifies it into room_service, housekeeping, concierge, or maintenance. Urgent phrases (fire, flood, leak, locked out, gas, medical) override the LLM and route the request as urgent. The request is appended to a log, the guest gets an SMS confirmation, and staff get a Slack alert with the right emoji for the department. When staff mark the request complete, the guest gets another SMS.

客人拨打或发送短信至 Telnyx 号码。Flask 应用接收 Webhook,通过来电显示(Caller ID)查找房间号,并根据情况直接称呼客人姓名或询问房间号。每个请求都会发送至 Telnyx AI 推理引擎,将其分类为客房服务、家政、礼宾或维修。紧急短语(如火灾、水灾、漏水、被锁门外、煤气、医疗)会绕过大模型(LLM),直接将请求标记为紧急。请求会被记录到日志中,客人会收到短信确认,员工则会收到带有对应部门表情符号的 Slack 提醒。当员工将请求标记为完成后,客人会收到另一条短信。

Why I Like This Example

为什么我喜欢这个示例

It is small enough to demo live, but it covers the parts that often get cut from a “Hello World” voice AI demo:

  • Caller-ID-based room lookup, with a regex-based fallback for unknown callers
  • A constrained JSON system prompt so the LLM returns structured output you can trust
  • An urgent-phrase override that does not depend on the LLM getting it right
  • Slack alerts that match the department
  • Idempotent webhook handling so retries do not double-log requests

它足够精简,适合现场演示,但涵盖了许多“Hello World”级语音 AI 演示中常被忽略的部分:

  • 基于来电显示的房间查找功能,以及针对未知来电者的正则表达式回退机制
  • 约束性的 JSON 系统提示词,确保大模型返回可信的结构化输出
  • 不依赖大模型判断的紧急短语覆盖机制
  • 与部门匹配的 Slack 提醒
  • 幂等的 Webhook 处理,确保重试不会导致请求被重复记录

That makes it useful as a starting template for any single-vertical phone service where one phone number handles a small set of structured requests.

这使得它成为任何单一垂直领域电话服务的理想入门模板,即通过一个电话号码处理一组结构化的请求。

Run It Locally

本地运行

git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/hotel-guest-services-python
cp .env.example .env
pip install -r requirements.txt
python app.py

Expose the webhook: ngrok http 5000 In the Telnyx Portal, set the Voice API app webhook URL to https://<ngrok-id>.ngrok-free.app/webhooks/voice and the Messaging Profile inbound webhook URL to https://<ngrok-id>.ngrok-free.app/webhooks/sms. Call or text the Telnyx number to test.

暴露 Webhook:ngrok http 5000 在 Telnyx 门户中,将 Voice API 应用的 Webhook URL 设置为 https://<ngrok-id>.ngrok-free.app/webhooks/voice,并将 Messaging Profile 的入站 Webhook URL 设置为 https://<ngrok-id>.ngrok-free.app/webhooks/sms。拨打或发送短信至 Telnyx 号码进行测试。

What To Demo

演示建议

I would keep the demo short:

  1. Call from a phone matching room 205. Say “Can I order a club sandwich and a sparkling water please?”
  2. Show the open request in curl http://localhost:5000/requests.
  3. Show the Slack alert in the staff channel.
  4. Mark it complete with curl -X POST http://localhost:5000/requests/0/complete.
  5. Show the fulfilment SMS on the guest phone.
  6. Then call from an unknown number, say “Room 205 please”, and make a second request to show the unknown-caller path.

我建议演示保持简洁:

  1. 用匹配 205 房间的手机拨打电话,说:“请问可以点一份俱乐部三明治和一瓶气泡水吗?”
  2. 通过 curl http://localhost:5000/requests 展示待处理请求。
  3. 在员工频道展示 Slack 提醒。
  4. 使用 curl -X POST http://localhost:5000/requests/0/complete 将其标记为完成。
  5. 在客人手机上展示完成确认短信。
  6. 然后用一个未知号码拨打,说“请转 205 房间”,并发出第二个请求,以展示未知来电者的处理路径。

Where To Take It Next

未来改进方向

The demo uses in-memory state, which is fine for learning. Production would replace ROOMS and service_requests with your PMS database (Opera, Mews, Cloudbeds), persist call state and event IDs to Redis, queue Slack and SMS side effects, add call recording for QA, and map urgent requests to a real paging system instead of Slack.

该演示使用内存状态,这对于学习来说足够了。在生产环境中,应将 ROOMSservice_requests 替换为你的 PMS 数据库(如 Opera、Mews、Cloudbeds),将通话状态和事件 ID 持久化到 Redis,对 Slack 和短信副作用进行排队处理,增加通话录音以供质量保证(QA)使用,并将紧急请求映射到真正的寻呼系统,而不是仅发送 Slack 提醒。

Resources

资源