Skip to content

Commit 711ea04

Browse files
committed
cv scripts
1 parent a54e2db commit 711ea04

File tree

5 files changed

+236
-0
lines changed

5 files changed

+236
-0
lines changed

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
![Logo_red](https://github.com/FSUMinho/website/blob/main/imgs/logo_red.png)
2+
3+
<h1 align="center">Google AppScripts Automations</h1>
4+
5+
## About
6+
7+
This repository contains a collection of Google App Scripts designed to automate tasks within our organization that rely on Google services. While these scripts are tailored to specific purposes, they can be adapted for use in other contexts.

cv_collection/README.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Recruitment CV collection
2+
3+
## About
4+
5+
This script automates the collection of CVs within our organization, streamlining the process of sharing them with sponsors. Individuals can send an email following a specific format, and the script will automatically create a dedicated folder in Google Drive to store the submitted CV. Additionally, the folder is shared with the sender, granting them the ability to update its contents at any time.
6+
7+
## Overview of Functionality
8+
9+
1. **Prevent Duplicate Processing**:
10+
- Creates or retrieves a Gmail label named `Processed`.
11+
- Ensures emails are processed only once by skipping threads already labeled as `Processed`.
12+
13+
2. **Organize Attachments**:
14+
- Creates a parent folder in Google Drive named "CVs" (if it doesn't already exist).
15+
- For emails with matching subjects (e.g., `CVPG1234`, `CVAG1234`), creates subfolders named after the subject.
16+
17+
3. **Store Attachments**:
18+
- Downloads email attachments into the corresponding subfolder in Google Drive.
19+
- Sets the folder's sharing permissions to "Anyone with the link" and grants edit rights.
20+
21+
4. **Reply to the Sender**:
22+
- Replies to the sender with a shareable link to the created folder.
23+
- Uses the email subject to personalize the response.
24+
25+
5. **Error Handling**:
26+
- Wraps the logic in a `try-catch` block to handle errors gracefully and log them.

cv_collection/script.gs

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
function processEmails() {
2+
try {
3+
// Specify the label for processed emails to avoid duplicates
4+
var processedLabel = GmailApp.getUserLabelByName("Processed") || GmailApp.createLabel("Processed");
5+
6+
// Specify the parent folder where CV folders will be created
7+
var parentFolderName = "CVs";
8+
var parentFolders = DriveApp.getFoldersByName(parentFolderName);
9+
var parentFolder = parentFolders.hasNext() ? parentFolders.next() : DriveApp.createFolder(parentFolderName);
10+
11+
// Broaden the search for all unread emails
12+
var threads = GmailApp.search('is:unread');
13+
Logger.log("Found " + threads.length + " unread threads");
14+
15+
threads.forEach(function(thread) {
16+
var messages = thread.getMessages();
17+
18+
// Check if the thread is already processed
19+
if (thread.getLabels().some(label => label.getName() === processedLabel.getName())) {
20+
Logger.log("Skipping already processed thread: " + thread.getFirstMessageSubject());
21+
return; // Skip already processed threads
22+
}
23+
24+
messages.forEach(function(message) {
25+
// Log the subject of each unread email
26+
Logger.log("Found unread email with subject: " + message.getSubject());
27+
28+
var subject = message.getSubject();
29+
var match = subject.match(/^CV(A|PG)\d+$/);
30+
31+
if (match) {
32+
var folderName = match[0];
33+
Logger.log("Matched folder name: " + folderName);
34+
var folders = parentFolder.getFoldersByName(folderName);
35+
var folder = folders.hasNext() ? folders.next() : parentFolder.createFolder(folderName);
36+
37+
// Save attachments
38+
var attachments = message.getAttachments();
39+
attachments.forEach(function(attachment) {
40+
folder.createFile(attachment);
41+
});
42+
43+
// Generate a shareable link to the folder with edit permission
44+
folder.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.EDIT);
45+
var folderUrl = folder.getUrl();
46+
47+
// Reply to the email with the link to the created folder
48+
var recipient = message.getFrom();
49+
var replySubject = "Access to Your CV Folder: " + folderName;
50+
var replyBody = "Hello,\n\nYour CV has been received and processed.\nYou can access your folder using the following link: " +
51+
folderUrl +
52+
"\nYou have edit permissions to manage the contents of this folder." +
53+
"\nBest regards,\nFSUMinho";
54+
GmailApp.sendEmail(recipient, replySubject, replyBody);
55+
56+
// Mark the thread as processed
57+
thread.addLabel(processedLabel);
58+
Logger.log("Marked thread as processed and replied to: " + recipient);
59+
} else {
60+
Logger.log("No match for subject: " + subject);
61+
}
62+
});
63+
});
64+
} catch (error) {
65+
Logger.log("Error: " + error.toString());
66+
}
67+
}

recruitment_cv_collection/README.md

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Recruitment CV collection
2+
3+
## About
4+
5+
This script serves as a suplement to the FSUMinh CV collection. It focous on collection CV from recruitment forms and share them in our collection. It does the same thing as the `cv_collection` script. The only difference is the source of the CVs.
6+
7+
### Overview of Functionality
8+
9+
- Extracts form responses from specified Google Sheets.
10+
- Creates a folder for each CV submission in a shared Google Drive directory.
11+
- Shares the folder with the CV's owner, granting them edit permissions to update their submission.
12+
- Sends a confirmation email to the submitter with a link to their folder.
13+
14+
## Configuration
15+
16+
This script requires the google sheets file ID where the form responses are beeing stored in order to extract the data. Multiple sheets files can be used.
17+
18+
You can extract the ID from the google sheets link:
19+
20+
```
21+
Full link
22+
https://docs.google.com/spreadsheets/d/187dNnLrPZxT5eDyxnOvGuyr67nAPZXIb4rgMZuX0Uhc/edit?gid=905334468#gid=905334468
23+
24+
ID
25+
187dNnLrPZxT5eDyxnOvGuyr67nAPZXIb4rgMZuX0Uhc
26+
```
27+
28+
The IDs should be added in the `sheetsIds` var:
29+
30+
```
31+
var sheetIds = [
32+
"12j9XBAo8AXo7ofrB5Cbeu1jQ2mP3SFtqQ-c6kU4d27s", // sheet 1
33+
"1liZlUD7WW9F1l-6lBJQ5Bb4VZfWVNzZMZb7D0qpKqIQ", // sheet 2
34+
"187dNnLrPZxT5eDyxnOvGuyr67nAPZXIb4rgMZuX0Uhc" // sheet 3
35+
];
36+
```

recruitment_cv_collection/script.gs

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
function processFormResponses() {
2+
try {
3+
// Specify the Google Sheets linked to the forms
4+
var sheetIds = [
5+
"12j9XBAo8AXo7ofrB5Cbeu1jQ2mP3SFtqQ-c6kU4d27s", // mnt
6+
"1liZlUD7WW9F1l-6lBJQ5Bb4VZfWVNzZMZb7D0qpKqIQ", // mecanica
7+
"187dNnLrPZxT5eDyxnOvGuyr67nAPZXIb4rgMZuX0Uhc" // eletronica
8+
];
9+
10+
// Specify the parent folder in the shared drive
11+
var sharedDriveFolderName = "CVs";
12+
var sharedDriveFolders = DriveApp.getFoldersByName(sharedDriveFolderName);
13+
var parentFolder = sharedDriveFolders.hasNext() ? sharedDriveFolders.next() : DriveApp.createFolder(sharedDriveFolderName);
14+
15+
// Use ScriptProperties to track processed timestamps
16+
var scriptProperties = PropertiesService.getScriptProperties();
17+
18+
// Loop through each sheet ID
19+
for (var sheetIndex = 0; sheetIndex < sheetIds.length; sheetIndex++) {
20+
var sheetId = sheetIds[sheetIndex];
21+
var sheet = SpreadsheetApp.openById(sheetId).getSheets()[0]; // Assuming you want the first sheet
22+
Logger.log("Processing sheet: " + sheet.getName());
23+
24+
// Get all responses from the sheet
25+
var responses = sheet.getDataRange().getValues(); // Includes headers
26+
27+
if (responses) {
28+
Logger.log("Responses found for sheet: " + sheet.getName());
29+
} else {
30+
Logger.log("Erro ao obter respostas para a folha: " + sheet.getName());
31+
continue; // Skip to the next sheet if no responses are found
32+
}
33+
34+
for (var i = 1; i < responses.length; i++) {
35+
var row = responses[i];
36+
var timestamp = row[0];
37+
var studentName = row[1];
38+
var fullName = row[2];
39+
var email = row[3];
40+
var uploadedFileUrl = row[7];
41+
42+
// Skip processed rows or rows without file upload
43+
if (scriptProperties.getProperty(timestamp) || !uploadedFileUrl) {
44+
continue;
45+
}
46+
47+
try {
48+
// Create a folder named after the full name or other identifier
49+
var folderName = "CV" + fullName;
50+
var folders = parentFolder.getFoldersByName(folderName);
51+
var folder = folders.hasNext() ? folders.next() : parentFolder.createFolder(folderName);
52+
53+
// Retrieve the uploaded file by its URL
54+
var uploadedFileId = getFileIdFromUrl(uploadedFileUrl); // Adiciona esta linha para extrair o ID do ficheiro
55+
if (uploadedFileId) {
56+
try {
57+
var uploadedFile = DriveApp.getFileById(uploadedFileId);
58+
folder.addFile(uploadedFile);
59+
Logger.log("File successfully added to folder: " + folderName);
60+
} catch (fileAccessError) {
61+
Logger.log("Error accessing or adding file with ID " + uploadedFileId + ": " + fileAccessError.toString());
62+
}
63+
} else {
64+
Logger.log("No valid file ID found in URL: " + uploadedFileUrl);
65+
}
66+
67+
// Set sharing permissions
68+
folder.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.EDIT);
69+
var folderUrl = folder.getUrl();
70+
71+
// Send a confirmation email
72+
GmailApp.sendEmail(email, "Partilha de CV",
73+
"Caro " + studentName + ",\n\n" +
74+
"O teu CV foi adicionado à nossa coleção e pode agora ser consultado pelos nossos patrocinadores.\n\n" +
75+
"Caso o queiras consultar ou submeter uma nova versão, podes fazê-lo nesta pasta: " + folderUrl + "\n\n" +
76+
"Cumprimentos,\nFSUMinho");
77+
78+
Logger.log("Folder created and email sent for: " + fullName);
79+
80+
// Mark the submission as processed by storing its timestamp
81+
scriptProperties.setProperty(timestamp, "processed");
82+
} catch (fileError) {
83+
Logger.log("Error processing file for row " + (i + 1) + ": " + fileError.toString());
84+
}
85+
}
86+
}
87+
} catch (error) {
88+
Logger.log("Error: " + error.toString());
89+
}
90+
}
91+
92+
/**
93+
* Helper function to extract the file ID from a Google Drive URL.
94+
*/
95+
function getFileIdFromUrl(url) {
96+
// Verifica dois formatos: /d/<ID> ou ?id=<ID>
97+
var match = url.match(/(?:\/d\/|id=)([a-zA-Z0-9_-]+)/);
98+
Logger.log("Extracted File ID: " + (match ? match[1] : "No match found for URL: " + url));
99+
return match ? match[1] : null;
100+
}

0 commit comments

Comments
 (0)