Напоминания о записи в WhatsApp для клиник, салонов и автосервисов
Клиент записался на четверг и забыл. Кресло пустует, врач или мастер простаивает, а администратор весь вечер обзванивает завтрашних клиентов. Автоматическое напоминание в WhatsApp делает это за него: приходит вовремя, клиент отвечает одной цифрой, а запись в базе обновляется сама.
Гайд для клиник, салонов красоты, автосервисов и всех, кто работает по записи: когда напоминать, как принять подтверждение ответом «1» или «2», что делать с отменами и как не помешать живой переписке администратора.
Когда напоминать
На практике хорошо работают два напоминания:
- за сутки — чтобы клиент успел перенести визит, а вы — отдать время другому. Сюда же — подготовка: прийти натощак, взять документы на машину;
- за 2 часа — коротко: время и адрес. Это напоминание о том, что пора выходить.
Если запись сделана меньше чем за сутки, хватит второго. Ночью не пишите: держите отправку в пределах дня по Алматы, например с 8 до 21. Время в базе и в скрипте считайте в одном часовом поясе — проще всего в алматинском.
Не отправляйте все напоминания одной пачкой в 9 утра. Если за час с номера ушли первые сообщения 40+ новым людям, защита от рассылок на сутки закроет первые сообщения новым контактам. Лучше напоминать за 24 часа до каждого визита: отправка сама растянется на весь день вслед за расписанием.
Откуда брать записи
Источник любой, лишь бы скрипт мог прочитать записи на ближайшие сутки:
- своя CRM или база — прямой запрос к таблице записей;
- Google Таблица — отправка прямо из Apps Script;
- 1С — HTTP-запрос из конфигурации или выгрузка в промежуточный скрипт;
- сервис онлайн-записи — если у него есть API, вебхуки или выгрузка, сверьтесь с его документацией.
Минимум полей: телефон в формате 77011234567, имя, дата и время, услуга или специалист, статус записи и две отметки — отправлено ли напоминание за сутки и за 2 часа. Отметки защищают от дублей: скрипт запускается часто и видит одни и те же записи.
Тексты напоминаний
Здравствуйте, Айгерим! Напоминаем о записи в клинике «Здоровье»: завтра, 14 ноября, в 10:30. Памятку о подготовке к визиту пришлём отдельно.
Ответьте 1 — подтверждаю, 2 — не смогу прийти.Айгерим, ждём вас сегодня в 10:30. Адрес: Алматы, ул. Сатпаева, 30, вход со двора.Назовите себя в первой строке, укажите дату, время, услугу и адрес. Один вопрос и понятный способ ответить. Без рекламы и «кстати, у нас скидки» — это сервисное сообщение, которого клиент ждёт.
Настройка по шагам
Шаг 1. Подключите номер
Зарегистрируйтесь, пополните баланс и привяжите номер администратора по QR-коду или коду по номеру — около 5 минут. API-ключ — в разделе «API и MCP». Номер остаётся на телефоне: администратор пишет с него как раньше.
Шаг 2. Запустите скрипт напоминаний по cron
Скрипт запускается каждые 15 минут, выбирает записи, у которых подошло время напоминания, и отправляет их через POST /messages/send. Таблица appointments здесь — пример; подставьте запрос к своей базе.
# remind.py — cron: */15 * * * * python3 /opt/remind/remind.py (pip install requests)
import os, sqlite3, time
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
import requests
TZ = ZoneInfo("Asia/Almaty")
HEADERS = {"Authorization": "Bearer " + os.environ["WAPI_KEY"]}
FROM = os.environ.get("WAPI_FROM") # id номера из GET /numbers, если номеров несколько
PLACE, ADDRESS = "клиника «Здоровье»", "Алматы, ул. Сатпаева, 30"
PLAN = [ # отметка, окно «от–до» часов до визита, текст
("reminded_day", 3, 24, "Здравствуйте, {name}! Напоминаем о записи: {place}, {date} в {time}, {service}.\n"
"Ответьте 1 — подтверждаю, 2 — не смогу прийти."),
("reminded_soon", 0, 2, "{name}, ждём вас сегодня в {time}. Адрес: {address}."),
]
db = sqlite3.connect("bookings.db")
db.row_factory = sqlite3.Row
now = datetime.now(TZ).replace(tzinfo=None)
fmt = lambda d: d.strftime("%Y-%m-%d %H:%M") # starts_at хранится как «2026-11-14 10:30» по Алматы
if 8 <= now.hour < 21:
for flag, h_from, h_to, template in PLAN:
rows = db.execute(f"SELECT * FROM appointments WHERE status IN ('booked', 'confirmed') AND {flag} = 0 "
"AND starts_at > ? AND starts_at <= ?",
(fmt(now + timedelta(hours=h_from)), fmt(now + timedelta(hours=h_to)))).fetchall()
for a in rows:
t = datetime.strptime(a["starts_at"], "%Y-%m-%d %H:%M")
text = template.format(name=a["name"], place=PLACE, address=ADDRESS, service=a["service"],
date=f"{t:%d.%m}", time=f"{t:%H:%M}")
r = requests.post("https://wapi.kz/api/v1/messages/send", headers=HEADERS,
json={"to": a["phone"], "text": text, **({"from": int(FROM)} if FROM else {})}, timeout=15)
code = r.json().get("code")
if r.status_code == 200 or code in ("invalid_to", "empty_text", "text_too_long"):
db.execute(f"UPDATE appointments SET {flag} = 1 WHERE id = ?", (a["id"],)) # негодный номер — проверьте запись вручную
db.commit()
elif code != "rate_limited":
raise SystemExit(f"Стоп: {r.json().get('error')}") # лимит, пауза, номер отключён
time.sleep(5) # первые сообщения новым людям — не чаще раза в 5 секундОкно «от 3 до 24 часов» — это и есть «записи на завтра», только разобранные по времени визита. Если сервер живёт в другом часовом поясе, cron всё равно подойдёт: даты скрипт считает по Алматы.
Шаг 3. Примите ответы «1» и «2» вебхуком
Задайте адрес вебхука в кабинете с секретом в адресе. Обработчик отвечает 200 сразу, а запись обновляет в отдельном потоке.
# hook.py — pip install flask requests
import os, sqlite3, threading
from datetime import datetime
from zoneinfo import ZoneInfo
import requests
from flask import Flask, request
app = Flask(__name__)
REPLIES = {"1": ("confirmed", "Спасибо, запись подтверждена. Ждём вас!"),
"2": ("cancelled", "Поняли, запись отменили. Администратор напишет вам, чтобы подобрать другое время.")}
def notify_admin(phone, booking_id):
print("Отмена записи", booking_id, phone) # замените на сообщение в Telegram или задачу в CRM
def handle(phone, answer, number_id):
status, reply = REPLIES[answer]
db = sqlite3.connect("bookings.db")
now = datetime.now(ZoneInfo("Asia/Almaty")).strftime("%Y-%m-%d %H:%M")
row = db.execute("SELECT id FROM appointments WHERE phone = ? AND status = 'booked' AND reminded_day = 1 "
"AND starts_at > ? ORDER BY starts_at LIMIT 1", (phone, now)).fetchone()
if not row:
return # подтверждать нечего — ответит человек
db.execute("UPDATE appointments SET status = ? WHERE id = ?", (status, row[0]))
db.commit()
requests.post("https://wapi.kz/api/v1/messages/send", timeout=15,
headers={"Authorization": "Bearer " + os.environ["WAPI_KEY"]},
json={"to": phone, "text": reply, "from": number_id})
if status == "cancelled":
notify_admin(phone, row[0])
@app.post("/whatsapp/webhook")
def webhook():
if request.args.get("token") != os.environ["WAPI_HOOK_TOKEN"]:
return "", 403
e = request.get_json(silent=True) or {}
p = e.get("payload") or {}
answer = (p.get("body") or "").strip()
if e.get("event") == "message" and p.get("from", "").endswith("@c.us") and answer in REPLIES:
threading.Thread(target=handle, args=(p["from"].split("@")[0], answer, e["wapi"]["number_id"])).start()
return "", 200 # остальные сообщения — живой разговорШаг 4. Проверьте на себе
Создайте запись на свой номер на завтра, дождитесь напоминания, ответьте «1», затем повторите с «2». Статус в базе должен меняться, а отмена — доходить до администратора.
Отмены, переносы и живой администратор
На «2» не пытайтесь перенести запись автоматически: освободите время и передайте клиента администратору — он предложит варианты. Если запись отменили или перенесли в CRM до напоминания, скрипт её не тронет: он читает свежий статус при каждом запуске. При переносе сбросьте отметки — клиент получит напоминание о новом времени. Молчание не считайте отменой: многие читают и не отвечают, поэтому напоминание за 2 часа уходит и тем, кто не подтвердил.
Номер остаётся на телефоне, поэтому все ответы клиентов администратор видит в обычном WhatsApp. Если клиент написал не «1» и не «2», а «можно на час позже?», обработчик промолчит, и ответит человек. Сообщения администратора с телефона приходят вебхуком message.out, а в журнале помечены source phone — так любая автоматика понимает, что разговор ведёт человек.
Лимиты
Напоминание часто оказывается первым сообщением человеку, а такие сообщения ограничены отдельно (подробнее). Первые 2 недели после подключения идёт прогрев: в дни 1–3 — до 20 новых контактов в сутки, в дни 4–7 — до 40, в дни 8–14 — до 80. Дальше на уровне «Хороший» — 150 новых контактов и 1 000 сообщений в сутки. Второе напоминание — уже не первое сообщение человеку, поэтому в лимит новых контактов не идёт.
Кончился лимит — скрипт получит new_contacts_limit и остановится. Остальным напомнит администратор, как раньше, а завтра лимит обновится. Платы за сообщения нет: номер стоит 9 900 ₸ в месяц (цены).
Частые вопросы
Нужно ли согласие клиента на напоминания?
Клиент оставил номер, чтобы записаться, и ждёт сообщений о визите. Но лучше сказать прямо при записи: «Напомним в WhatsApp за день». Правовые вопросы обработки персональных данных уточните у юриста.
Что, если клиент ответит не цифрой?
Обработчик реагирует только на «1» и «2». Всё остальное остаётся живому администратору — он видит сообщение на телефоне и отвечает сам.
Что делать, если у клиента нет WhatsApp?
Проверьте номер через /contacts/check при записи — до 200 проверок в сутки на номер. Таким клиентам напоминайте звонком или SMS.
Можно ли отправить схему проезда или памятку файлом?
Да: фото и файлы отправляются по публичной ссылке, размер — до 2 ГБ, это лимит WhatsApp. Подробнее — в гайде про отправку файлов.
Подойдёт ли это для салона без своего сервера?
Отправлять можно прямо из Google Таблицы через Apps Script. Ответы «1»/«2» надёжнее принимать через n8n или Make и уже оттуда писать в таблицу — см. Google Таблицы и отрасли: салоны красоты, клиники, автосервисы.
Подключите WhatsApp к своим системам
9 900 ₸ в месяц за номер, без платы за сообщения. Сервер в Казахстане, оплата Kaspi или счётом на ТОО/ИП. Подключение — около 5 минут.