<commit_before><!DOCTYPE html>
<html lang="fr">
<head>
	<meta charset="utf-8">
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><!-- http://stackoverflow.com/questions/14637943/what-is-x-ua-compatible-when-it-references-ie-edge-chrome-1 -->

	<title>SaaS 015 Google people API: eagerly get contacts (rev6)</title>

	<meta name="viewport" content="width=device-width, initial-scale=1.0">

	<link rel="stylesheet" type="text/css" href="https://rawgit.com/Offirmo/offirmo-monorepo/master/2-advanced/view-css/dist/offirmo-reset%2Butils.css" />
	<style type="text/css">
		body {
			background-color: mediumblue;
			color: white;
		}
	</style>
</head>

<body>

<div class="o⋄centered-article">

<h1>...</h1>
<a>https://developers.google.com/api-client-library/javascript/start/start-js</a>

<!--Add buttons to initiate auth sequence and sign out-->
<button id="authorize-button" style="display: none;">Authorize</button>
<button id="signout-button" style="display: none;">Sign Out</button>

<div id="content"></div>

<script>
	document.querySelector('h1').textContent = document.title;
		Array.prototype.forEach.call(document.querySelectorAll('a'), function(el) {
		el.href || (el.href = el.text);
	});

	console.info(`[${document.title}] loading!`, {
		'document.referrer': document.referrer,
		'window.parent': window.parent,
		'window.self': window.self,
		'window.top': window.top,
		in_iframe: window.self !== window.top,
	})
	window.addEventListener("message", receiveMessage, false);
	function receiveMessage(event) {
		console.info(`[${document.title}] received message:`, event)
	}
</script>

