Esta página aún no está traducida al español — mostrando la versión en inglés.

Wasi real estate

Let your chatbot search your Wasi CRM's listings for sale or rent, returning up to 5 properties as text (and as cards for rich channels).

The Wasi Real Estate tool (key: "wasi", module Chatbotgen.AI.Tools.Wasi) connects your chatbot to the Wasi API at https://api.wasi.co/v1.

Tool description (verbatim from seed)

Wasi Real Estate — Search properties from Wasi CRM. The chatbot guides users to search properties for sale or rent, showing results as cards with images and details.

Configuration fields

Two fields, both required:

  • Company ID (key: id_company, type: text, required)
  • API Token (key: wasi_token, type: password, required)

Get both from your Wasi account.

Function definition (what the LLM sees)

Verified from wasi.ex:

  • Name: search_properties
  • Description: "Search real estate properties for sale or rent. Always ask the user for city and whether they want sale or rent before calling."
  • Parameters:
Param Type Required Description
id_city string yes "ID de la ciudad donde se busca la propiedad. Ver contexto para ciudades disponibles."
for_sale boolean yes "true si se busca propiedades en venta."
for_rent boolean yes "true si se busca propiedades en renta."
min_bedrooms number no "Número mínimo de habitaciones."
max_bedrooms number no "Número máximo de habitaciones."
min_price number no "Precio mínimo de la propiedad."
max_price number no "Precio máximo de la propiedad."

System prompt injection

The tool calls fetch_cities(config) at conversation time (cached for 5 minutes per company) and injects a Spanish prompt block. Verbatim from wasi.ex's system_context/1:

[WASI - Búsqueda de Propiedades]
Tienes la función "search_properties" para buscar propiedades inmobiliarias. Guía al usuario preguntándole qué tipo de propiedad busca.
SIEMPRE pregunta si quiere buscar para VENTA o para RENTA. Nunca busques por ambos al mismo tiempo.
NUNCA respondas "no estoy seguro" — siempre busca en Wasi lo que pide el usuario.
Si no encuentras propiedades, enfócate en la próxima búsqueda.
IMPORTANTE: Necesitas la ciudad y si es venta o renta para buscar.
Muestra los resultados de forma atractiva con imágenes, precios, características y links.
Cuando nombres ciudades, NUNCA digas el id_city — solo muestra el nombre.

Tipos de propiedad:
Casa (1), Apartamento (2), Local comercial (3), Oficina (4), Lote/Terreno (5),
Lote Comercial (6), Finca (7), Bodega (8), Chalet (10), Casa de Campo (11),
Hoteles (12), Aparta-Estudio (14), Consultorio (15), Edificio (16),
Duplex (20), Bungalow (22), Casa de Playa (24), Garaje (26), Cabañas (28).

Ciudades disponibles:
{city_lines}

Runtime flow (verified from wasi.ex's call/2)

  1. The tool builds query params for /property/search: id_company, wasi_token, id_city, for_sale ("1" or "0"), for_rent ("1" or "0"), plus any optional filters set on the call (min/max bedrooms, min/max price).
  2. Req.get("https://api.wasi.co/v1/property/search", params, receive_timeout: 15_000).
  3. If the response is HTTP 200 and a map, extract_properties/1 strips status and total, keeps all map values, and takes up to 5 properties.
  4. If the property list is empty: returns {:ok, "No se encontraron propiedades con esos criterios."} (text only, no rich response).
  5. Otherwise returns:
    • Text — each property formatted as **{title}**\n{description up to 200 chars}\nPrecio: {price}\nHabitaciones: {n}\nBaños: {n}\nGarajes: {n}\nLink: {url} (fields omitted when empty/nil). Properties separated by \n\n---\n\n.
    • Rich response{"title": "Propiedades encontradas", "display_template": "cards", "cards": [...]}. Each card:
      • title — property title (or "Propiedad" as fallback)
      • subtitle — first 150 chars of the description
      • image_url — from main_image.url (or main_image itself if it's a string)
      • characteristics — up to 4 {title, value} entries: Precio, Habitaciones, Baños, Garajes (only those with non-empty values)
      • buttons[{type: "link", title: "Ver más", link: {p.link}}] if p.link is set, else []

Error paths

  • Non-200 response: {:error, "Wasi API returned status {n}"}
  • Transport error: {:error, "Wasi request failed: {reason}"}
  • Exception during the call: {:error, "Wasi error: {message}"}

The AI.ToolRunner catches those {:error, reason} returns and feeds "Error: {reason}" back to the LLM as the tool message — so the chatbot sees the error text and decides how to recover.

Price formatting

property_price/1 returns:

  • p["sale_price_label"] if p["for_sale"] == "true" and the label is non-empty
  • p["rent_price_label"] if p["for_rent"] == "true" and the label is non-empty
  • "No especificado" otherwise (and in that case, Precio is omitted from characteristics)

City cache

fetch_cities/1 is memoized via AI.Tools.Cache under the key "wasi_cities:{id_company}" with TTL 5 minutes. On cache miss it calls /location/cities-with-property with the company credentials.

Plan notes

The Tools page (and all tool enablement) sits behind the AI Tools feature, advertised in the feature-lock card as Growth — $79/mo. See Plans & pricing.