|
@@ -83,6 +83,12 @@ const isQuotaExceeded = apiCalls => {
|
|
return quotaExceeded;
|
|
return quotaExceeded;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+const youtubeChannelRegex =
|
|
|
|
+ // eslint-disable-next-line max-len
|
|
|
|
+ /\.[\w]+\/(?:(?:channel\/(?<channelId>UC[0-9A-Za-z_-]{21}[AQgw]))|(?:user\/?(?<channelUsername>[\w-]+))|(?:c\/?(?<channelCustomUrl>[\w-]+))|(?:\/?(?<channelUsernameOrCustomUrl>@?[\w-]+)))/;
|
|
|
|
+
|
|
|
|
+// TODO maybe make use of the forHandle/forUsername for YouTube channel list queries, instead of doing a search
|
|
|
|
+
|
|
class _YouTubeModule extends CoreClass {
|
|
class _YouTubeModule extends CoreClass {
|
|
// eslint-disable-next-line require-jsdoc
|
|
// eslint-disable-next-line require-jsdoc
|
|
constructor() {
|
|
constructor() {
|
|
@@ -554,6 +560,21 @@ class _YouTubeModule extends CoreClass {
|
|
* @returns {Promise} - returns promise (reject, resolve)
|
|
* @returns {Promise} - returns promise (reject, resolve)
|
|
*/
|
|
*/
|
|
GET_CHANNEL_ID_FROM_CUSTOM_URL(payload) {
|
|
GET_CHANNEL_ID_FROM_CUSTOM_URL(payload) {
|
|
|
|
+ /**
|
|
|
|
+ * Example URLs
|
|
|
|
+ * # Caravan Palace
|
|
|
|
+ * https://www.youtube.com/channel/UCKH9HfYY_GEcyltl2mbD5lA
|
|
|
|
+ * https://www.youtube.com/user/CaravanPalace
|
|
|
|
+ * https://www.youtube.com/c/CaravanPalace # Doesn't exist
|
|
|
|
+ * https://www.youtube.com/@CaravanPalace
|
|
|
|
+ * https://www.youtube.com/CaravanPalace
|
|
|
|
+ * # Pogo
|
|
|
|
+ * https://www.youtube.com/channel/UCn-K7GIs62ENvdQe6ZZk9-w
|
|
|
|
+ * https://www.youtube.com/user/PogoMusic # Doesn't exist
|
|
|
|
+ * https://www.youtube.com/c/PogoMusic
|
|
|
|
+ * https://www.youtube.com/@PogoMusic # Redirects to /pogomusic
|
|
|
|
+ * https://www.youtube.com/PogoMusic
|
|
|
|
+ */
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
async.waterfall(
|
|
async.waterfall(
|
|
[
|
|
[
|
|
@@ -564,7 +585,12 @@ class _YouTubeModule extends CoreClass {
|
|
maxResults: 50
|
|
maxResults: 50
|
|
};
|
|
};
|
|
|
|
|
|
- params.q = payload.customUrl;
|
|
|
|
|
|
+ const { customUrl } = payload;
|
|
|
|
+
|
|
|
|
+ // Force query to YouTube to start with @, so it will search for "@PogoMusic" for example
|
|
|
|
+ const query = customUrl.startsWith("@") ? customUrl : `@${customUrl}`;
|
|
|
|
+
|
|
|
|
+ params.q = query;
|
|
|
|
|
|
YouTubeModule.runJob(
|
|
YouTubeModule.runJob(
|
|
"API_SEARCH",
|
|
"API_SEARCH",
|
|
@@ -904,19 +930,14 @@ class _YouTubeModule extends CoreClass {
|
|
*/
|
|
*/
|
|
GET_CHANNEL_ID(payload) {
|
|
GET_CHANNEL_ID(payload) {
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
- const regex =
|
|
|
|
- /\.[\w]+\/(?:(?:channel\/(UC[0-9A-Za-z_-]{21}[AQgw]))|(?:user\/?([\w-]+))|(?:c\/?([\w-]+))|(?:\/?([\w-]+)))/;
|
|
|
|
- const splitQuery = regex.exec(payload.url);
|
|
|
|
|
|
+ const splitQuery = youtubeChannelRegex.exec(payload.url);
|
|
|
|
|
|
- if (!splitQuery) {
|
|
|
|
|
|
+ if (!splitQuery.groups) {
|
|
YouTubeModule.log("ERROR", "GET_CHANNEL_ID", "Invalid YouTube channel URL query.");
|
|
YouTubeModule.log("ERROR", "GET_CHANNEL_ID", "Invalid YouTube channel URL query.");
|
|
reject(new Error("Invalid playlist URL."));
|
|
reject(new Error("Invalid playlist URL."));
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- const channelId = splitQuery[1];
|
|
|
|
- const channelUsername = splitQuery[2];
|
|
|
|
- const channelCustomUrl = splitQuery[3];
|
|
|
|
- const channelUsernameOrCustomUrl = splitQuery[4];
|
|
|
|
|
|
+ const { channelId, channelUsername, channelCustomUrl, channelUsernameOrCustomUrl } = splitQuery.groups;
|
|
|
|
|
|
const disableSearch = payload.disableSearch || false;
|
|
const disableSearch = payload.disableSearch || false;
|
|
|
|
|
|
@@ -977,19 +998,14 @@ class _YouTubeModule extends CoreClass {
|
|
*/
|
|
*/
|
|
GET_CHANNEL_VIDEOS(payload) {
|
|
GET_CHANNEL_VIDEOS(payload) {
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
- const regex =
|
|
|
|
- /\.[\w]+\/(?:(?:channel\/(UC[0-9A-Za-z_-]{21}[AQgw]))|(?:user\/?([\w-]+))|(?:c\/?([\w-]+))|(?:\/?([\w-]+)))/;
|
|
|
|
- const splitQuery = regex.exec(payload.url);
|
|
|
|
|
|
+ const splitQuery = youtubeChannelRegex.exec(payload.url);
|
|
|
|
|
|
- if (!splitQuery) {
|
|
|
|
|
|
+ if (!splitQuery.groups) {
|
|
YouTubeModule.log("ERROR", "GET_CHANNEL_VIDEOS", "Invalid YouTube channel URL query.");
|
|
YouTubeModule.log("ERROR", "GET_CHANNEL_VIDEOS", "Invalid YouTube channel URL query.");
|
|
reject(new Error("Invalid playlist URL."));
|
|
reject(new Error("Invalid playlist URL."));
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- const channelId = splitQuery[1];
|
|
|
|
- const channelUsername = splitQuery[2];
|
|
|
|
- const channelCustomUrl = splitQuery[3];
|
|
|
|
- const channelUsernameOrCustomUrl = splitQuery[4];
|
|
|
|
|
|
+ const { channelId, channelUsername, channelCustomUrl, channelUsernameOrCustomUrl } = splitQuery.groups;
|
|
|
|
|
|
const disableSearch = payload.disableSearch || false;
|
|
const disableSearch = payload.disableSearch || false;
|
|
|
|
|