Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
Maxim-Mazurok committed Jan 11, 2020
0 parents commit 7c4d6e7
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Google Tasks API TypeScript Example
Very basic (and sometimes ugly) but working example of Google Tasks API usage in TypeScript for Browser


## Instructions:
1. Get Client ID and API key: [instructions](https://developers.google.com/tasks/quickstart/js#step_1_turn_on_the)
1. Set `CLIENT_ID` and `API_KEY` in [src/index.ts](src/index.ts)
1. Run `npm run compile` to compile TS to JS (`index.js` should appear in `dist` folder)
1. Start your server (using `https-serve` + edit `hosts` file, or `ngrok`)
1. Authorize, and you'll see your TaskLists as well as Tasks within those TaskLists

## Troubleshooting:
- Always look in the browser console for errors
- Make sure that you're serving via https (using `https-serve` + edit `hosts` file, or `ngrok`)
- Make sure that your domain is added in Google developer console
- You can open issue here if you need help
20 changes: 20 additions & 0 deletions dist/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Google Tasks API TypeScript Example</title>
</head>
<body>
<!--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>

<pre id="content" style="white-space: pre-wrap;"></pre>

<script src="index.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
onload="this.onload=function(){};handleClientLoad()"
onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
</body>
</html>
39 changes: 39 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "google-tasks-api-ts-example",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"compile": "tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": {
"name": "Maxim Mazurok",
"url": "https://maxim.mazurok.com",
"email": "maxim@mazurok.com"
},
"license": "MIT",
"dependencies": {
"@types/gapi": "0.0.39",
"@types/gapi.auth2": "0.0.51",
"@types/gapi.client.tasks": "^1.0.1",
"typescript": "^3.7.4"
}
}
111 changes: 111 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Client ID and API key from the Developer Console
const CLIENT_ID = 'xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com';
const API_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';

// Array of API discovery doc URLs for APIs used by the quickstart
const DISCOVERY_DOCS = ['https://www.googleapis.com/discovery/v1/apis/tasks/v1/rest'];

// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
const SCOPES = 'https://www.googleapis.com/auth/tasks.readonly';

const authorizeButton = document.getElementById('authorize_button');
const signoutButton = document.getElementById('signout_button');

/**
* On load, called to load the auth2 library and API client library.
*/
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}

/**
* Initializes the API client library and sets up sign-in state
* listeners.
*/
function initClient() {
gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES,
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);

// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton && (authorizeButton.onclick = handleAuthClick);
signoutButton && (signoutButton.onclick = handleSignoutClick);
}, function (error) {
appendPre(JSON.stringify(error, null, 2));
});
}

/**
* Called when the signed in status changes, to update the UI
* appropriately. After a sign-in, the API is called.
*/
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
authorizeButton && (authorizeButton.style.display = 'none');
signoutButton && (signoutButton.style.display = 'block');
listTaskLists();
} else {
authorizeButton && (authorizeButton.style.display = 'block');
signoutButton && (signoutButton.style.display = 'none');
}
}

/**
* Sign in the user upon button click.
*/
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}

/**
* Sign out the user upon button click.
*/
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}

/**
* Append a pre element to the body containing the given message
* as its text node. Used to display the results of the API call.
*
* @param {string} message Text to be placed in pre element.
*/
function appendPre(message) {
const pre = document.getElementById('content');
const textContent = document.createTextNode(message + '\n');
pre && pre.appendChild(textContent);
}

/**
* Print task lists.
*/
function listTaskLists() {
gapi.client.tasks.tasklists.list({
maxResults: '10',
}).then(function (response) {
appendPre('Task Lists:');
const taskLists = response.result.items;
if (taskLists && taskLists.length > 0) {
for (let i = 0; i < taskLists.length; i++) {
const taskList = taskLists[i];
appendPre(taskList.title + ' (' + taskList.id + ')');

taskList.id && gapi.client.tasks.tasks.list({
tasklist: taskList.id,
}).then((response) => {
appendPre('\nTasks:');
response.result.items && response.result.items.forEach(task => appendPre(task.title));
});
}
} else {
appendPre('No task lists found.');
}
});
}
23 changes: 23 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"compilerOptions": {
"target": "es2015",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"inlineSourceMap": false,
"inlineSources": false,
"noImplicitAny": false,
"suppressExcessPropertyErrors": true,
"diagnostics": false,
"listFiles": false,
"outDir": "dist",
"noEmitOnError": false,
"strict": true
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules"
]
}

0 comments on commit 7c4d6e7

Please sign in to comment.