Skip to content

Commit f4d5bc0

Browse files
committed
to: adding sheet command
1 parent a87d100 commit f4d5bc0

File tree

4 files changed

+123
-62
lines changed

4 files changed

+123
-62
lines changed

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
"jobsPerMessage": 3,
1717
"minsCheckInterval": 5,
1818
"rooms": [
19-
""
19+
"测试多个群"
2020
],
21-
"googleSheet": false
21+
"googleSheet": true
2222
},
2323
"dependencies": {
2424
"@types/node-cron": "^3.0.11",
@@ -30,7 +30,7 @@
3030
"eslint-config-prettier": "^9.1.0",
3131
"eslint-plugin-prettier": "^5.2.1",
3232
"google-auth-library": "^9.14.0",
33-
"google-spreadsheet": "^4.1.2",
33+
"google-spreadsheet": "^4.1.3",
3434
"node-cron": "^3.0.3",
3535
"prettier": "^3.3.3",
3636
"qrcode-terminal": "^0.12.0",

src/command-handler.ts

+38-19
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { InternshipJobProvider } from './providers/internship-job-provider';
33
import { NewGraduateJobProvider } from './providers/new-graduate-job-provider';
44
import { FileSystemService } from './file-system-service';
55
import { AnnotationType, Job, JobProvider, JobType, RoomsCacheFileNames } from './types';
6-
import { GoogleSheetProvider } from './google-sheets-provider';
6+
import { GoogleSheetDoc } from './google-sheets-provider';
77
import { jobWxBotConfig } from '../package.json';
88

99
interface Command {
@@ -131,44 +131,63 @@ export class CommandHandler {
131131
},
132132
},
133133
{
134-
name: 'sheet',
134+
name: 'room-sheet',
135135
aliases: [],
136-
description: 'Get the excel sheet',
136+
description: 'Get All Jobs posted in this chat room',
137137
when: jobWxBotConfig.googleSheet,
138138
execute: async (message: Message) => {
139+
console.log('1. Function called, message:', message);
140+
139141
const room = message.room();
140142
const roomTopic = await room?.topic();
141-
if (!roomTopic || !room) return;
142-
//read roomTopic from
143+
144+
console.log('2. Room and roomTopic:', { room, roomTopic });
145+
146+
if (!roomTopic || !room) {
147+
console.log('Room or roomTopic is undefined, exiting function');
148+
return;
149+
}
150+
143151
let internJob: Job[] = [];
144152
if (FileSystemService.fileExists(roomTopic, RoomsCacheFileNames.SENT_INTERN_JOBS)) {
145153
internJob = FileSystemService.readJSON<Job[]>(
146154
roomTopic,
147155
RoomsCacheFileNames.SENT_INTERN_JOBS,
148156
);
149157
}
158+
159+
console.log('3. Intern jobs read:', internJob);
160+
150161
let newGradJob: Job[] = [];
151162
if (FileSystemService.fileExists(roomTopic, RoomsCacheFileNames.SENT_NEW_GRAD_JOBS)) {
152163
newGradJob = FileSystemService.readJSON<Job[]>(
153164
roomTopic,
154165
RoomsCacheFileNames.SENT_NEW_GRAD_JOBS,
155166
);
156167
}
157-
const doc = GoogleSheetProvider.getInstance().doc;
168+
169+
console.log('4. New grad jobs read:', newGradJob);
170+
171+
const today = new Date().getTime();
172+
const googleSheetDoc = new GoogleSheetDoc();
173+
await googleSheetDoc.initialize(`${roomTopic} Job Posted Info - ${today}`);
174+
const doc = googleSheetDoc.doc;
175+
if (!doc) return;
176+
158177
await doc.loadInfo();
159-
try {
160-
let sheet = doc.sheetsByTitle['Intern'];
161-
await sheet.clear();
162-
sheet = doc.sheetsByTitle['New Grad'];
163-
await sheet.clear();
164-
} catch (error) {
165-
console.error('there is no intern or new grad sheet');
166-
}
167-
await GoogleSheetProvider.getInstance().addJobSheet('Intern', internJob);
168-
await GoogleSheetProvider.getInstance().addJobSheet('New Grad', newGradJob);
169-
room.say(
170-
`Generate google sheet success! Here is the link: https://docs.google.com/spreadsheets/d/${process.env.GOOGLE_SHEET_ID}`,
171-
);
178+
179+
console.log('5. Google Sheet Doc created:', { googleSheetDoc, doc });
180+
181+
await googleSheetDoc.addJobSheet('Intern', internJob);
182+
await googleSheetDoc.addJobSheet('New Grad', newGradJob);
183+
184+
console.log('9. Job sheets added');
185+
186+
doc.setPublicAccessLevel('reader');
187+
let a = await doc.share('[email protected]');
188+
189+
console.log('10. Document shared, result:', a);
190+
room.say('haohaohao');
172191
},
173192
},
174193
];

