eric60 / YouTube-Blocker

A Chrome Extension that blocks non-educational YouTube videos
17 stars 10 forks source link

WhiteList #9

Open mholtstrom opened 6 months ago

mholtstrom commented 6 months ago

@eric60 I'm a developer who wants to configure his 7-year-old's ChromeBook (that is controlled via FamilyLink) to only be able to browse and play videos based on a whitelist of channels (like TedEd). From my investigation so far, this isn't supported by Google/Chromebook/FamilyLink/YouTube. A chrome extension seems like my best bet. My full analysis is at https://holtstrom.com/michael/blog/post/735/Internet-for-Kids.html And you can reach me at [chromeapps at holtstrom.com] Would you consider adding this to your extension? If you have any advice for me in building my own version, I'd appreciate it.

eric60 commented 6 months ago

Hey @mholtstrom that's great what you're trying to do for your kid!

Unfortunately don't have time to update this except getting to manifest v3 which is due soon by June. Any updates currently might be for naught until its updated to v3 first since chrome will stop working on v3 after june deadline, hope to have time to release by end of april.

yea that whitelist extension looks perfect except for its over privileged settings.

You can try this if you have time and think its worth it, please share with me if you get it working, thanks

  1. setup this chrome extension from chrome extension store and get it working
  2. fork and setup this extension locally. Disable the extension from the store and use the extension you set up locally, you can reuse the api key you previously set up.
  3. now time to add your custom code
  4. just for barebones, you don't have to update the UI, just need to update the script logic
  5. just update content.js
  6. e.g. add a hardcoded whitelist of channels like const allowedChannelIds = ['a', 'b']
  7. since extension is already calling youtube data api v3, you can just get the channel id like this: channelId = response.items[0].snippet.channelId;
  8. you might need to update the api request to get that channelId data though
  9. finally update content.js again to block the video if the currentChannelId is not in the allowedChannelIds list
  10. As you know, you can't prevent your kid from deleting any extension since they can just right click on the extension in the chrome menu bar and click "remove from chrome", but I'm thinking you can tell them that you'll be able to tell that they deleted it since they won't be able to add your custom extension back. You can do this by blocking chrome://extensions/ which is necessary to add back your custom extension from your files. They can't just redownload the extension from the chrome store since yours is a custom local one. Thinking you can block the site from your router or use a computer website blocker with password + uninstall protection (you may already have one) like coldturkey blocker or focusme (I use this, very difficult to break and has uninstall protections)
  11. if your kid is somehow able to figure out how to access the extension code and update the whitelisted channelIds from chrome or your files, then maybe they deserve it and you will be pleasantly surprised! 😆
  12. Note that with focusme, you can also block file paths / applications to block your kid from accessing the extension code in your files
  13. good luck to you and your family!

