-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathmove-github-emails.js
More file actions
executable file
·186 lines (160 loc) · 5.6 KB
/
move-github-emails.js
File metadata and controls
executable file
·186 lines (160 loc) · 5.6 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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#!/usr/bin/env node
/**
* Script to find and move existing GitHub notification emails
* to the GitHub Notifications subfolder
*/
const https = require('https');
const fs = require('fs');
const path = require('path');
// Configuration
const homePath = process.env.HOME || require('os').homedir();
const tokenPath = path.join(homePath, '.outlook-assistant-tokens.json');
const githubFolderId =
'AAMkAGQ0NzYwMTdmLTYzMWUtNDE1ZS04ZDYyLTZjZmQ5YjkyNWM0OQAuAAAAAAAMiw_uRKMyQ4cvWGcmDNGZAQD-pkus0juzTK_ueB_BlgMCAAGKmpqoAAA=';
const notificationsFolderId =
'AAMkAGQ0NzYwMTdmLTYzMWUtNDE1ZS04ZDYyLTZjZmQ5YjkyNWM0OQAuAAAAAAAMiw_uRKMyQ4cvWGcmDNGZAQD-pkus0juzTK_ueB_BlgMCAAGKmpqpAAA=';
// Main function
async function moveGitHubEmails() {
try {
// Read the authentication token from file
console.log(`Reading token from ${tokenPath}`);
const tokenData = JSON.parse(fs.readFileSync(tokenPath, 'utf8'));
const accessToken = tokenData.access_token;
if (!accessToken) {
console.error('No access token found in token file!');
process.exit(1);
}
console.log('Successfully read access token');
// Step 1: Search for GitHub notification emails in the inbox
console.log('\nSearching for GitHub notification emails...');
const searchParams = new URLSearchParams({
$filter:
"from/emailAddress/address eq 'notifications@github.com' or from/emailAddress/address eq 'noreply@github.com'",
$top: 100,
$select: 'id,subject,from,receivedDateTime',
});
const inboxEmails = await callGraphAPI(
`me/mailFolders/inbox/messages?${searchParams.toString()}`
);
console.log(
`Found ${inboxEmails.value.length} GitHub notification emails in inbox`
);
// Step 2: Classify emails as workflow notifications or other
const workflowEmails = [];
const otherEmails = [];
inboxEmails.value.forEach((email) => {
const subject = email.subject.toLowerCase();
if (
subject.includes('workflow') ||
subject.includes('run failed') ||
subject.includes('run completed') ||
subject.includes('github actions')
) {
workflowEmails.push(email);
} else if (subject.includes('[gondola')) {
workflowEmails.push(email); // These are also notifications
} else {
otherEmails.push(email);
}
});
console.log(`Workflow notifications: ${workflowEmails.length}`);
console.log(`Other GitHub emails: ${otherEmails.length}`);
// Step 3: Move workflow notifications to the Notifications subfolder
if (workflowEmails.length > 0) {
console.log(
'\nMoving workflow notifications to Notifications subfolder...'
);
let movedCount = 0;
for (const email of workflowEmails) {
try {
await callGraphAPI(`me/messages/${email.id}/move`, 'POST', {
destinationId: notificationsFolderId,
});
movedCount++;
console.log(
`Moved ${movedCount}/${workflowEmails.length}: "${email.subject}"`
);
} catch (error) {
console.error(`Failed to move email: ${error.message}`);
}
}
console.log(
`Successfully moved ${movedCount} workflow notifications to Notifications subfolder`
);
}
// Step 4: Move other GitHub emails to the main GitHub folder
if (otherEmails.length > 0) {
console.log('\nMoving other GitHub emails to GitHub folder...');
let movedCount = 0;
for (const email of otherEmails) {
try {
await callGraphAPI(`me/messages/${email.id}/move`, 'POST', {
destinationId: githubFolderId,
});
movedCount++;
console.log(
`Moved ${movedCount}/${otherEmails.length}: "${email.subject}"`
);
} catch (error) {
console.error(`Failed to move email: ${error.message}`);
}
}
console.log(
`Successfully moved ${movedCount} other GitHub emails to GitHub folder`
);
}
console.log('\nEmail organization complete!');
} catch (error) {
console.error('Error:', error);
}
}
/**
* Helper function to call Microsoft Graph API
*/
async function callGraphAPI(endpoint, method = 'GET', data = null) {
return new Promise((resolve, reject) => {
// Read token from file again to ensure it's fresh
const tokenData = JSON.parse(fs.readFileSync(tokenPath, 'utf8'));
const accessToken = tokenData.access_token;
const options = {
hostname: 'graph.microsoft.com',
path: `/v1.0/${endpoint}`,
method: method,
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
};
const req = https.request(options, (res) => {
let responseData = '';
res.on('data', (chunk) => {
responseData += chunk;
});
res.on('end', () => {
if (res.statusCode >= 200 && res.statusCode < 300) {
try {
const jsonResponse = responseData ? JSON.parse(responseData) : {};
resolve(jsonResponse);
} catch (error) {
reject(new Error(`Failed to parse API response: ${error.message}`));
}
} else {
reject(
new Error(
`API request failed with status ${res.statusCode}: ${responseData}`
)
);
}
});
});
req.on('error', (error) => {
reject(new Error(`Network error: ${error.message}`));
});
if (data && (method === 'POST' || method === 'PATCH' || method === 'PUT')) {
req.write(JSON.stringify(data));
}
req.end();
});
}
// Run the script
moveGitHubEmails();