// 'use strict'; chrome.runtime.onInstalled.addListener(function () { // https://stackoverflow.com/questions/19377262/regex-for-youtube-url chrome.contextMenus.create({ id: 'metube', title: "Send to MeTube", targetUrlPatterns: [ 'https://www.youtube.com/*', 'https://m.youtube.com/*', 'https://youtu.be/*' ], contexts: ['link'], }); chrome.contextMenus.create({ id: 'metube-page', title: "Send page to MeTube", contexts: ['page'], }); chrome.contextMenus.create({ id: 'metube-cookie', title: "Send cookie to MeTube", contexts: ['page'], }); }); function sendCookieToMetube(pageUrl, metubeUrl, callback) { console.log("[Cookie] Starting to send cookie for " + pageUrl + " to metubeUrl=" + metubeUrl); if (typeof callback !== 'function') { callback = function () {}; } let urlObj = new URL(pageUrl); let domain = urlObj.hostname; console.log("[Cookie] Domain extracted: " + domain); // Get all cookies for the current domain chrome.cookies.getAll({ domain: domain }, function(cookies) { console.log("[Cookie] Retrieved " + (cookies ? cookies.length : 0) + " cookies for domain: " + domain); if (!cookies || cookies.length === 0) { console.log("[Cookie] No cookies found for domain: " + domain); return; } // Format cookies as a string (name=value; name2=value2) let cookieString = cookies.map(cookie => `${cookie.name}=${cookie.value}`).join('; '); console.log("[Cookie] Cookie string length: " + cookieString.length); console.log("[Cookie] Cookie preview: " + cookieString.substring(0, 100) + "..."); // Base64 encode the cookie string to handle special characters let cookieBase64 = btoa(unescape(encodeURIComponent(cookieString))); console.log("[Cookie] Base64 encoded cookie length: " + cookieBase64.length); let postData = { "url": pageUrl, "cookie": cookieBase64, "domain": domain }; console.log("[Cookie] Sending POST to: " + metubeUrl + "/cookie"); console.log("[Cookie] Post data:", postData); fetch(metubeUrl + "/cookie", { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify(postData) }) .then(response => { console.log("[Cookie] Response status: " + response.status); return response.json(); }) .then(function (response) { console.log("[Cookie] Response data:", response); if (response.status === 'ok') { console.log("[Cookie] Cookie sent successfully"); callback(); } else { console.error("[Cookie] Unexpected response status:", response); } }) .catch(e => { console.error("[Cookie] ERROR: " + e); console.error("[Cookie] Error details:", e); }); }); } function sendVideoUrlToMetube(videoUrl, metubeUrl, format, advancedSettings, callback) { console.log("Sending videoUrl=" + videoUrl + " to metubeUrl=" + metubeUrl); if (typeof callback !== 'function') { callback = function () { }; } let {hostname} = new URL(videoUrl) let postData = { "quality": "best", "format": format, "url": videoUrl, 'auto_start': !advancedSettings['disable_auto_start'] ?? true } Object.keys(advancedSettings).forEach((key) => { if (advancedSettings[key] && !['disable_auto_start'].includes(key) ) { postData[key] = hostname.startsWith('www.') ? hostname.replace('www.', '') : hostname } }) console.log(postData) fetch(metubeUrl + "/add", { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify(postData) }) .then(response => response.json()) .then(function (response) { if (response.status === 'ok') { callback(); } }) .catch(e => console.log("Ran into an unexpected error: " + e)); } chrome.contextMenus.onClicked.addListener(function (item, tab) { chrome.storage.sync.get(['metube', 'contextMenuClickBehavior', 'defaultFormat', 'advancedSettings'], function (data) { if (data === undefined || !data.hasOwnProperty('metube') || data.metube === "") { openTab(chrome.runtime.getURL('options.html'), tab); return } // Handle cookie menu item if (item.menuItemId === 'metube-cookie') { console.log("[Menu] Cookie menu clicked"); console.log("[Menu] item.pageUrl:", item.pageUrl); console.log("[Menu] tab.url:", tab.url); let pageUrl = item.pageUrl || tab.url; console.log("[Menu] Using pageUrl:", pageUrl); console.log("[Menu] MeTube URL:", data.metube); sendCookieToMetube(pageUrl, data.metube, function () { console.log("[Menu] Cookie send callback completed for: " + pageUrl); }); return; } let needToSwitch = (data.contextMenuClickBehavior === 'context-menu-send-current-url-and-switch'); let videoUrl = item.linkUrl || item.pageUrl; sendVideoUrlToMetube(videoUrl, data.metube, data.defaultFormat, data.advancedSettings, function () { if (needToSwitch) { openTab(data.metube, tab); } }); }); }); chrome.action.onClicked.addListener(function (tab) { chrome.storage.sync.get(['metube', 'clickBehavior', 'defaultFormat', 'advancedSettings'], function (data) { if (data === undefined || !data.hasOwnProperty('metube') || data.metube === "") { openTab(chrome.runtime.getURL('options.html'), tab); return } if (data.clickBehavior === 'go-to-metube') { openTab(data.metube, tab); return; } let needToSwitch = (data.clickBehavior === 'send-current-url-and-switch'); chrome.tabs.query({ active: true, lastFocusedWindow: true }, function (tabs) { // use this tab to get the youtube video URL let videoUrl = tabs[0].url; sendVideoUrlToMetube(videoUrl, data.metube, data.defaultFormat, data.advancedSettings, function () { if (needToSwitch) { openTab(data.metube, tab); } }); }); }); }); function openTab(url, currentTab) { chrome.tabs.query({ url: url + "/*" }, function (tabs) { if (tabs.length !== 0) { chrome.tabs.update(tabs[0].id, { 'active': true }, () => { }); } else { chrome.tabs.create({ url: url, index: currentTab.index + 1 }); } }); }