import { blob } from "https://esm.town/v/std/blob?v=12";
import { resyAuth } from "https://esm.town/v/vtdocs/resyAuth";
import { resyBookSlot } from "https://esm.town/v/vtdocs/resyBookSlot";
import { resyGetMatchingSlot } from "https://esm.town/v/vtdocs/resyGetMatchingSlot";
import { resyGetSlotBookingToken } from "https://esm.town/v/vtdocs/resyGetSlotBookingToken";
import { resyVenueIdFromSlugAndCity } from "https://esm.town/v/vtdocs/resyVenueIdFromSlugAndCity";
import { sha256 } from "https://esm.town/v/vtdocs/sha256";
export const resyBot = async (opts: {
slug: string;
city: string;
day: string;
start: string;
end: string;
partySize: number;
email?: string;
password?: string;
}): Promise<string> => {
let { slug, city, day, start, end, partySize, email, password } = opts;
email ??= Deno.env.get("RESY_EMAIL");
password ??= Deno.env.get("RESY_PASSWORD");
let resyBotData = await blob.getJSON("resyBotData");
const key = [
slug,
city,
day,
start,
end,
partySize,
await sha256(email),
].join(",");
if (resyBotData === undefined) {
resyBotData = {};
}
if (resyBotData[key] !== undefined) {
throw new Error(
`not running resy bot – successful booking exists for ${key}`,
);
}
const auth = await resyAuth(email, password);
const venue = await resyVenueIdFromSlugAndCity(
auth.token,
slug,
city,
);
const matchingSlot = await resyGetMatchingSlot(
auth.token,
venue.id,
day,
start,
end,
partySize,
);
const { bookToken } = await resyGetSlotBookingToken(
auth.token,
matchingSlot.config.token,
matchingSlot.date.start,
partySize,
);
if (auth.paymentMethods.length === 0) {
throw new Error("no payment methods on account (add one and try again)");
}
const bookingMetadata = await resyBookSlot(
auth.token,
bookToken,
auth.paymentMethods[0].id,
);
resyBotData[key] = bookingMetadata;
await blob.setJSON("resyBotData", resyBotData);
return `Booked ${slug} in ${city} at ${matchingSlot.date.start} for ${partySize} people.
Check https://resy.com/account/reservations-and-notify for more details!`;
};