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
import { fetch } from "https://esm.town/v/std/fetch";
import { resyPublicAPIKey } from "https://esm.town/v/vtdocs/resyPublicAPIKey";
export const resyGetMatchingSlot = async (
token: string,
venueId: number,
day: string, // 2023-07-05
start: string, // 19:00
end: string, // 20:00
partySize: number,
): Promise<{
"config": {
"id": number;
"type": string;
"token": string;
};
"date": {
"end": string;
"start": string;
};
}> => {
const startTime = new Date(`${day} ${start}`);
const endTime = new Date(`${day} ${end}`);
const slotsRes = await fetch(
`https://api.resy.com/4/find?lat=0&long=0&day=${day}&party_size=${partySize}&venue_id=${venueId}`,
{
"headers": {
"authorization":
`ResyAPI api_key="${resyPublicAPIKey}"`,
"x-resy-auth-token": token,
},
},
);
const slotsJSON = await slotsRes.json();
if (slotsJSON.results.venues[0].slots.length === 0) {
throw new Error(`no slots on ${day}`);
}
const availableSlots = slotsJSON.results.venues[0].slots;
const matchingSlots = availableSlots.filter((slot) => {
const time = new Date(slot.date.start);
return time >= startTime && time <= endTime;
});
if (matchingSlots.length === 0) {
throw new Error(
`there were some slots on ${day} but none between ${startTime.toISOString()}-${startTime.toISOString()}`,
);
}
// Get the slot in the middle of the list, usually in the middle of the time range.
// (This idea was copied from @alp.bookReservationOnResy)
const middleSlotIndex = Math.floor(matchingSlots.length / 2);
const slot = matchingSlots.at(middleSlotIndex);
return {
config: slot.config,
date: slot.date,
};
};