import { encode as encodeBase64 } from "https://deno.land/std@0.190.0/encoding/base64.ts";
const CLIENT_ID = Deno.env.get("GOOGLE_CLIENT_ID");
const CLIENT_SECRET = Deno.env.get("GOOGLE_CLIENT_SECRET");
const REDIRECT_URI = Deno.env.get("REDIRECT_URI");
const SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"];
export default async function server(request: Request): Promise<Response> {
const url = new URL(request.url);
const path = url.pathname;
if (path === "/") {
const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?` +
`client_id=${CLIENT_ID}` +
`&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` +
`&response_type=code` +
`&scope=${encodeURIComponent(SCOPES.join(" "))}` +
`&access_type=offline`;
return new Response(`
<html>
<head>
<title>Google Calendar OAuth</title>
</head>
<body>
<h1>Google Calendar OAuth</h1>
<p>Click the button below to authorize access to your Google Calendar:</p>
<a href="${authUrl}"><button>Authorize</button></a>
<p><a href="${import.meta.url.replace("esm.town", "val.town")}">View source</a></p>
</body>
</html>
`, {
headers: { "Content-Type": "text/html" },
});
} else if (path === "/callback") {
const code = url.searchParams.get("code");
if (!code) {
return new Response("No code provided", { status: 400 });
}
const tokenResponse = await fetch("https://oauth2.googleapis.com/token", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Authorization: `Basic ${encodeBase64(`${CLIENT_ID}:${CLIENT_SECRET}`)}`,
},
body: new URLSearchParams({
code,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
redirect_uri: REDIRECT_URI,
grant_type: "authorization_code",
}),
});
const tokens = await tokenResponse.json();
const now = new Date();
const oneWeekLater = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);
const calendarResponse = await fetch(
`https://www.googleapis.com/calendar/v3/calendars/primary/events?` +
`timeMin=${now.toISOString()}` +
`&timeMax=${oneWeekLater.toISOString()}` +
`&singleEvents=true` +
`&orderBy=startTime`,
{
headers: {
Authorization: `Bearer ${tokens.access_token}`,
},
}
);
const calendarData = await calendarResponse.json();
return new Response(JSON.stringify(calendarData, null, 2), {
headers: { "Content-Type": "application/json" },
});
} else {
return new Response("Not found", { status: 404 });
}
}