<script type="text/javascript">
	// Enter an API key from the Google API Console:
	//   https://console.developers.google.com/apis/credentials
	const apiKey = '<KEY>';

	// Enter the API Discovery Docs that describes the APIs you want to
	// access. In this example, we are accessing the People API, so we load
	// Discovery Doc found here: https://developers.google.com/people/api/rest/
	const discoveryDocs = [
		'https://people.googleapis.com/$discovery/rest?version=v1',
	];

	// Enter a client ID for a web application from the Google API Console:
	//   https://console.developers.google.com/apis/credentials?project=_
	// In your API Console project, add a JavaScript origin that corresponds
	//   to the domain where you will be running the script.
	const clientId = '496416474187-44a6sog5bp16jmt2gfk2mfds45smm4bj.apps.googleusercontent.com';

	// Enter one or more authorization scopes. Refer to the documentation for
	// the API or https://developers.google.com/people/v1/how-tos/authorizing
	// for details.
	// space separated!
	const scope = 'profile https://www.googleapis.com/auth/contacts.readonly'

	const authorizeButton = document.getElementById('authorize-button');
	const signoutButton = document.getElementById('signout-button');

	// https://developers.google.com/api-client-library/javascript/reference/referencedocs

	// TODO check referrer, and don't do anything if unexpected

	function on_client_loaded() {
		console.log('on_client_loaded', {gapi})
		// Load the API client + auth2 library
		// TODO promisify
		const load_retval = gapi.load('client:auth2', {
			callback: (x) => {
				console.log('gapi load success', x)
				on_gapi_libs_loaded()
			},
			onerror: (err) => {
				// Handle loading error.
				console.error('gapi.client failed to load!', err);
			},
			timeout: 5000, // 5 seconds.
			ontimeout: (x) => {
				// Handle timeout.
				console.error('gapi.client could not load in a timely manner!', x);
			},
		});
		console.log('on_client_loaded', {load_retval})
	}

	function on_gapi_libs_loaded() {
		console.log('on_gapi_libs_loaded', {client: gapi.client, auth2: gapi.auth2})
		const init_retval = Promise.resolve(gapi.client.init({
				apiKey,
				discoveryDocs,
				clientId,
				scope,
			}))
			.then((x) => {
				console.info('on_gapi_libs_loaded: init success', x)

				// Listen for sign-in state changes.
				gapi.auth2.getAuthInstance().isSignedIn.listen(on_signin_status_updated);

				// Handle the initial sign-in state.
				on_signin_status_updated(gapi.auth2.getAuthInstance().isSignedIn.get());

				authorizeButton.onclick = handleAuthClick;
				signoutButton.onclick = handleSignoutClick;
			})
			.catch(err => {
				console.error('on_gapi_libs_loaded:', err)
			})

		console.log({init_retval})
	}

	function on_signin_status_updated(isSignedIn) {
		console.log('updateSigninStatus', {isSignedIn})
		if (isSignedIn) {
			authorizeButton.style.display = 'none';
			signoutButton.style.display = 'block';
			makeApiCalls();
		} else {
			authorizeButton.style.display = 'block';
			signoutButton.style.display = 'none';
		}
	}

	function handleAuthClick(event) {
		gapi.auth2.getAuthInstance().signIn();
	}

	function handleSignoutClick(event) {
		gapi.auth2.getAuthInstance().signOut();
	}

	function getProfile() {
		return Promise.resolve(gapi.client.people.people.get({
				'resourceName': 'people/me',
				'personFields': 'names,emailAddresses',
			}))
			.then(console.info.bind(console, 'getProfile'))
			.catch(err => {
				console.error('getProfile:', err)
				throw err
			})
	}

	function displayContacts(src, infos) {
		if (infos && infos.result && infos.result.connections && infos.result.connections.length) {
			const interestingConnections = infos.result.connections
				.filter(conn => {
					return conn.emailAddresses && conn.emailAddresses.length
				})

			const cleanedConnections = []
			interestingConnections.forEach(({names, emailAddresses}) => {
				if (names.length > 1) console.info('FYI', names)

				emailAddresses.forEach(email => {
					if (!email) return

					cleanedConnections.push({
						name: (name[0] || {}).displayName || email,
						email,
					})
				})
			})

			console.info(`from ${src}:`, cleanedConnections)
			const p = document.createElement('p');
			p.appendChild(document.createTextNode(`${interestingConnections.length} contacts loaded`));
			document.getElementById('content').appendChild(p);

			// 1.) check our parent
			// post to our parent if it is what we expect
			window.parent.postMessage(
				JSON.stringify(cleanedConnections),
				document.referrer, // having been validated previously<commit_msg>TLDW :scream_cat:<commit_after><!DOCTYPE html>
<html lang="fr">
<head>
	<meta charset="utf-8">
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><!-- http://stackoverflow.com/questions/14637943/what-is-x-ua-compatible-when-it-references-ie-edge-chrome-1 -->

	<title>SaaS 015 Google people API: eagerly get contacts (rev7)</title>

	<meta name="viewport" content="width=device-width, initial-scale=1.0">

	<link rel="stylesheet" type="text/css" href="https://rawgit.com/Offirmo/offirmo-monorepo/master/2-advanced/view-css/dist/offirmo-reset%2Butils.css" />
	<style type="text/css">
		body {
			background-color: mediumblue;
			color: white;
		}
	</style>
</head>

<body>

<div class="o⋄centered-article">

<h1>...</h1>
<a>https://developers.google.com/api-client-library/javascript/start/start-js</a>

<!--Add buttons to initiate auth sequence and sign out-->
<button id="authorize-button" style="display: none;">Authorize</button>
<button id="signout-button" style="display: none;">Sign Out</button>

<div id="content"></div>

<script>
	document.querySelector('h1').textContent = document.title;
		Array.prototype.forEach.call(document.querySelectorAll('a'), function(el) {
		el.href || (el.href = el.text);
	});

	console.info(`[${document.title}] loading!`, {
		'document.referrer': document.referrer,
		'window.parent': window.parent,
		'window.self': window.self,
		'window.top': window.top,
		in_iframe: window.self !== window.top,
	})
	window.addEventListener("message", receiveMessage, false);
	function receiveMessage(event) {
		console.info(`[${document.title}] received message:`, event)
	}
</script>

<script type="text/javascript">
	// Enter an API key from the Google API Console:
	//   https://console.developers.google.com/apis/credentials
	const apiKey = '<KEY>';

	// Enter the API Discovery Docs that describes the APIs you want to
	// access. In this example, we are accessing the People API, so we load
	// Discovery Doc found here: https://developers.google.com/people/api/rest/
	const discoveryDocs = [
		'https://people.googleapis.com/$discovery/rest?version=v1',
	];

	// Enter a client ID for a web application from the Google API Console:
	//   https://console.developers.google.com/apis/credentials?project=_
	// In your API Console project, add a JavaScript origin that corresponds
	//   to the domain where you will be running the script.
	const clientId = '496416474187-44a6sog5bp16jmt2gfk2mfds45smm4bj.apps.googleusercontent.com';

	// Enter one or more authorization scopes. Refer to the documentation for
	// the API or https://developers.google.com/people/v1/how-tos/authorizing
	// for details.
	// space separated!
	const scope = 'profile https://www.googleapis.com/auth/contacts.readonly'

	const authorizeButton = document.getElementById('authorize-button');
	const signoutButton = document.getElementById('signout-button');

	// https://developers.google.com/api-client-library/javascript/reference/referencedocs

	// TODO check referrer, and don't do anything if unexpected

	function on_client_loaded() {
		console.log('on_client_loaded', {gapi})
		// Load the API client + auth2 library
		// TODO promisify
		const load_retval = gapi.load('client:auth2', {
			callback: (x) => {
				console.log('gapi load success', x)
				on_gapi_libs_loaded()
			},
			onerror: (err) => {
				// Handle loading error.
				console.error('gapi.client failed to load!', err);
			},
			timeout: 5000, // 5 seconds.
			ontimeout: (x) => {
				// Handle timeout.
				console.error('gapi.client could not load in a timely manner!', x);
			},
		});
		console.log('on_client_loaded', {load_retval})
	}

	function on_gapi_libs_loaded() {
		console.log('on_gapi_libs_loaded', {client: gapi.client, auth2: gapi.auth2})
		const init_retval = Promise.resolve(gapi.client.init({
				apiKey,
				discoveryDocs,
				clientId,
				scope,
			}))
			.then((x) => {
				console.info('on_gapi_libs_loaded: init success', x)

				// Listen for sign-in state changes.
				gapi.auth2.getAuthInstance().isSignedIn.listen(on_signin_status_updated);

				// Handle the initial sign-in state.
				on_signin_status_updated(gapi.auth2.getAuthInstance().isSignedIn.get());

				authorizeButton.onclick = handleAuthClick;
				signoutButton.onclick = handleSignoutClick;
			})
			.catch(err => {
				console.error('on_gapi_libs_loaded:', err)
			})

		console.log({init_retval})
	}

	function on_signin_status_updated(isSignedIn) {
		console.log('updateSigninStatus', {isSignedIn})
		if (isSignedIn) {
			authorizeButton.style.display = 'none';
			signoutButton.style.display = 'block';
			makeApiCalls();
		} else {
			authorizeButton.style.display = 'block';
			signoutButton.style.display = 'none';
		}
	}

	function handleAuthClick(event) {
		gapi.auth2.getAuthInstance().signIn();
	}

	function handleSignoutClick(event) {
		gapi.auth2.getAuthInstance().signOut();
	}

	function getProfile() {
		return Promise.resolve(gapi.client.people.people.get({
				'resourceName': 'people/me',
				'personFields': 'names,emailAddresses',
			}))
			.then(console.info.bind(console, 'getProfile'))
			.catch(err => {
				console.error('getProfile:', err)
				throw err
			})
	}

	function displayContacts(src, infos) {
		if (infos && infos.result && infos.result.connections && infos.result.connections.length) {
			const interestingConnections = infos.result.connections
				.filter(conn => {
					return conn.emailAddresses && conn.emailAddresses.length
				})
			console.info(`from ${src}:`, interestingConnections)

			const cleanedConnections = []
			interestingConnections.forEach(({names = [], emailAddresses = []} = {}) => {
				if (names && names.length > 1) console.info('FYI', names)

				emailAddresses.forEach(email => {
					if (!email) return

					cleanedConnections.push({
						name: (names[0] || {}).displayName || email,
						email,
					})
				})
			})

			console.info(`from ${src}: cleaned`, cleanedConnections)

			const p = document.createElement('p');
			p.appendChild(document.createTextNode(`${interestingConnections.length} contacts loaded`));
			document.getElementById('content').appendChild(p);

			// 1.) check our parent
			// post to our parent if it is what we expect
			window.parent.postMessage(
				JSON.stringify(cleanedConnections),
				document.referrer, // having been validated previously
{'fraction_non_alphanumeric': 0.1512268008807801, 'fraction_numerical': 0.010066058508965083, 'mean_word_length': 4.076646706586827, 'pattern_counts': {'":': 0, '<': 65, '<?xml version=': 0, '>': 85, 'https://': 18, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5655227', 'n_tokens_mistral': 4677, 'n_tokens_neox': 4094, 'n_words': 833}