Skip to main content
A hotel chain wants one WhatsApp assistant per hotel. Every hotel has its own name, check-in times, amenities, PMS code, payment merchant and escalation rules. Writing one agent per hotel means 90 copies of the same code. Writing one agent with the hotels hardcoded means a deploy every time the front desk changes a check-out time. This guide builds one agent that serves every hotel:
  • each hotel is an item of a collection, edited by the operations team in the portal;
  • the Conversation Hub sends the id of the WhatsApp number that received the message (phoneNumberId), and the agent uses it to pick the hotel;
  • a new hotel goes live by adding an item in the portal and listing its number. No deploy.

1. Declare the hotel schema

manifest/index.ts
What each piece buys you in the portal:
  • itemLabel: 'name' lists the hotels by name, and itemSubtitle: 'pms.propertyCode' shows the PMS code next to it, so two “Hotel Centro” in different cities are easy to tell apart.
  • The nested objects (amenities, pms, payment, handoff) become sub-sections of each hotel, reachable from the side rail.
  • .min(1) on name, propertyCode and merchantId makes them required: a hotel can’t be saved without them.
  • Fields with .default() come pre-filled for every new hotel.

2. Route by number

main.ts
A few choices in this code:
  • The Hub sends phoneNumberId at the top of the request body, next to metadata (which carries conversationId, contactPhone and contactName). The portal tester and rf test send metadata only, so numberOf reads the playground value first and the Hub field after it.
  • An unknown number hands off instead of guessing a hotel. A guest of hotel A should never get hotel B’s prices because a number wasn’t listed yet.
  • hotelId and configInfo() in the output let you trace, in the execution logs, which hotel and which config version produced each answer.
Keep the PMS and payment calls in tools that receive match.hotel.pms and match.hotel.payment as parameters. The tool code stays the same for every hotel; only the config changes.

3. Deploy and add the first hotels

Open the agent in the portal and go to Configuration. In staging, click + next to Hotels, type the name (the id is suggested from it), and fill in the fields. Required fields are marked, and the save stays blocked until they are filled.
Hotel form in dark mode with the Amenities sub-section selected

Each hotel opens as one form, with its sub-sections in the rail

To bring a batch of hotels in from a spreadsheet, declare them in manifest/staging.json and deploy once. They show up in the portal and the team can adjust them from there:
manifest/staging.json

4. Test before going live

In the agent tester, pick the Hotel Copacabana scenario (from the playground fixtures) and send a message: the answer should use Copacabana’s check-in time. Then pick Number without a hotel and confirm the handoff. Locally, pull the staging values and run:

5. Promote

When staging is right, click Promote to production in the Configuration tab. The dialog lists every field and hotel that changes. Promote the agent code first if this is the first version with the hotels field.

Operating it day to day

If two hotels list the same phone number id, the agent picks the first one it finds. When you move a number between hotels, remove it from the old hotel in the same save.

Next steps

Agent Config

Every schema type, UI hint and CLI command

Conversation Hub SDK

Reply, send media and hand off to humans from the agent