Public
Edited
Jan 16
Importers
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
authButton = {
const buttonElement = html`<div id="g-button" style="position: absolute; top: 10px; right: 10px;" />`;
const promptElement = html`<div id="g-prompt" style="position: absolute; top: 0; right: 0;" />`;
const element = html`<div id="sign-in" style="height: 300px;">${buttonElement}${promptElement}</div>`;
return element;
}
Insert cell
placeholder = html`<div />`
Insert cell
token = new Promise((resolve, reject) => {
google.accounts.id.initialize({
client_id,
prompt_parent_id: "g-prompt",
auto_select: true,
callback: async (response) => {
if (response && response.credential) {
const token = response.credential;
const credential = parseJwt(token);
const expirationTime = new Date(Date.now() + credential.exp);
console.log(
`Google token expires at ${expirationTime.toLocaleString()}`
);
authButton.style.display = "none";
resolve(token);
return Promises.when(expirationTime).then(() => {
authButton.style.display = "block";
google.accounts.id.prompt();
});
}
reject(response);
}
});
const buttonElement = document.getElementById("g-button");
google.accounts.id.renderButton(buttonElement, {
theme: "outline",
size: "large"
});
google.accounts.id.prompt((notification) => {
if (notification.isNotDisplayed() || notification.isSkippedMoment()) {
google.accounts.id.renderButton(buttonElement, {
theme: "outline",
size: "large"
});
}
});
})
Insert cell
Insert cell
gapi.client.getToken()
Insert cell
gapi = {
const gapi = await require("//apis.google.com/js/api.js").catch(
() => window.gapi
);
await token;
await new Promise((callback, onerror) => {
gapi.load("client", { callback, onerror });
});
return new Promise((resolve, reject) => {
const client = google.accounts.oauth2.initTokenClient({
client_id,
scope,
prompt: "",
callback: (tokenResponse) => {
if (tokenResponse && tokenResponse.access_token) {
resolve(gapi);
}
},
errorCallback: (error) => {
console.error(error);
}
});
client.requestAccessToken();
});
}
Insert cell
Insert cell
client_id = "134940173616-9idertc5irfihj7jv49gb7msejjctu1t.apps.googleusercontent.com"
Insert cell
scope = "profile email https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/analytics https://www.googleapis.com/auth/photoslibrary.readonly https://www.googleapis.com/auth/photoslibrary.sharing"
Insert cell
discoveryDocs = [
"https://sheets.googleapis.com/$discovery/rest?version=v4",
"https://www.googleapis.com/discovery/v1/apis/drive/v3/rest",
"https://analyticsdata.googleapis.com/$discovery/rest?version=v1beta",
"https://www.googleapis.com/discovery/v1/apis/photoslibrary/v1/rest"
]
Insert cell
Insert cell
parseJwt = (token) => {
var base64Url = token.split(".")[1];
var base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
var jsonPayload = decodeURIComponent(
atob(base64)
.split("")
.map(function (c) {
return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
})
.join("")
);

return JSON.parse(jsonPayload);
}
Insert cell
google = await require("//accounts.google.com/gsi/client").catch(
() => window.google
)
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more