-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathserver.js
More file actions
136 lines (115 loc) · 3.76 KB
/
server.js
File metadata and controls
136 lines (115 loc) · 3.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
const express = require('express');
const bodyParser = require('body-parser');
const Schema = require('schema-client');
// Map webhook events to handlers
// See https://schema.io/docs#webhooks for a complete list of events
const webhookEvents = {
'webhook.test': handleWebhookTest,
'product.updated': handleProductUpdated,
'order.submitted': handleOrderSubmitted,
'payment.succeeded': handlePaymentSucceeded
};
// URL this server will receive events at
const WEBHOOK_URL = process.env.WEBHOOK_URL || 'your endpoint url';
// Alias to identify this webhook and ensure we update a single configuration
const WEBHOOK_ALIAS = process.env.WEBHOOK_ALIAS || 'example';
// Port this server will listen on
// Note: if using ngrok, your tunnel should point to this port on localhost
const PORT = process.env.PORT || 8080;
// Connect to Schema using ID and Key
const SCHEMA_CLIENT_ID = process.env.SCHEMA_CLIENT_ID || 'your client id';
const SCHEMA_CLIENT_KEY = process.env.SCHEMA_CLIENT_KEY || 'your client key';
const schema = new Schema.Client(SCHEMA_CLIENT_ID, SCHEMA_CLIENT_KEY);
// Initiate express
const app = express();
app.use(bodyParser.json());
// Receive webhook events on POST
app.post('/', (req, res) => {
receiveEvent(req.body).then(() => {
res.status(200).end();
}).catch(err => {
res.status(500).end(err);
});
});
// Listen for webhooks
app.listen(PORT, () => {
console.log(`> Listening on port ${PORT} for events to ${WEBHOOK_URL}\n`);
// Register webhook endpoint and send a test event
registerWebhook().then(sendTestEvent).catch(console.error);
});
// Create or update a webhook endpoint configuration
function registerWebhook() {
return schema.get('/:webhooks/:last', { alias: WEBHOOK_ALIAS }).then(existingWebhook => {
if (existingWebhook) {
// Update existing webhook
return schema.put('/:webhooks/{id}', {
id: existingWebhook.id,
url: WEBHOOK_URL,
events: { $set: Object.keys(webhookEvents) },
enabled: true
});
} else {
// Create new webhook
return schema.post('/:webhooks', {
alias: WEBHOOK_ALIAS,
url: WEBHOOK_URL,
events: Object.keys(webhookEvents),
enabled: true
});
}
}).then(webhook => {
if (webhook.errors) {
throw new Error(`Unable to register webhook! ${JSON.stringify(webhook.errors)}`);
}
return webhook;
});
}
// Send a test event
function sendTestEvent(webhook) {
return schema.post('/events', {
model: ':webhooks',
type: 'webhook.test',
data: { id: webhook.id }
});
}
// Receive and handle webhook events
function receiveEvent(event) {
const { type, model, data } = event;
const now = new Date();
console.log(`[${now.toISOString()}] Received ${type} for /${model}/${data.id}`);
console.log(JSON.stringify(event, null, 2));
// Get handler from event map
const handler = webhookEvents[event.type];
// Throw an error if the event is not defined
if (handler === undefined) {
throw new Error(`Unable to handle ${event.type} event`);
}
return Promise.resolve(handler(event));
}
// ============================================
// Event handlers
// --------------------------------------------
function handleWebhookTest(event) {
console.log('> Webhook test successful');
}
function handleProductUpdated(event) {
return schema.get('/products/{id}', {
id: event.data.id
}).then(product => {
// TODO: something with updated product
});
}
function handleOrderSubmitted(event) {
return schema.get('/orders/{id}', {
id: event.data.id
}).then(order => {
// TODO: something with submitted order
});
}
function handlePaymentSucceeded(event) {
return schema.get('/payments/{id}', {
id: event.data.id
}).then(payment => {
// TODO: something with successful payment
});
}