Webhook Discord
This commit is contained in:
@@ -52,6 +52,7 @@ const {
|
||||
getBillingSummary,
|
||||
getEndpointResponse,
|
||||
isInsufficientCreditsError,
|
||||
claimNotificationOnce,
|
||||
simulatePurchase,
|
||||
simulateWebhook,
|
||||
syncRevenueCatCustomerInfo,
|
||||
@@ -67,6 +68,7 @@ const {
|
||||
} = require('./lib/openai');
|
||||
const { applyCatalogGrounding, normalizeText } = require('./lib/scanGrounding');
|
||||
const { ensureStorageBucketWithRetry, uploadImage, isStorageConfigured } = require('./lib/storage');
|
||||
const { isPurchaseEventType, notifyPurchase, notifyNewUser } = require('./lib/discord');
|
||||
const {
|
||||
exchangeCodeForTokens: exchangeTiktokCode,
|
||||
getTiktokTokens,
|
||||
@@ -521,6 +523,28 @@ app.post('/api/revenuecat/webhook', express.json({ limit: '1mb' }), async (reque
|
||||
}
|
||||
const eventPayload = request.body?.event || request.body;
|
||||
const result = await syncRevenueCatWebhookEvent(db, eventPayload);
|
||||
if (isPurchaseEventType(eventPayload?.type)) {
|
||||
// RevenueCat delivers webhooks at-least-once; dedupe notifications by
|
||||
// event id so redeliveries don't ping the sales channel twice.
|
||||
const eventId = String(eventPayload?.id || eventPayload?.transaction_id || '').trim();
|
||||
const isFirstDelivery = eventId
|
||||
? await claimNotificationOnce(db, `discord-purchase-event:${eventId}`)
|
||||
: true;
|
||||
if (isFirstDelivery) {
|
||||
// RevenueCat's `price` is always USD; only `price_in_purchased_currency`
|
||||
// matches the `currency` field.
|
||||
const hasLocalPrice = typeof eventPayload?.price_in_purchased_currency === 'number';
|
||||
notifyPurchase({
|
||||
productId: eventPayload?.product_id,
|
||||
price: hasLocalPrice ? eventPayload.price_in_purchased_currency : eventPayload?.price,
|
||||
currency: hasLocalPrice ? eventPayload?.currency : 'USD',
|
||||
store: eventPayload?.store,
|
||||
isTrial: String(eventPayload?.period_type || '').toUpperCase() === 'TRIAL',
|
||||
isRenewal: String(eventPayload?.type || '').toUpperCase() === 'RENEWAL',
|
||||
isSandbox: String(eventPayload?.environment || '').toUpperCase() === 'SANDBOX',
|
||||
});
|
||||
}
|
||||
}
|
||||
response.status(200).json({ received: true, syncedAt: result.syncedAt });
|
||||
} catch (error) {
|
||||
const payload = toApiErrorPayload(error);
|
||||
@@ -1059,6 +1083,11 @@ app.post('/auth/signup', async (request, response) => {
|
||||
}
|
||||
const user = await authSignUp(db, email, name, password);
|
||||
const token = issueToken(user.id, user.email, user.name);
|
||||
notifyNewUser({
|
||||
provider: 'email',
|
||||
platform: request.header('x-app-platform'),
|
||||
appVersion: request.header('x-app-version'),
|
||||
});
|
||||
response.status(201).json({ userId: user.id, email: user.email, name: user.name, token });
|
||||
} catch (error) {
|
||||
const status = error.status || 500;
|
||||
@@ -1089,6 +1118,13 @@ app.post('/auth/apple', async (request, response) => {
|
||||
}
|
||||
const user = await authSignInWithApple(db, identityToken, { appleUser, email, name });
|
||||
const token = issueToken(user.id, user.email, user.name);
|
||||
if (user.isNewUser) {
|
||||
notifyNewUser({
|
||||
provider: 'apple',
|
||||
platform: request.header('x-app-platform'),
|
||||
appVersion: request.header('x-app-version'),
|
||||
});
|
||||
}
|
||||
response.status(200).json({
|
||||
userId: user.id,
|
||||
email: user.email,
|
||||
|
||||
Reference in New Issue
Block a user