Hướng dẫn sử dụng Webhook
Cấu hình trên Admin: xem Hướng dẫn Admin — Auth Config và Webhook.
1. Lấy Webhook Config
Bước 1: Tìm TenantWebhook theo code
// Cách 1: Dùng TenantWebhookService
Optional<TenantWebhook> webhookOpt = tenantWebhookService.findByTenantIdAndCode(tenantId, "WEBHOOK_CODE");
// Cách 2: Dùng Repository trực tiếp (có filter status)
Optional<TenantWebhook> webhookOpt = tenantWebhookRepository
.findByTenantIdAndCodeAndStatus(tenantId, "WEBHOOK_CODE", TenantWebhookStatus.ACTIVE);
tenantId: ID của tenant cần gửi webhook"WEBHOOK_CODE": Khóa định danh của webhook (ví dụ:"NEBULA_SIGNAL_UPDATE")
Bước 2: Lấy danh sách TenantAuthConfig
TenantWebhook.tenantAuthConfigIds là chuỗi JSON chứa danh sách ID, ví dụ: [1, 2].
TenantWebhook webhookConfig = webhookOpt.get();
List<TenantAuthConfig> authConfigs = new ArrayList<>();
if (webhookConfig.getTenantAuthConfigIds() != null) {
List<Long> authConfigIds = MapperUtils.readValue(
webhookConfig.getTenantAuthConfigIds(),
new TypeReference<List<Long>>() {}
);
if (authConfigIds != null && !authConfigIds.isEmpty()) {
authConfigs = tenantAuthConfigRepository
.findAllByTenantIdAndIdIn(tenantId, authConfigIds);
}
}
2. Gửi Webhook
Sau khi có webhookConfig và authConfigs, gọi:
webhookService.sendWebhook(tenantId, payload, webhookConfig, authConfigs);
Tham số
| Tham số | Kiểu | Mô tả |
|---|---|---|
tenantId | Long | ID của tenant |
payload | Map<String, List<SignalDataDto>> | Dữ liệu gửi đi (key: identifier, value: danh sách data) |
webhookConfig | TenantWebhook | Config đã lấy ở bước 1 |
authConfigs | List<TenantAuthConfig> | Auth configs đã lấy ở bước 2 |
Hàm sendWebhook() tự động thực hiện
- Kiểm tra trạng thái webhook phải là
ACTIVE - Kiểm tra endpoint không null
- Serialize payload thành JSON
- Áp dụng authentication (API_KEY / BASIC / HMAC) vào header hoặc query param
- Tạo bản ghi
WebhookExecutionđể theo dõi - Gửi HTTP POST request với OkHttp3
- Cập nhật trạng thái execution (SUCCESS hoặc RETRY_FAILED)
- Ghi integration log
Lưu ý: Nếu gửi thất bại,
WebhookRetryWorkersẽ tự động retry theo policy đã cấu hình. Không cần xử lý retry thủ công.
3. Ví dụ đầy đủ
Tham khảo NebulaNotificationServiceImpl.java — ví dụ hoàn chỉnh cách lấy config và gửi webhook:
@Service
@RequiredArgsConstructor
public class MyNotificationServiceImpl {
private static final String MY_WEBHOOK_CODE = "MY_WEBHOOK_CODE";
private final TenantWebhookRepository tenantWebhookRepository;
private final TenantAuthConfigRepository tenantAuthConfigRepository;
private final WebhookService webhookService;
public void sendNotification(Long tenantId, Map<String, List<SignalDataDto>> payload) {
// 1. Lấy webhook config
Optional<TenantWebhook> webhookOpt = tenantWebhookRepository
.findByTenantIdAndCodeAndStatus(tenantId, MY_WEBHOOK_CODE, TenantWebhookStatus.ACTIVE);
if (webhookOpt.isEmpty()) {
log.warn("Webhook config not found for tenantId: {}, code: {}", tenantId, MY_WEBHOOK_CODE);
return;
}
TenantWebhook webhookConfig = webhookOpt.get();
// 2. Lấy auth configs
List<TenantAuthConfig> authConfigs = new ArrayList<>();
if (webhookConfig.getTenantAuthConfigIds() != null) {
try {
List<Long> authConfigIds = MapperUtils.readValue(
webhookConfig.getTenantAuthConfigIds(),
new TypeReference<List<Long>>() {}
);
if (authConfigIds != null && !authConfigIds.isEmpty()) {
authConfigs = tenantAuthConfigRepository
.findAllByTenantIdAndIdIn(tenantId, authConfigIds);
}
} catch (Exception e) {
authConfigs = new ArrayList<>();
}
}
// 3. Gửi webhook
webhookService.sendWebhook(tenantId, payload, webhookConfig, authConfigs);
}
}
4. Payload mẫu
Payload được gửi dưới dạng JSON:
{
"user_001": [
{
"ticker": "VNM",
"type": "BUY",
"volume": 100,
"date": "2024-03-28",
"createdDate": "2024-03-28T10:00:00"
},
{
"ticker": "FPT",
"type": "SELL",
"volume": 50,
"date": "2024-03-28",
"createdDate": "2024-03-28T10:05:00"
}
],
"user_002": [
{
"ticker": "HPG",
"type": "BUY",
"volume": 200,
"date": "2024-03-28",
"createdDate": "2024-03-28T10:10:00"
}
]
}
Lưu ý: Payload hiện tại dùng
Map<String, List<SignalDataDto>>. Nếu cần gửi loại dữ liệu khác, có thể thay đổi kiểu payload tương ứng.