-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
170 lines (145 loc) · 5.19 KB
/
Copy pathindex.js
File metadata and controls
170 lines (145 loc) · 5.19 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
const fetch = require("node-fetch");
const mailgun = require("mailgun-js");
const { Storage } = require("@google-cloud/storage");
const AWS = require("aws-sdk");
const fs = require("fs");
require('dotenv').config();
const DOMAIN = "demo.pranavkulkarni.me";
const mg = mailgun({
apiKey: process.env.MAIL_GUN_API_KEY,
domain: DOMAIN,
});
const gcpCredentials = JSON.parse(Buffer.from(process.env.GCP_PRIVATE_KEY, 'base64').toString('utf-8'));
const storage = new Storage({
projectId: gcpCredentials.project_id,
credentials: gcpCredentials,
});
console.log(gcpCredentials);
function generateTimestamp() {
const now = new Date();
const timestamp = `${now.getFullYear()}${padZero(now.getMonth() + 1)}${padZero(now.getDate())}_${padZero(now.getHours())}${padZero(now.getMinutes())}${padZero(now.getSeconds())}`;
return timestamp;
}
function padZero(value) {
return value < 10 ? `0${value}` : value;
}
const dynamoDBTableName = "Csye6225_Demo_DynamoDB";
const bucketName = process.env.GCS_BUCKET_NAME;
const dynamoDB = new AWS.DynamoDB.DocumentClient();
exports.handler = async function handler(event) {
let fileName;
try {
console.log("EVENT SNS", event.Records[0].Sns);
console.log("EVENT", event);
const timestamp = generateTimestamp();
const eventData = JSON.parse(event.Records[0].Sns.Message);
console.log(eventData);
const releaseUrl = eventData.submission_url;
const recipientEmail = eventData.email;
const assignmentId = eventData.assignmentId;
console.log("URL:", releaseUrl);
console.log("EMAIL:", recipientEmail);
console.log("Assignment ID : ", assignmentId);
const response = await fetch(releaseUrl);
console.log('response', response);
if (!response.ok) {
console.log("Download Failed Fetch");
throw new Error(`Failed to download release: ${response.statusText}`);
}
const fileContents = await response.buffer();
fileName = `${recipientEmail}/${assignmentId}/submision_${timestamp}.zip`;
// Update DynamoDB status to "Email Sending"
await trackEmail(recipientEmail, "Email Sending");
await uploadToGCS(fileContents, fileName);
// Generate signed URL for the object
const objectUrl = `https://storage.googleapis.com/${bucketName}/${fileName}`;
const signedUrl = await generateSignedUrl(bucketName, fileName, { expiresIn: 3600 });
await sendSuccessEmail(
recipientEmail,
"Download Successful",
"The release was successfully downloaded and uploaded to the Bucket.",
objectUrl,
signedUrl
);
// Update DynamoDB status to "Download Successful Email Sent"
await trackEmail(recipientEmail, "Download Successful Email Sent");
} catch (error) {
fileName = fileName || "unknownFileName.zip"
const eventData = JSON.parse(event.Records[0].Sns.Message);
console.error("Error:", error);
const recipientEmail = eventData.email;
// Send error email
await sendFailureEmail(
recipientEmail,
"Download Failed",
`The release was not downloaded. Error: ${error.message}`,
fileName
);
// Update DynamoDB status to "Download Failed Email Sent"
await trackEmail(recipientEmail, "Download Failed Email Sent");
}
};
// Upload Submission
async function uploadToGCS(fileContents, fileName) {
console.log("This is the bucket name : ", bucketName);
const bucket = storage.bucket(bucketName);
console.log("The file name is fileName: ", fileName);
const file = bucket.file(fileName);
return new Promise((resolve, reject) => {
const writeStream = file.createWriteStream();
writeStream
.on("error", reject)
.on("finish", () => resolve(fileContents))
.end(fileContents);
});
}
// Mail Gun
async function sendSuccessEmail(to, subject, message, objectUrl, signedUrl) {
try {
const data = {
from: "csye6225@demo.pranavkulkarni.me",
to: to,
subject: subject,
text: `${message}\n\nDownload the release from the following URL:\n${objectUrl}\n\nSigned URL for direct access:\n${signedUrl}`,
};
await mg.messages().send(data);
} catch (error) {
console.error("Error sending success email:", error);
// If there's an error sending the email, update DynamoDB status to "Email Sending Failed"
await trackEmail(to, "Email Sending Failed");
throw error; // Re-throw the error to maintain the original behavior
}
}
async function sendFailureEmail(to, subject, message, fileName) {
const data = {
from: "csye6225@demo.pranavkulkarni.me",
to: to,
subject: subject,
text: `${message}`,
};
await mg.messages().send(data);
}
// Function to generate a signed URL
async function generateSignedUrl(bucketName, fileName, options = {}) {
const [url] = await storage
.bucket(bucketName)
.file(fileName)
.getSignedUrl({
action: "read",
expires: Date.now() + options.expiresIn * 1000, // Convert expiresIn from seconds to milliseconds
});
return url;
}
// DynamoDB
async function trackEmail(recipientEmail, status) {
const params = {
TableName: dynamoDBTableName,
Item: {
id: Date.now().toString(),
status: status,
timestamp: new Date().toISOString(),
email: recipientEmail,
},
};
return dynamoDB.put(params).promise();
}