-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathrequestReceiver.ts
More file actions
139 lines (122 loc) · 3.29 KB
/
Copy pathrequestReceiver.ts
File metadata and controls
139 lines (122 loc) · 3.29 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
137
138
139
import express from "express";
import * as fs from "fs";
import * as path from "path";
import crypto from "crypto";
const app = express();
const port = process.env.PORT || 9001;
app.set("trust proxy", 1);
app.use(
express.json({
// Allow built-in types other than object and array too
strict: false,
verify: (req: any, res, buf) => {
req.rawBody = buf;
},
limit: "10mb",
})
);
app.use(
express.urlencoded({
extended: true,
verify: (req: any, res, buf) => {
req.rawBody = buf;
},
limit: "10mb",
})
);
const outputToFile = (output: any, provider: string, version: string) => {
if (!fs.existsSync(path.join(process.cwd(), "providers", provider))) {
console.warn(
`${provider} doesn't exist could not save json. Create index.json for provider.`
),
fs.mkdirSync(path.join(process.cwd(), "providers", provider));
return;
}
const provider_config = fs.readFileSync(
path.join(process.cwd(), "providers", provider, "index.json"),
"utf-8"
);
if (!provider_config) {
console.warn(
`${provider} config doesn't exist could not save json. Create index.json for provider.`
);
}
const parsed_configs = JSON.parse(provider_config);
if (
!fs.existsSync(path.join(process.cwd(), "providers", provider, version))
) {
fs.mkdirSync(path.join(process.cwd(), "providers", provider, version));
}
// topic_identifier is either a single header/body key or an ordered list of
// them. A list is for providers that put the event type in different places
// depending on the product — the first key that resolves wins, so the most
// specific one goes first. See providers/scrapfly/README.md.
const topic_identifiers: string[] = []
.concat(parsed_configs.configs.topic_identifier || [])
.filter(Boolean);
let topic;
for (const identifier of topic_identifiers) {
topic = output.headers[identifier] || output.body?.[identifier];
if (topic) break;
}
if (!topic) {
topic = `untitled-${crypto
.createHash("md5")
.update(JSON.stringify(output.body, null))
.digest("hex")}`;
}
output.topic = topic;
fs.writeFileSync(
path.join(
process.cwd(),
"providers",
provider,
version,
`${topic.replace(/[/:\\]/g, ".")}.json`
),
JSON.stringify(output, null, 2)
);
};
const formatOutput = (req: any) => {
let headers = {};
Object.entries(req.headers).forEach(([key, value]) => {
if (
key === "idempotency-key" &&
value === req.headers["x-hookdeck-eventid"]
) {
return;
}
if (key.includes("hookdeck")) {
return;
}
if (key === "host") {
return;
}
headers = {
...headers,
[key]: value,
};
});
return {
headers,
body: req.body,
};
};
app.all("/:provider/:version", (req, res) => {
const provider = req.params.provider;
const version = req.params.version;
res.on("finish", () => {
const output = formatOutput(req);
console.log(JSON.stringify(output, null, 2));
outputToFile(output, provider, version);
console.log(JSON.stringify(formatOutput(req), null, 2));
});
res.status(200).json({
message: `it works!`,
});
});
app.listen(port, () => {
console.log(`Webhook receiver listening on http://localhost:${port}`, {
type: "server",
});
});