-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
160 lines (140 loc) · 7.08 KB
/
index.js
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import express from 'express'
import { config } from 'dotenv';
import crypto from 'crypto'
import axios from 'axios';
//creates a new instance of an Express application
const app = express();
//setting up config.env file so that we can use content of it
config({
path: ".env"
})
// <------------ middlewares ------------>
//we'll be sending data in json format, that's why it is required to use this middleware
app.use(express.json());
// variables
const PORT = process.env.PORT
// Global variable to store the x-hook-secret
let secret = "";
// Local endpoint for receiving events
app.post("/receiveWebhook", (req, res) => {
try {
if (req.headers["x-hook-secret"]) {
console.log("This is a new webhook")
secret = req.headers["x-hook-secret"]
res.setHeader("X-Hook-Secret", secret)
res.sendStatus(200)
} else if (req.headers["x-hook-signature"]) {
const computedSignature = crypto
.createHmac("SHA256", secret)
.update(JSON.stringify(req.body))
.digest("hex");
if (
!crypto.timingSafeEqual(
Buffer.from(req.headers["x-hook-signature"]),
Buffer.from(computedSignature)
)
) {
// Fail
res.sendStatus(401);
} else {
// Success
console.log(`Events on ${Date()}:`);
// we have project ---> then section that's why receiving two events.. we can use either of them, both have same response gid
const event = req.body.events[1];
// if exist
if (event) {
if (event.action === "added" && event.parent.resource_type === "section" && event.resource.resource_type === "task") {
// Access the task gid
const gid = event.resource.gid;
console.log(gid)
// if gid is not undefined
if (gid) {
// Make API request to fetch task details
const accessToken = process.env.TOKEN;
let taskResponse;
// giving a delay of 2 minutes, reason--> user also need some time to enter the task related information in Asana
setTimeout(async () => {
taskResponse = await axios.get(`https://app.asana.com/api/1.0/tasks/${gid}`, {
headers: {
"Authorization": `Bearer ${accessToken}`,
},
});
// if task related information exist
if (taskResponse) {
// destructuring the required details
const taskDetails = taskResponse?.data?.data;
const id = taskDetails?.gid
const name = taskDetails?.name?.trim() || "Empty"
const assignee = taskDetails?.assignee?.name?.trim() || "Yet To Be Assigned"
const priority = taskDetails?.custom_fields[0]?.display_value?.trim() || "Not Selected"
const duedate = taskDetails?.due_on || "Not Mentioned"
const status = taskDetails?.custom_fields[1]?.display_value?.trim() || "Not Selected"
const description = taskDetails?.custom_fields[2]?.text_value?.trim() || "Empty"
console.log(id, name, assignee, priority, duedate, status, description)
// data which we need to send to Air table
const data = {
"records": [
{
"fields": {
"ID": id,
"Name": name,
"Assignee": assignee,
"Priority": priority,
"Due Date": duedate,
"Status": status,
"Description": description,
}
},
]
};
console.log(data)
// required variables to make a POST request
const baseURL = 'https://api.airtable.com/v0';
const baseId = process.env.BASEID;
const tableIdOrName = process.env.TABLEID;
const apiKey = process.env.AIRTABLETOKEN;
// describing headers
const headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
};
// POST request to add a new row to Air Table
axios.post(`${baseURL}/${baseId}/${tableIdOrName}`, data, { headers })
.then(response => {
console.log('POST request successful!');
console.log(response.data);
})
.catch(error => {
console.error('Error making POST request:', error);
});
}
}, 60000 * 2)
}
}
}
res.sendStatus(200);
}
} else {
console.error("Something went wrong!");
res.sendStatus(400);
}
} catch (error) {
console.error("Error: ", error)
res.sendStatus(500);
}
})
//it is a test route just to see our server is working
app.get("/", (req, res) => {
return res.send(`<div style = "background:magenta;padding:100px;"><h2>Welcome to My Server</h2>
<p>Description...</p>
<div><ul>
<li>Add a new task to Asana</li>
<li>Collect this data through webhook</li>
<li>Add this data to Airtable</li>
</ul></div>
</div>`)
})
//function is used to bind and listen to the connections on the specified host and port
app.listen(PORT, (req, res) => {
console.log(`Server is active on Port ${PORT}`)
})