sample code i found from another extension

 var xhr = new XMLHttpRequest(),
                id = this.getParam(location.href.slice(location.href.indexOf("?") + 1), "v");
            xhr.open("GET", "https://www.googleapis.com/youtube/v3/videos?part=snippet&id=" + id + "&key=" + key, false);
            xhr.send();
            if (xhr.readyState === xhr.DONE && xhr.status === 200) {
                var response = JSON.parse(xhr.responseText);
                id = response.items[0].snippet.channelId;
``` /*------------------------------------------------------------------------------ SHOW CHANNEL VIDEOS COUNT ------------------------------------------------------------------------------*/ ImprovedTube.channelVideosCount = function () { if (this.storage.channel_videos_count === true && this.elements.yt_channel_link) { var key = this.storage["google-api-key"] || ImprovedTube.defaultApiKey; if (this.elements.yt_channel_link.href.indexOf("/channel/") == -1) { var xhr = new XMLHttpRequest(), id = this.getParam(location.href.slice(location.href.indexOf("?") + 1), "v"); xhr.open("GET", "https://www.googleapis.com/youtube/v3/videos?part=snippet&id=" + id + "&key=" + key, false); xhr.send(); if (xhr.readyState === xhr.DONE && xhr.status === 200) { var response = JSON.parse(xhr.responseText); id = response.items[0].snippet.channelId; } } else { id = this.elements.yt_channel_link.href.slice(this.elements.yt_channel_link.href.indexOf("/channel/") + "/channel/".length); if (id.indexOf("/") !== -1) { id = id.match(/.+?(?=\/)/)[0]; } } xhr = new XMLHttpRequest(); xhr.addEventListener("load", function () { var response = JSON.parse(this.responseText), parent = document.querySelector("#meta ytd-channel-name + yt-formatted-string"), element = ImprovedTube.elements.channel_videos_count || document.createElement("div"); ImprovedTube.empty(element); if (response.error) { element.appendChild(document.createTextNode("• Error: " + response.error.code)); } else { element.appendChild(document.createTextNode("• " + response.items[0].statistics.videoCount + " videos")); } element.className = "it-channel-videos-count"; ImprovedTube.elements.channel_videos_count = element; parent.appendChild(element); ImprovedTube.elements.channel_videos_count = element; }); xhr.open("GET", "https://www.googleapis.com/youtube/v3/channels?part=statistics&id=" + id + "&key=" + key, true); xhr.send(); } }; ```
eric60 commented 6 months ago

Also regarding these points

Block shorts as well as full videos.

Not sure if this will also block shorts, unhook chrome extension can hide shorts

When navigating youtube, block all display of non-whitelisted suggestions/

That will be more difficult to implement, I suggest using the chrome extensions listed below instead, though they can be edited, it's best to just hide all the addicting YouTube recommendations, Home Screen, side bar, subscriptions, comments, etc.

Thinking you could just have a book mark folder for the white listed channels and they can click into any of the videos on the channel page.

  1. DF tube chrome extension
  2. Unhook chrome extension
mholtstrom commented 6 months ago

Thanks for the detailed reply. I also got replies from safetube and youtube-warden. Since you're not on manifest v3 and since youtube-warden already has a white-list, I'll experiment with that first. I may come back to yours though.

I understood your instructions about updating content.js but looking at onHistoryStateUpdated.addListener, I don't understand how that blocks embedded videos. Will it work on a page like this? Maybe you get onHistoryStateUpdated not only for the main page but also for all embeds?

Thanks also for the analysis about disabling the extension. Actually on ChromeOS the child needs a parent password to add extensions, and youtube-warden says there is a way to prevent them from removing extensions, although it looked like it needed console access which I haven't tried on ChormeOS.

Thanks for the DF and Unhook suggestions. I submitted a whitelist feature request to Unhook. But I would prefer them to be open source, and I really need the whitelist. For now I'm using YouTube Blocker but I hope to switch to youtube-warden. And rather then try to cleanup the YouTube navigation, I think I'll just make a bookmark page of channels and block all of youtube that isn't an approved channel or a video from an approved channel.

eric60 commented 6 months ago

Actually on ChromeOS the child needs a parent password to add extensions, and https://github.com/maninalift/youtube-warden/issues/1 says there is a way to prevent them from removing extensions, although it looked like it needed console access which I haven't tried on ChormeOS.

That's really really nice, then extension passwords are very useful yea

I understood your instructions about updating content.js but looking at onHistoryStateUpdated.addListener, I don't understand how that blocks embedded videos. Will it work on a page like this? Maybe you get onHistoryStateUpdated not only for the main page but also for all embeds?

This extension doesn't work on embeded websites, think would need to 1) increase site access scope beyond youtube, which I feel might not be worth it, wanted to keep scope just within youtube.com, not a catch all for embedded videos 2) somehow detect an embedded video on the html tags like check for iframe src="http://www.youtube.com/embed/youtubeVideoIdHere, then call youtube data api for that video id to get category / channel type data to block/not block

[screenshot 1]

image

will let you know when get to v3, maybe can add a whitelist then

mholtstrom commented 6 months ago

Ok. Thanks for all the info. In my case on ChromeOS with FamilyLink I give per-domain access. So if I don't want her seeing embedded videos on say TedEd then I should just not grant access to that domain at all. But since I do want to grant TedEd and since the videos are from YouTube, I must grant FamilyLink access to YouTube. But then I've granted all of YouTube. So I think your extension's logic is sufficient. I think I want to: