-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
357 lines (283 loc) · 11.3 KB
/
server.js
File metadata and controls
357 lines (283 loc) · 11.3 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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const passport = require("passport");
const session = require("express-session");
const MongoStore = require("connect-mongo")(session);
const methodOverride = require("method-override");
const flash = require("express-flash");
const logger = require("morgan");
const connectDB = require("./config/database");
const mainRoutes = require("./routes/main");
const postRoutes = require("./routes/posts");
const convertRoutes = require("./routes/convert")
//Use .env file in config folder
require("dotenv").config({ path: "./config/.env" });
// Passport config
require("./config/passport")(passport);
//Connect To Database
connectDB();
//Using EJS for views
app.set("view engine", "ejs");
//Static Folder
app.use(express.static("public"));
//Body Parsing
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
//Logging
app.use(logger("dev"));
//Use forms for put / delete
app.use(methodOverride("_method"));
// Setup Sessions - stored in MongoDB
app.use(
session({
secret: "keyboard cat",
resave: false,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection }),
})
);
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
//Use flash messages for errors, info, ect...
app.use(flash());
//Setup Routes For Which The Server Is Listening
app.use("/", mainRoutes);
app.use("/post", postRoutes);
app.use("/convert", convertRoutes);
//Server Running
app.listen(process.env.PORT, () => {
console.log("Server is running, you better catch it!");
});
// const fs = require('fs').promises;
// const path = require('path');
// const { authenticate } = require('@google-cloud/local-auth');
// const { google } = require('googleapis');
// const pdf2json = require("./middleware/pdf2json");
// const Anthropic = require('@anthropic-ai/sdk')
// const { toFile } = require('@anthropic-ai/sdk')
// // --- NEW Core Functions for Attachments ---
// /**
// * Lists messages matching the PDF filter.
// * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
// * @returns {Promise<Array<Object>>} A promise that resolves to an array of message resources (IDs only).
// */
// async function listPdfMessages(auth) {
// const gmail = google.gmail({ version: 'v1', auth });
// // Gmail search query: has:attachment AND filename:pdf
// const query = 'has:attachment filename:pdf';
// console.log(`\n--- Searching for messages with PDF attachments (query: "${query}") ---`);
// try {
// const res = await gmail.users.messages.list({
// userId: 'me',
// q: query,
// maxResults: 5, // Limit to 5 for testing
// });
// const messages = res.data.messages || [];
// if (messages.length === 0) {
// console.log('No messages with PDF attachments found.');
// return [];
// }
// console.log(`Found ${messages.length} messages. Processing...`);
// return messages;
// } catch (err) {
// console.error('Error listing messages:', err);
// return [];
// }
// }
// /**
// * Gets the full message content and identifies the PDF attachment part.
// * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
// * @param {string} messageId The ID of the message.
// * @returns {Promise<Object|null>} The message part containing the PDF, or null.
// */
// async function getFullMessage(auth, messageId) {
// const gmail = google.gmail({ version: 'v1', auth });
// try {
// const res = await gmail.users.messages.get({
// userId: 'me',
// id: messageId,
// format: 'full', // Important: must fetch 'full' to get payload parts
// });
// // Recursively search the message parts for the PDF
// const findPdfPart = (parts) => {
// if (!parts) return null;
// for (const part of parts) {
// // Check if it's a PDF attachment
// if (part.mimeType === 'application/pdf' && part.filename) {
// return part;
// }
// // Recursively check nested parts (e.g., multipart/mixed)
// const foundInNested = findPdfPart(part.parts);
// if (foundInNested) return foundInNested;
// }
// return null;
// };
// return findPdfPart(res.data.payload.parts);
// } catch (err) {
// console.error(`Error getting message ${messageId}:`, err.message);
// return null;
// }
// }
// /**
// * Downloads the attachment data and saves it as a file.
// * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
// * @param {string} messageId The ID of the message.
// * @param {Object} attachmentPart The message part containing the PDF information.
// */
// let hasInbox
// async function downloadPdfAttachment(auth, messageId, attachmentPart) {
// const gmail = google.gmail({ version: 'v1', auth });
// // Check if the attachment data is inline or requires a separate API call
// const attachmentId = attachmentPart.body.attachmentId;
// const filename = attachmentPart.filename;
// if (!attachmentId) {
// console.log(` Skipping: PDF "${filename}" in message ${messageId} is too large or inline to download easily via this method.`);
// return;
// }
// try {
// const res = await gmail.users.messages.attachments.get({
// userId: 'me',
// messageId: messageId,
// id: attachmentId,
// });
// // The data is Base64 URL-safe encoded
// const fileData = res.data.data;
// const buffer = Buffer.from(fileData, 'base64');
// const savePath = path.join(process.cwd(), 'downloads', filename);
// await fs.writeFile(savePath, buffer);
// console.log(` ✅ Successfully downloaded PDF: ${filename} to ${savePath}`);
// hasInbox = true
// } catch (err) {
// console.error(` ❌ Error downloading attachment ${filename} from message ${messageId}:`, err.message);
// }
// }
// // --- Main Execution Logic ---
// async function gmailRead() {
// try {
// const authClient = await authorize();
// console.log('Authorization successful.');
// // 1. Create a downloads directory if it doesn't exist
// const downloadsDir = path.join(process.cwd(), 'downloads');
// await fs.mkdir(downloadsDir, { recursive: true });
// console.log(`Created download directory at: ${downloadsDir}`);
// // 2. List all messages containing a PDF attachment
// const messages = await listPdfMessages(authClient);
// // 3. Process each message to find and download the PDF
// for (const msg of messages) {
// console.log(`\n--> Checking Message ID: ${msg.id}`);
// const pdfPart = await getFullMessage(authClient, msg.id);
// if (pdfPart) {
// console.log(` Found PDF: ${pdfPart.filename}`);
// await downloadPdfAttachment(authClient, msg.id, pdfPart);
// } else {
// console.log(' No PDF attachment found in message payload (might be due to MIME structure or not being a direct PDF attachment).');
// }
// }
// console.log('\n--- PDF Download process complete. ---');
// } catch (error) {
// console.error('An error occurred during execution:', error);
// }
// }
// gmailRead()
// if(!hasInbox) return
// async function getPdf() {
// try {
// convertPdf('./downloads/resume.pdf')
// }
// catch (err) {
// console.error(err)
// }
// }
// getPdf()
// // with claude file
// // let file
// // async function fileRead() {
// // const anthropic = new Anthropic({
// // apiKey: process.env.API_KEY_CLAUDE
// // });
// // await anthropic.beta.files.upload({
// // file: await toFile(fs.createReadStream('./downloads/resume.pdf'), undefined, { type: 'application/pdf' })
// // }, {
// // betas: ['files-api-2025-04-14']
// // }).then(res => file = res.id)
// // const response = await anthropic.beta.messages.create({
// // model: "claude-sonnet-4-5",
// // max_tokens: 1024,
// // messages: [
// // {
// // role: "user",
// // content: [
// // {
// // type: "text",
// // text: "Please summarize this document for me."
// // },
// // {
// // type: "document",
// // source: {
// // type: "file",
// // file_id: `${file}`
// // }
// // }
// // ]
// // }
// // ],
// // betas: ["files-api-2025-04-14"],
// // });
// // console.log(response);
// // }
// fileRead()
// //old method
// // class ClaudeAPIClient {
// // constructor() {
// // this.anthropic = new Anthropic({
// // apiKey: process.env.API_KEY_CLAUDE,
// // });
// // }
// // async simpleChat(message, model = 'claude-sonnet-4-20250514') {
// // try {
// // const response = await this.anthropic.messages.create({
// // model: model,
// // max_tokens: 1000,
// // temperature: 0.7,
// // messages: [
// // { role: 'user', content: message }
// // ]
// // });
// // return response.content[0].text;
// // } catch (error) {
// // console.error('Claude API Error:', error);
// // return `Error: ${error.message}`;
// // }
// // }
// // }
// // async function grabJson() {
// // fs.readFile('./downloads/convertedPDFs/output.json', 'utf8', (err, data) => {
// // if (err) {
// // console.error('Error reading file:', err);
// // return;
// // }
// // console.log('File contents:', data, 'done!');
// // const claude = new ClaudeAPIClient();
// // claude.simpleChat(`Hello. You are a model that scans PDF documents and returns yes or no if it is an invoice or if it is not an invoice. Please read the following document, which is a PDF converted to JSON format. Return yes if it is an invoice and no if it is not an invoice. Then, Please let me know if you are able to read this output format or if you would prefer the format to be a txt file. Let me know wether a pdf converted to json, txt, or the raw pdf file would be easier for you to understand. Document:${data}`).then(response => console.log(response))
// // });
// // }
// // grabJson()
// // async function claudeRun() {
// // const anthropic = new Anthropic({
// // apiKey: process.env.ANTHROPIC_API_KEY
// // });
// // const msg = await anthropic.messages.create({
// // model: "claude-haiku-4-5",
// // max_tokens: 1000,
// // messages: [
// // {
// // role: "user",
// // content: "can you read this PDF and tell me what it is?"
// // }
// // ]
// // });
// // console.log(msg);
// // }
// // claudeRun().catch(console.error);