├── README.md ├── index.html └── main.js /README.md: -------------------------------------------------------------------------------- 1 | # Youtube API/Auth2 App 2 | 3 | > App that uses Youtube API v3 to fetch and display channel data and latest videos. Uses Auth2 library to authenticate 4 | 5 | ## Quick Start 6 | 7 | Add Your OAuth client id to main.js and open index.html 8 | 9 | ## App Info 10 | 11 | ### Author 12 | 13 | Brad Traversy 14 | [Traversy Media](http://www.traversymedia.com) 15 | 16 | ### Version 17 | 18 | 1.0.0 19 | 20 | ### License 21 | 22 | This project is licensed under the MIT License 23 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 17 | 18 | YouTube Channel Data 19 | 20 | 21 | 22 | 29 |
30 |
31 |
32 |

Log In With Google

33 | 34 | 35 |
36 |
37 |
38 |
39 |
40 |
41 | 42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | 53 | 54 | 55 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | // Options 2 | const CLIENT_ID = '739916412029-2v255arol9ntohe68hndvll6h7junank.apps.googleusercontent.com'; 3 | const DISCOVERY_DOCS = [ 4 | 'https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest' 5 | ]; 6 | const SCOPES = 'https://www.googleapis.com/auth/youtube.readonly'; 7 | 8 | const authorizeButton = document.getElementById('authorize-button'); 9 | const signoutButton = document.getElementById('signout-button'); 10 | const content = document.getElementById('content'); 11 | const channelForm = document.getElementById('channel-form'); 12 | const channelInput = document.getElementById('channel-input'); 13 | const videoContainer = document.getElementById('video-container'); 14 | 15 | const defaultChannel = 'techguyweb'; 16 | 17 | // Form submit and change channel 18 | channelForm.addEventListener('submit', e => { 19 | e.preventDefault(); 20 | 21 | const channel = channelInput.value; 22 | 23 | getChannel(channel); 24 | }); 25 | 26 | // Load auth2 library 27 | function handleClientLoad() { 28 | gapi.load('client:auth2', initClient); 29 | } 30 | 31 | // Init API client library and set up sign in listeners 32 | function initClient() { 33 | gapi.client 34 | .init({ 35 | discoveryDocs: DISCOVERY_DOCS, 36 | clientId: CLIENT_ID, 37 | scope: SCOPES 38 | }) 39 | .then(() => { 40 | // Listen for sign in state changes 41 | gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus); 42 | // Handle initial sign in state 43 | updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get()); 44 | authorizeButton.onclick = handleAuthClick; 45 | signoutButton.onclick = handleSignoutClick; 46 | }); 47 | } 48 | 49 | // Update UI sign in state changes 50 | function updateSigninStatus(isSignedIn) { 51 | if (isSignedIn) { 52 | authorizeButton.style.display = 'none'; 53 | signoutButton.style.display = 'block'; 54 | content.style.display = 'block'; 55 | videoContainer.style.display = 'block'; 56 | getChannel(defaultChannel); 57 | } else { 58 | authorizeButton.style.display = 'block'; 59 | signoutButton.style.display = 'none'; 60 | content.style.display = 'none'; 61 | videoContainer.style.display = 'none'; 62 | } 63 | } 64 | 65 | // Handle login 66 | function handleAuthClick() { 67 | gapi.auth2.getAuthInstance().signIn(); 68 | } 69 | 70 | // Handle logout 71 | function handleSignoutClick() { 72 | gapi.auth2.getAuthInstance().signOut(); 73 | } 74 | 75 | // Display channel data 76 | function showChannelData(data) { 77 | const channelData = document.getElementById('channel-data'); 78 | channelData.innerHTML = data; 79 | } 80 | 81 | // Get channel from API 82 | function getChannel(channel) { 83 | gapi.client.youtube.channels 84 | .list({ 85 | part: 'snippet,contentDetails,statistics', 86 | forUsername: channel 87 | }) 88 | .then(response => { 89 | console.log(response); 90 | const channel = response.result.items[0]; 91 | 92 | const output = ` 93 | 106 |

${channel.snippet.description}

107 |
108 | Visit Channel 111 | `; 112 | showChannelData(output); 113 | 114 | const playlistId = channel.contentDetails.relatedPlaylists.uploads; 115 | requestVideoPlaylist(playlistId); 116 | }) 117 | .catch(err => alert('No Channel By That Name')); 118 | } 119 | 120 | // Add commas to number 121 | function numberWithCommas(x) { 122 | return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); 123 | } 124 | 125 | function requestVideoPlaylist(playlistId) { 126 | const requestOptions = { 127 | playlistId: playlistId, 128 | part: 'snippet', 129 | maxResults: 10 130 | }; 131 | 132 | const request = gapi.client.youtube.playlistItems.list(requestOptions); 133 | 134 | request.execute(response => { 135 | console.log(response); 136 | const playListItems = response.result.items; 137 | if (playListItems) { 138 | let output = '

Latest Videos

'; 139 | 140 | // Loop through videos and append output 141 | playListItems.forEach(item => { 142 | const videoId = item.snippet.resourceId.videoId; 143 | 144 | output += ` 145 |
146 | 147 |
148 | `; 149 | }); 150 | 151 | // Output videos 152 | videoContainer.innerHTML = output; 153 | } else { 154 | videoContainer.innerHTML = 'No Uploaded Videos'; 155 | } 156 | }); 157 | } 158 | --------------------------------------------------------------------------------