elsamueldev commited on
Commit
e1dafe2
1 Parent(s): aae7b59

Upload 6 files

Browse files
Files changed (6) hide show
  1. Dockerfile +11 -0
  2. app.js +37 -0
  3. discord-webhook.js +74 -0
  4. package.json +23 -0
  5. schemas.js +22 -0
  6. server.js +15 -0
Dockerfile ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:20
2
+
3
+ WORKDIR /app
4
+
5
+ COPY package.json ./
6
+
7
+ RUN npm install
8
+
9
+ COPY . .
10
+
11
+ CMD ["node", "index.js"]
app.js ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import express from 'express';
2
+ import cors from 'cors';
3
+
4
+ import { DiscordWebhook } from './discord-webhook.js';
5
+ import { messageSchema } from './schemas.js';
6
+
7
+
8
+ /**
9
+ *
10
+ * @param {DiscordWebhook} discordWebhook
11
+ * @returns {express.Express}
12
+ */
13
+ export function createApp(discordWebhook) {
14
+ const app = express();
15
+ app.disable('x-powered-by');
16
+ app.use(express.json());
17
+ app.use(cors());
18
+
19
+ app.post('/submit', async (req, res) => {
20
+ const result = messageSchema.safeParse(req.body);
21
+ if (!result.success) {
22
+ res.status(400).send(result.error.message);
23
+ return;
24
+ }
25
+
26
+ const sent = await discordWebhook.sendEmbed(result.data);
27
+
28
+ if (!sent) {
29
+ res.status(500).send('Tu mensaje no se ha podido guardar');
30
+ return;
31
+ }
32
+
33
+ res.status(201).send('va');
34
+ });
35
+
36
+ return app;
37
+ }
discord-webhook.js ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { urlSchema } from "./schemas.js";
2
+
3
+
4
+ export class DiscordWebhook {
5
+ #url;
6
+
7
+ constructor(url) {
8
+ this.#url = urlSchema.parse(url);
9
+ }
10
+
11
+
12
+ /**
13
+ *
14
+ * @param {object} payload
15
+ * @returns {boolean}
16
+ */
17
+ #sendPayload = async (payload) => {
18
+ const response = await fetch(this.#url, {
19
+ method: 'POST',
20
+ body: JSON.stringify(payload),
21
+ headers: {
22
+ 'Content-Type': 'application/json'
23
+ }
24
+ });
25
+
26
+ const sent = response.status === 204;
27
+
28
+ if (!sent) {
29
+ console.error(await response.text());
30
+ }
31
+
32
+ return sent;
33
+ };
34
+
35
+ /**
36
+ * @param {string} content
37
+ * @returns {Promise<boolean>}
38
+ */
39
+ async sendPlainText(content) {
40
+ const payload = {
41
+ content
42
+ };
43
+
44
+ return this.#sendPayload(payload);
45
+ }
46
+
47
+ /**
48
+ *
49
+ * @param {object} content
50
+ * @returns {Promise<boolean>}
51
+ */
52
+ async sendEmbed(content) {
53
+ const fields = [];
54
+
55
+ for (const [label, value] of Object.entries(content)) {
56
+ const field = {
57
+ name: label,
58
+ value: value
59
+ };
60
+ fields.push(field);
61
+ }
62
+
63
+ const embed = {
64
+ title: "Nuevo mensaje",
65
+ fields
66
+ };
67
+
68
+ const payload = {
69
+ embeds: [embed]
70
+ };
71
+
72
+ return this.#sendPayload(payload);
73
+ }
74
+ }
package.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "confia-form-backend",
3
+ "version": "1.0.0",
4
+ "main": "server.js",
5
+ "type": "module",
6
+ "scripts": {
7
+ "start": "node server.js",
8
+ "test": "echo \"Error: no test specified\" && exit 1"
9
+ },
10
+ "keywords": [],
11
+ "author": "",
12
+ "license": "ISC",
13
+ "description": "",
14
+ "devDependencies": {
15
+ "@types/express": "5.0.0",
16
+ "@types/node": "22.7.5"
17
+ },
18
+ "dependencies": {
19
+ "cors": "2.8.5",
20
+ "express": "4.21.1",
21
+ "zod": "3.23.8"
22
+ }
23
+ }
schemas.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import z from 'zod';
2
+
3
+ export const messageSchema = z.object({
4
+ name: z.string({
5
+ required_error: "El nombre es obligatorio",
6
+ invalid_type_error: "El nombre debe ser texto"
7
+ })
8
+ .min(3, "El nombre debe tener por lo menos 3 caracteres")
9
+ .max(20, "El nombre no puede superar los 20 caracteres"),
10
+ email: z.string({
11
+ required_error: "El correo es obligatorio",
12
+ invalid_type_error: "El correo debe ser texto"
13
+ }).email("El correo debe ser válido"),
14
+ message: z.string({
15
+ required_error: "El mensaje es obligatorio",
16
+ invalid_type_error: "El mensaje debe ser un texto"
17
+ })
18
+ .min(1, "El mensaje no puede estar vacío")
19
+ .max(500, "El mensaje no puede superar los 500 caracteres")
20
+ });
21
+
22
+ export const urlSchema = z.string().url();
server.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { createApp } from "./app.js";
2
+ import { DiscordWebhook } from "./discord-webhook.js";
3
+
4
+ const webhookUrl = process.env.WEBHOOK_URL;
5
+ if (!webhookUrl) {
6
+ console.error("WEBHOOK_URL environment variable is not set.");
7
+ process.exit(1);
8
+ }
9
+
10
+ const PORT = process.env.PORT ?? 80;
11
+ const app = createApp(new DiscordWebhook(webhookUrl));
12
+
13
+ app.listen(PORT, () => {
14
+ console.log(`Server is listening on port ${PORT}`);
15
+ });