Чтобы записи уезжали в Google Calendar, платформе нужно собственное приложение в Google — пара значений Client ID и Client secret. Это делается один раз на всю платформу: салоны и мастера потом просто нажимают «Подключить». Ниже — путь по консоли Google с кадрами каждого экрана и кнопками «Копировать» для строк, которые Google сверяет символ в символ.
Кому что делать: шаги 1–7 выполняет администратор платформы (у него доступ к серверу), шаг 8 — владелец салона или мастер в своём кабинете. Полей для ключей Google в кабинете нет и не будет: ключ один на всех, и хранится он на сервере.
1. Проект и включение Calendar API
- Откройте console.cloud.google.com и создайте проект (например izzicrm-calendar).
- APIs & Services → Library → найдите Google Calendar API → Enable.
Без «Enable» все остальные шаги пройдут успешно, а первый же вызов календаря вернёт ошибку доступа.
2. Экран согласия: кто и о чём просит
Раздел Google Auth Platform (в старых кабинетах — OAuth consent screen). User type — External. Название приложения и почта поддержки видны на экране согласия, поэтому пишите то, что клиент узнает: «IZZI CRM». Домен приложения и ссылки на политику приватности и условия — страницы платформы.
3. Test users — пока приложение не проверено Google
Audience → Test users → Add users. Внесите Google-аккаунты всех, кто будет подключать календарь: владельцев салонов и мастеров. Потолок — 100 аккаунтов на всю платформу; после прохождения verification список вести не нужно.
«Access blocked: … has not completed the Google verification process» у пользователя означает ровно одно — его почты нет в этом списке. Кабинет тут ни при чём: кнопка отработала, отказ рисует Google.
4. Права (scopes) — ровно три
Data Access → Add or remove scopes. Нужны три и ни одного лишнего — они совпадают с тем, что запрашивает код:
https://www.googleapis.com/auth/calendar.events
openid
emailcalendar.events — sensitive scope. Именно из-за него до verification действует потолок test users.
5. OAuth-клиент и адрес возврата
Credentials → Create credentials → OAuth client ID, тип приложения — Web application. Единственное, что нужно заполнить, — адрес возврата:
https://izzicrm.ru/api/v1/calendar-sync/google/callbackAuthorized JavaScript origins оставляем пустым: редирект серверный, JS-виджета Google у нас нет.
Мастер Google кладёт поле Authorized JavaScript origins ВЫШЕ Authorized redirect URIs, и адрес с путём естественно уходит не туда. Признак ошибки — Invalid Origin: URIs must not contain a path. Адрес с /api/v1/… идёт только во второе поле.
6. Где на самом деле лежит секрет
После Create Google показывает окно с Client ID и кнопкой Download JSON. Скопируйте Client ID сразу. Секрет ищите в карточке клиента (Clients → ваш клиент) или внутри скачанного JSON — он начинается с GOCSPX-.
Client ID заканчивается на .apps.googleusercontent.com, секрет начинается с GOCSPX-. Обе строки — из одного клиента: пара от разных клиентов даёт invalid_client.
Финальный экран мастера client_secret не показывает вовсе — только Client ID и «Download JSON». Это сбивает: люди закрывают окно и ищут секрет заново. Он всегда доступен в карточке клиента, терять его не страшно — но и пересылать в чат, где он останется навсегда, не нужно: при ротации секрета все висящие OAuth-переходы обрываются.
7. Куда вставить
Обе строки уезжают в окружение сервера (переменные GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET и адрес возврата) и применяются перезапуском API — кода это не меняет, миграций не требует. Если вы владелец салона: передайте значения администратору платформы, вставлять их в кабинете некуда.
Признак, что ключи доехали: на экране Настройки → Уведомления кнопка «Подключить календарь салона» ведёт на экран согласия Google, а не показывает сообщение «Google Calendar не настроен на сервере».
8. Подключение салона — и галочка, которую нельзя снимать
- Настройки → Уведомления → блок «Календарь салона» → «Подключить календарь салона». Личный календарь мастера подключается там же, в карточке сотрудника, вкладка «Календарь».
- Выберите Google-аккаунт — тот, что внесён в Test users (шаг 3).
- На экране согласия оставьте отмеченной галочку про события календаря и нажмите Continue.
Sensitive-права Google показывает отдельными галочками. Снять её и нажать «Continue» — обычная ошибка: экран выглядит успешным.
Со снятой галочкой Google выдаёт токен без доступа к календарю и ничего об этом не сообщает. Кабинет такую привязку не создаёт вовсе: вы вернётесь с сообщением о том, что доступ к календарю не выдан, и достаточно нажать «Подключить» ещё раз, оставив галочку. Рабочая привязка при этом не затирается.
Если что-то пошло не так
- «Google Calendar не настроен на сервере» — ключей на сервере ещё нет (шаги 1–7) или API не перезапускали после их добавления.
- redirect_uri_mismatch — адрес возврата в консоли не совпадает с нашим символ в символ; сверьте строку из шага 5 (частое: лишний слэш в конце, http вместо https, адрес попал в поле origins).
- Access blocked — почта не внесена в Test users (шаг 3).
- invalid_client — Client ID и секрет от разных клиентов или секрет скопирован с пробелом.
- Подключено, но записи не уезжают — проверьте, включён ли тумблер «Синхронизировать записи», и что подключён тот аккаунт, в календарь которого смотрите. Уже существующие записи в календарь не переносятся сами: для них есть кнопка «Выгрузить».
Чек-лист
- Проект создан, Google Calendar API включён (Enable).
- Экран согласия заполнен, User type — External.
- В Test users внесены все, кто будет подключать календарь.
- В Data Access ровно три права, среди них calendar.events.
- Тип клиента — Web application, адрес возврата вставлен в Authorized redirect URIs.
- Client ID и Client secret скопированы из ОДНОГО клиента и переданы администратору платформы.
- Кнопка «Подключить календарь салона» ведёт на экран согласия Google.
- На экране согласия галочка про календарь осталась отмеченной, кабинет показывает «Подключён — почта».