-
Notifications
You must be signed in to change notification settings - Fork 189
Expand file tree
/
Copy pathwebhook.js
More file actions
132 lines (128 loc) · 3.91 KB
/
webhook.js
File metadata and controls
132 lines (128 loc) · 3.91 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
import axiosRetry, { exponentialDelay, linearDelay } from "axios-retry";
import { HttpsProxyAgent } from "https-proxy-agent";
import Config from "./config.js";
import SlackError from "./errors.js";
/**
* This Webhook class posts the configured payload to the provided webhook, with
* whatever additional settings set.
*/
export default class Webhook {
/**
* @param {Config} config
*/
async post(config) {
if (!config.inputs.webhook) {
throw new SlackError(config.core, "No webhook was provided to post to");
}
/**
* @type {import("axios-retry").IAxiosRetryConfig}
* @see {@link https://www.npmjs.com/package/axios-retry}
*/
const retries = this.retries(config.inputs.retries);
axiosRetry(config.axios, retries);
try {
const response = await config.axios.post(
config.inputs.webhook,
config.content.values,
{
...this.proxies(config),
},
);
config.core.setOutput("ok", response.status === 200);
config.core.setOutput("response", JSON.stringify(response.data));
config.core.debug(JSON.stringify(response.data));
} catch (/** @type {any} */ err) {
const response =
typeof err?.toJSON === "function"
? err.toJSON()
: {
message: err?.message,
status: err?.response?.status,
};
config.core.setOutput("ok", response.status === 200);
config.core.setOutput("response", JSON.stringify(response.message));
config.core.debug(JSON.stringify(response));
throw new SlackError(config.core, response.message ?? "Request failed", {
cause: err,
});
}
}
/**
* Return configurations for http proxy options if these are set.
* @param {Config} config
* @returns {import("axios").AxiosRequestConfig | undefined}
* @see {@link https://github.com/slackapi/slack-github-action/pull/132}
*/
proxies(config) {
const { webhook, proxy } = config.inputs;
if (!webhook) {
throw new SlackError(config.core, "No webhook was provided to proxy to");
}
if (!proxy) {
return undefined;
}
try {
if (new URL(webhook).protocol !== "https:") {
config.core.debug(
"The webhook destination is not HTTPS so skipping the HTTPS proxy",
);
return undefined;
}
switch (new URL(proxy).protocol) {
case "https:":
return {
httpsAgent: new HttpsProxyAgent(proxy),
};
case "http:":
return {
httpsAgent: new HttpsProxyAgent(proxy),
proxy: false,
};
default:
throw new SlackError(
config.core,
`Unsupported URL protocol: ${proxy}`,
);
}
} catch (/** @type {any} */ err) {
throw new SlackError(config.core, "Failed to configure the HTTPS proxy", {
cause: err,
});
}
}
/**
* Return configurations for retry options with different delays.
* @param {string} option
* @returns {import("axios-retry").IAxiosRetryConfig}
*/
retries(option) {
switch (option?.trim().toUpperCase()) {
case "0":
return { retries: 0 };
case "5":
return {
retryCondition: axiosRetry.isRetryableError,
retries: 5,
retryDelay: linearDelay(60 * 1000), // 5 minutes
};
case "10":
return {
retryCondition: axiosRetry.isRetryableError,
retries: 10,
retryDelay: (count, err) => exponentialDelay(count, err, 2 * 1000), // 34.12 minutes
};
case "RAPID":
return {
retryCondition: axiosRetry.isRetryableError,
retries: 12,
retryDelay: linearDelay(1 * 1000), // 12 seconds
};
default:
return {
retryCondition: axiosRetry.isRetryableError,
retries: 5,
retryDelay: linearDelay(60 * 1000), // 5 minutes
};
}
}
}