Skip to content

Commit f9c87f2

Browse files
Fix coffee chat stats and scheduling links
1 parent e4b38f7 commit f9c87f2

2 files changed

Lines changed: 32 additions & 8 deletions

File tree

src/coffeeChats/coffeeChatService.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -250,18 +250,20 @@ export const createPairings = (
250250
};
251251

252252
/**
253-
* Extracts scheduling links (Calendly, Cal.com, etc.) from user profile
253+
* Extracts Calendly scheduling link from user profile
254254
*/
255255
export const getSchedulingLink = async (
256256
userId: string,
257257
): Promise<string | null> => {
258258
try {
259-
const userInfo = await slackbot.client.users.info({ user: userId });
260-
if (!userInfo.ok || !userInfo.user?.profile) {
259+
const userProfile = await slackbot.client.users.profile.get({
260+
user: userId,
261+
});
262+
if (!userProfile.ok || !userProfile.profile) {
261263
return null;
262264
}
263265

264-
const profile = userInfo.user.profile;
266+
const profile = userProfile.profile;
265267

266268
// Check profile fields for scheduling links (e.g. in the link field of Misc. Information)
267269
const fieldsToCheck = [
@@ -279,7 +281,9 @@ export const getSchedulingLink = async (
279281
if (!field || typeof field !== "string") continue;
280282

281283
// Slack custom fields format links as <https://calendly.com/user|Text> or <https://calendly.com/user>
282-
const slackLinkMatch = field.match(/<(https?:\/\/calendly\.com\/[^|>]+)(?:\|[^>]+)?>/i);
284+
const slackLinkMatch = field.match(
285+
/<(https?:\/\/calendly\.com\/[^|>]+)(?:\|[^>]+)?>/i,
286+
);
283287
if (slackLinkMatch) {
284288
return slackLinkMatch[1];
285289
}
@@ -291,9 +295,7 @@ export const getSchedulingLink = async (
291295
}
292296

293297
// Fallback for calendly without protocol
294-
const domainMatch = field.match(
295-
/calendly\.com\/[\w-]+/i,
296-
);
298+
const domainMatch = field.match(/calendly\.com\/[\w-]+/i);
297299
if (domainMatch) {
298300
return "https://" + domainMatch[0];
299301
}
@@ -630,8 +632,11 @@ export const createCoffeeChatsForChannel = async (
630632
*/
631633
export const reportStats = async (): Promise<void> => {
632634
try {
635+
const now = moment().tz("America/New_York").toDate();
636+
633637
const activeConfigs = await CoffeeChatConfigModel.find({
634638
isActive: true,
639+
nextPairingDate: { $lte: now },
635640
});
636641

637642
if (activeConfigs.length === 0) {

tests/coffeeChats/coffeeChatService.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ describe("coffeeChatService", () => {
121121
channelName: mockChannelName,
122122
isActive: true,
123123
pairingFrequencyDays: mockPairingFrequencyDays,
124+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
124125
}).save();
125126

126127
// Call the function
@@ -169,6 +170,7 @@ describe("coffeeChatService", () => {
169170
channelName: mockChannelName,
170171
isActive: false,
171172
pairingFrequencyDays: mockPairingFrequencyDays,
173+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
172174
}).save();
173175

174176
// Call the function
@@ -207,6 +209,7 @@ describe("coffeeChatService", () => {
207209
channelName: mockChannelName,
208210
isActive: true,
209211
pairingFrequencyDays: mockPairingFrequencyDays,
212+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
210213
}).save();
211214

212215
await coffeeChatService.pauseCoffeeChats(mockChannelId);
@@ -945,6 +948,7 @@ describe("coffeeChatService", () => {
945948
channelName: mockChannelName,
946949
isActive: true,
947950
pairingFrequencyDays: mockPairingFrequencyDays,
951+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
948952
}).save();
949953

950954
// Create some pairings
@@ -1016,6 +1020,7 @@ describe("coffeeChatService", () => {
10161020
channelName: mockChannelName,
10171021
isActive: false,
10181022
pairingFrequencyDays: mockPairingFrequencyDays,
1023+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
10191024
}).save();
10201025

10211026
// Call the function
@@ -1048,6 +1053,7 @@ describe("coffeeChatService", () => {
10481053
channelName: mockChannelName,
10491054
isActive: true,
10501055
pairingFrequencyDays: mockPairingFrequencyDays,
1056+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
10511057
}).save();
10521058

10531059
// Call the function
@@ -1070,6 +1076,7 @@ describe("coffeeChatService", () => {
10701076
channelName: mockChannelName,
10711077
isActive: true,
10721078
pairingFrequencyDays: mockPairingFrequencyDays,
1079+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
10731080
}).save();
10741081

10751082
// Create a pairing that is not due for stats reporting
@@ -1101,6 +1108,7 @@ describe("coffeeChatService", () => {
11011108
channelName: mockChannelName,
11021109
isActive: true,
11031110
pairingFrequencyDays: mockPairingFrequencyDays,
1111+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
11041112
}).save();
11051113

11061114
// Pairing within the reporting window (counts toward period stats)
@@ -1162,6 +1170,7 @@ describe("coffeeChatService", () => {
11621170
channelName: mockChannelName,
11631171
isActive: true,
11641172
pairingFrequencyDays: mockPairingFrequencyDays,
1173+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
11651174
}).save();
11661175

11671176
const recentDueDate = moment()
@@ -1247,6 +1256,7 @@ describe("coffeeChatService", () => {
12471256
channelName: mockChannelName,
12481257
isActive: true,
12491258
pairingFrequencyDays: mockPairingFrequencyDays,
1259+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
12501260
}).save();
12511261

12521262
const recentDueDate = moment()
@@ -1304,6 +1314,7 @@ describe("coffeeChatService", () => {
13041314
channelName: mockChannelName,
13051315
isActive: true,
13061316
pairingFrequencyDays: mockPairingFrequencyDays,
1317+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
13071318
}).save();
13081319

13091320
// One period pairing that is NOT confirmed — still triggers the stats post
@@ -1348,6 +1359,7 @@ describe("coffeeChatService", () => {
13481359
channelName: "coffee-chats",
13491360
isActive: true,
13501361
pairingFrequencyDays: mockPairingFrequencyDays,
1362+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
13511363
}).save();
13521364

13531365
// Pairing in the target channel
@@ -1404,6 +1416,7 @@ describe("coffeeChatService", () => {
14041416
channelName: mockChannelName,
14051417
isActive: true,
14061418
pairingFrequencyDays: mockPairingFrequencyDays,
1419+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
14071420
}).save();
14081421

14091422
// Create a pairing that is due for stats reporting but has a previous pairing from a round long ago
@@ -1435,6 +1448,7 @@ describe("coffeeChatService", () => {
14351448
channelName: "coffee-chats",
14361449
isActive: true,
14371450
pairingFrequencyDays: mockPairingFrequencyDays,
1451+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
14381452
}).save();
14391453

14401454
// Create a pairing that is halfway to due date, with a conversationId
@@ -1480,6 +1494,7 @@ describe("coffeeChatService", () => {
14801494
channelName: "coffee-chats",
14811495
isActive: true,
14821496
pairingFrequencyDays: mockPairingFrequencyDays,
1497+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
14831498
}).save();
14841499

14851500
// Create a pairing that is not halfway to due date
@@ -1520,6 +1535,7 @@ describe("coffeeChatService", () => {
15201535
channelName: "coffee-chats",
15211536
isActive: true,
15221537
pairingFrequencyDays: mockPairingFrequencyDays,
1538+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
15231539
}).save();
15241540

15251541
// Create a pairing that is halfway to due date but already confirmed
@@ -1561,6 +1577,7 @@ describe("coffeeChatService", () => {
15611577
channelName: "coffee-chats",
15621578
isActive: false,
15631579
pairingFrequencyDays: mockPairingFrequencyDays,
1580+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
15641581
}).save();
15651582

15661583
// Create a pairing that is halfway to due date, with a conversationId
@@ -1601,6 +1618,7 @@ describe("coffeeChatService", () => {
16011618
channelName: "coffee-chats",
16021619
isActive: true,
16031620
pairingFrequencyDays: mockPairingFrequencyDays,
1621+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
16041622
}).save();
16051623

16061624
// Create a pairing that is halfway to due date but has no conversationId
@@ -1641,6 +1659,7 @@ describe("coffeeChatService", () => {
16411659
channelName: "coffee-chats",
16421660
isActive: true,
16431661
pairingFrequencyDays: mockPairingFrequencyDays,
1662+
nextPairingDate: moment().tz("America/New_York").subtract(1, "minutes").toDate(),
16441663
}).save();
16451664

16461665
// Create 2 pairings that are halfway to due date, with conversationIds

0 commit comments

Comments
 (0)