Обновление дашборда Mode при завершении задания
Введение
Это руководство научит вас обновлять дашборд Mode после того, как задание dbt успешно завершилось и появились свежие данные. Интеграция будет:
- Получать уведомление вебхука в Zapier
- Запускать обновление отчета в Mode
Хотя мы используем API Mode для конкретного примера, принципы легко применимы к вашему инструменту на выбор.
Предварительные требования
Для настройки интеграции вам необходимо быть знакомым со следующим:
- dbt Webhooks
- Zapier
- API Mode
Создание нового Zap в Zapier
Используйте Webhooks by Zapier в качестве триггера и Catch Raw Hook в качестве события. Если вы не собираетесь проверять подлинность вашего вебхука (не рекомендуется!), то можете выбрать Catch Hook вместо этого.
Нажмите Continue, затем скопируйте URL вебхука.

Настройка нового вебхука в dbt
Подробные инструкции см. в разделе Create a webhook subscription. В качестве события необходимо выбрать Run completed, а также изменить список Jobs так, чтобы он содержал только те задания, завершение которых должно запускать обновление отчёта.
Запомните секретный ключ вебхука для дальнейшего использования.
После того как вы протестировали эндпоинт в dbt, вернитесь в Zapier и нажмите Test Trigger — это создаст пример тела webhook на основе тестового события, отправленного из dbt.
Значения в примере тела жестко закодированы и не отражают ваш проект, но они дают Zapier правильно сформированный объект во время разработки.
Хранение секретов
На следующем шаге вам понадобятся Webhook Secret Key из предыдущего шага, а также dbt personal access token или service account token, а также Mode API token and secret.
Zapier позволяет хранить секреты, что предотвращает отображение ваших ключей в открытом виде в коде Zap. Вы сможете получить к ним доступ через утилиту StoreClient.
Это руководство предполагает, что имена секретных ключей: DBT_WEBHOOK_KEY, MODE_API_TOKEN и MODE_API_SECRET. Если вы используете другие имена, убедитесь, что вы обновили все ссылки на них в примере кода.
Это руководство использует краткосрочное действие кода для хранения секретов, но вы также можете использовать инструмент, такой как Postman, для взаимодействия с REST API или создать отдельный Zap и вызвать Set Value Action.
a. Создание подключения Storage by Zapier
Если у вас его еще нет, перейдите на https://zapier.com/app/connections/storage и создайте новое подключение. Запомните сгенерированный UUID секрет для дальнейшего использования.
b. Добавьте временный шаг с кодом
Выберите Run Python в качестве события. Выполните следующий код:
store = StoreClient('abc123') # замените на ваш UUID secret
store.set('DBT_WEBHOOK_KEY', 'abc123') # замените на ваш API token <Constant name="cloud" />
store.set('MODE_API_TOKEN', 'abc123') # замените на ваш Mode API Token
store.set('MODE_API_SECRET', 'abc123') # замените на ваш Mode API Secret
Протестируйте шаг. Вы можете удалить это действие, когда тест пройдет успешно. Ключ будет оставаться сохраненным, пока к нему обращаются хотя бы раз в три месяца.
Добавление действия кода
Выберите Code by Zapier в качестве приложения и Run Python в качестве события.
В области Set up action добавьте два элемента в Input Data: raw_body и auth_header. Свяжите их с полями 1. Raw Body и 1. Headers Http Authorization из шага Catch Raw Hook выше.

В поле Code вставьте следующий код, заменив YOUR_SECRET_HERE в конструкторе StoreClient на секрет, который вы создали при настройке интеграции Storage by Zapier (а не ваш секрет <Constant name="cloud" />), а также установив переменные account_username и report_token в реальные значения.
Код ниже проверит подлинность запроса, затем отправит команду run report в API Mode для данного токена отчета.
import hashlib
import hmac
import json
#замените на токен отчета, который вы хотите запустить
account_username = 'YOUR_MODE_ACCOUNT_USERNAME_HERE'
report_token = 'YOUR_REPORT_TOKEN_HERE'
auth_header = input_data['auth_header']
raw_body = input_data['raw_body']
# Доступ к секретным учетным данным
secret_store = StoreClient('YOUR_SECRET_HERE')
hook_secret = secret_store.get('DBT_WEBHOOK_KEY')
username = secret_store.get('MODE_API_TOKEN')
password = secret_store.get('MODE_API_SECRET')
# Убедитесь, что вебхук пришёл от dbt
signature = hmac.new(hook_secret.encode('utf-8'), raw_body.encode('utf-8'), hashlib.sha256).hexdigest()
if signature != auth_header:
raise Exception("Calculated signature doesn't match contents of the Authorization header. This webhook may not have been sent from <Constant name="cloud" />.")
full_body = json.loads(raw_body)
hook_data = full_body['data']
if hook_data['runStatus'] == "Success":
# Создание запуска отчета с помощью API Mode
url = f'https://app.mode.com/api/{account_username}/reports/{report_token}/run'
params = {
'parameters': {
"user_id": 123,
"location": "San Francisco"
}
}
headers = {
'Content-Type': 'application/json',
'Accept': 'application/hal+json'
}
response = requests.post(
url,
json=params,
headers=headers,
auth=HTTPBasicAuth(username, password)
)
response.raise_for_status()
return
Тестирование и развертывание
Вы можете повторять шаг кода, изменяя код и затем снова запуская тест. Когда вы будете довольны результатом, вы можете опубликовать ваш Zap.