src/google-sheets-provider.ts

+67-34
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,89 @@
11
import { JWT } from 'google-auth-library';
22
import { GoogleSpreadsheet } from 'google-spreadsheet';
33
import { Job } from './types';
4+
45
const SCOPES = [
56
'https://www.googleapis.com/auth/spreadsheets',
67
'https://www.googleapis.com/auth/drive.file',
8+
'https://www.googleapis.com/auth/drive.readonly',
9+
'https://www.googleapis.com/auth/drive',
710
];
811

9-
export class GoogleSheetProvider {
10-
private static instance: GoogleSheetProvider;
11-
12-
public static getInstance() {
13-
if (!this.instance) {
14-
this.instance = new GoogleSheetProvider();
15-
}
16-
return this.instance;
17-
}
18-
private docSheet: GoogleSpreadsheet;
12+
export class GoogleSheetDoc {
13+
private docSheet: GoogleSpreadsheet | undefined = undefined;
14+
private auth: JWT;
1915

20-
private constructor() {
21-
const auth = new JWT({
16+
public constructor() {
17+
this.auth = new JWT({
2218
email: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL,
2319
key: process.env.GOOGLE_PRIVATE_KEY!.split(String.raw`\n`).join('\n'),
2420
scopes: SCOPES,
2521
});
26-
this.docSheet = new GoogleSpreadsheet(process.env.GOOGLE_SHEET_ID!, auth);
2722
}
23+
24+
public async initialize(title: string): Promise<void> {
25+
try {
26+
console.log('Initializing GoogleSheetDoc with title:', title);
27+
this.docSheet = await GoogleSpreadsheet.createNewSpreadsheetDocument(this.auth, { title });
28+
await this.docSheet.loadInfo();
29+
await this.docSheet.addSheet({ title: 'Intern' });
30+
await this.docSheet?.sheetsByIndex[0]?.delete();
31+
console.log('New spreadsheet created successfully');
32+
} catch (error) {
33+
console.error('Error initializing GoogleSheetDoc:', error);
34+
throw error;
35+
}
36+
}
37+
2838
public get doc() {
2939
return this.docSheet;
3040
}
3141

3242
public async addJobSheet(title: string, jobs: Job[]) {
33-
await this.doc.loadInfo();
34-
let sheet = this.doc.sheetsByTitle[title];
35-
if (sheet) {
36-
await sheet.clear();
37-
await sheet.setHeaderRow(['Date Posted', 'Company', 'Role', 'Location', 'Application Link']);
38-
} else {
39-
sheet = await this.doc.addSheet({
40-
title,
41-
headerValues: ['Date Posted', 'Company', 'Role', 'Location', 'Application Link'],
42-
});
43+
if (!this.docSheet) {
44+
console.error('Document sheet is not initialized');
45+
return;
46+
}
47+
48+
try {
49+
console.log(`Adding job sheet: ${title}`);
50+
await this.doc?.loadInfo();
51+
let sheet = this.doc?.sheetsByTitle[title];
52+
53+
if (sheet) {
54+
console.log('Clearing existing sheet');
55+
await sheet.clear();
56+
await sheet.setHeaderRow([
57+
'Date Posted',
58+
'Company',
59+
'Role',
60+
'Location',
61+
'Application Link',
62+
]);
63+
} else {
64+
console.log('Creating new sheet');
65+
sheet = await this.doc?.addSheet({
66+
title,
67+
headerValues: ['Date Posted', 'Company', 'Role', 'Location', 'Application Link'],
68+
});
69+
}
70+
71+
let rows = jobs
72+
.map((job) => ({
73+
'Date Posted': job.datePosted,
74+
Company: job.company,
75+
Role: job.role,
76+
Location: job.location,
77+
'Application Link': job.applicationLink,
78+
}))
79+
.sort((a, b) => b['Date Posted'].localeCompare(a['Date Posted']));
80+
81+
console.log(`Adding ${rows.length} rows to the sheet`);
82+
await sheet?.addRows(rows);
83+
console.log('Rows added successfully');
84+
} catch (error) {
85+
console.error('Error in addJobSheet:', error);
86+
throw error;
4387
}
44-
let rows = jobs
45-
.map((job) => ({
46-
'Date Posted': job.datePosted,
47-
Company: job.company,
48-
Role: job.role,
49-
Location: job.location,
50-
'Application Link': job.applicationLink,
51-
}))
52-
.sort((a, b) => b['Date Posted'].localeCompare(a['Date Posted']));
53-
54-
await sheet.addRows(rows);
5588
}
5689
}

yarn.lock

+15-6
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ axios@^1.1.3:
700700
form-data "^4.0.0"
701701
proxy-from-env "^1.1.0"
702702

703-
axios@^1.4.0, axios@^1.7.5:
703+
axios@^1.7.5:
704704
version "1.7.5"
705705
resolved "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz#21eed340eb5daf47d29b6e002424b3e88c8c54b1"
706706
integrity sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==
@@ -709,6 +709,15 @@ axios@^1.4.0, axios@^1.7.5:
709709
form-data "^4.0.0"
710710
proxy-from-env "^1.1.0"
711711

712+
axios@^1.7.6:
713+
version "1.7.7"
714+
resolved "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f"
715+
integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==
716+
dependencies:
717+
follow-redirects "^1.15.6"
718+
form-data "^4.0.0"
719+
proxy-from-env "^1.1.0"
720+
712721
balanced-match@^1.0.0:
713722
version "1.0.2"
714723
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@@ -1452,12 +1461,12 @@ google-protobuf@^3.18.0:
14521461
resolved "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.4.tgz#2f933e8b6e5e9f8edde66b7be0024b68f77da6c9"
14531462
integrity sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ==
14541463

1455-
google-spreadsheet@^4.1.2:
1456-
version "4.1.2"
1457-
resolved "https://registry.npmjs.org/google-spreadsheet/-/google-spreadsheet-4.1.2.tgz#92e30fdba7e0d78c55d50731528df7835d58bfee"
1458-
integrity sha512-HFBweDAkOcyC2qO9kmWESKbNuOcn+R7UzZN/tj5LLNxVv8FHmg113u0Ow+yaKwwIOt/NnDtPLuptAhaxTs0FYw==
1464+
google-spreadsheet@^4.1.3:
1465+
version "4.1.3"
1466+
resolved "https://registry.npmjs.org/google-spreadsheet/-/google-spreadsheet-4.1.3.tgz#9b0dc777b175ad90f1aaf22ce78753f271352a76"
1467+
integrity sha512-v/OBWYz8K40Vr3CMiPjo+iIhtri66MVzfCO4llDHJTsM5hI9PfMm64xjgvlRxd+/WHLMVvvlCEEYoNO7iMpJTQ==
14591468
dependencies:
1460-
axios "^1.4.0"
1469+
axios "^1.7.6"
14611470
lodash "^4.17.21"
14621471

14631472
graphemer@^1.4.0:

0 commit comments

Comments
 (0)