youtube.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Function to extract YouTube channel ID from various URL formats
  2. export const extractYouTubeChannelId = (url: string): string | null => {
  3. const patterns = [
  4. // Channel ID format: https://www.youtube.com/channel/UCxxxxxx
  5. /youtube\.com\/channel\/([a-zA-Z0-9_-]+)/,
  6. // Handle format: https://www.youtube.com/c/ChannelName
  7. /youtube\.com\/c\/([a-zA-Z0-9_-]+)/,
  8. // User format: https://www.youtube.com/user/username
  9. /youtube\.com\/user\/([a-zA-Z0-9_-]+)/,
  10. // Custom URL format: https://www.youtube.com/@channelname
  11. /youtube\.com\/@([a-zA-Z0-9_-]+)/,
  12. ];
  13. for (const pattern of patterns) {
  14. const match = url.match(pattern);
  15. if (match) {
  16. return match[1];
  17. }
  18. }
  19. return null;
  20. };
  21. // Function to detect if a URL is a direct RSS feed
  22. export const isDirectRSSFeed = (url: string): boolean => {
  23. return url.includes('feeds/videos.xml?channel_id=');
  24. };
  25. // Function to convert YouTube channel URL to RSS feed URL
  26. export const convertYouTubeToRSS = (url: string): string => {
  27. // If it's already an RSS feed URL, return as is
  28. if (isDirectRSSFeed(url)) {
  29. return url;
  30. }
  31. const channelId = extractYouTubeChannelId(url);
  32. if (channelId) {
  33. // For channel ID format (starts with UC), we can directly create the RSS URL
  34. if (url.includes('/channel/') && channelId.startsWith('UC')) {
  35. return `https://www.youtube.com/feeds/videos.xml?channel_id=${channelId}`;
  36. }
  37. // For other formats, warn that it might not work
  38. console.warn(`YouTube RSS URL might not work for custom username: ${channelId}. You may need to find the actual channel ID starting with 'UC'`);
  39. return `https://www.youtube.com/feeds/videos.xml?channel_id=${channelId}`;
  40. }
  41. // If we can't extract the channel ID, return the original URL
  42. return url;
  43. };
  44. // Function to extract channel name from @username format URL
  45. export const extractChannelNameFromUrl = (url: string): string | null => {
  46. // Try to extract from @username format
  47. const atMatch = url.match(/youtube\.com\/@([a-zA-Z0-9_-]+)/);
  48. if (atMatch && atMatch[1]) {
  49. return atMatch[1];
  50. }
  51. // Try to extract from /c/ format
  52. const cMatch = url.match(/youtube\.com\/c\/([a-zA-Z0-9_-]+)/);
  53. if (cMatch && cMatch[1]) {
  54. return cMatch[1];
  55. }
  56. // Try to extract from /user/ format
  57. const userMatch = url.match(/youtube\.com\/user\/([a-zA-Z0-9_-]+)/);
  58. if (userMatch && userMatch[1]) {
  59. return userMatch[1];
  60. }
  61. return null;
  62. };
  63. // Function to check if URL needs channel ID lookup
  64. export const needsChannelIdLookup = (url: string): boolean => {
  65. return url.includes('/@') || url.includes('/c/') || url.includes('/user/');
  66. };
  67. // Function to get instructions for finding channel ID
  68. export const getChannelIdInstructions = (): string => {
  69. return `Pour trouver le flux RSS d'une chaîne YouTube :
  70. Méthode recommandée :
  71. 1. Allez sur la page de la chaîne YouTube
  72. 2. Clic droit → "Afficher le code source"
  73. 3. Cherchez : <link rel="alternate" type="application/rss+xml"
  74. 4. Copiez l'URL complète du flux RSS (https://www.youtube.com/feeds/videos.xml?channel_id=UCxxxxx)
  75. Méthode alternative :
  76. 1. Cherchez "channelId":"UC..." dans le code source
  77. 2. Utilisez l'URL : https://www.youtube.com/channel/UCxxxxx`;
  78. };
  79. // Function to automatically fetch YouTube channel RSS and name
  80. export const fetchYouTubeRSSUrl = async (url: string): Promise<{rssUrl: string, channelName: string} | null> => {
  81. try {
  82. const { supabase } = await import('@/integrations/supabase/client');
  83. const { data: { session } } = await supabase.auth.getSession();
  84. if (!session?.access_token) {
  85. console.error('No active session for fetch-youtube-rss');
  86. return null;
  87. }
  88. const response = await fetch(`https://wftyukugedtojizgatwj.supabase.co/functions/v1/fetch-youtube-rss`, {
  89. method: 'POST',
  90. headers: {
  91. 'Content-Type': 'application/json',
  92. 'Authorization': `Bearer ${session.access_token}`
  93. },
  94. body: JSON.stringify({ url })
  95. });
  96. if (!response.ok) {
  97. const errorData = await response.json();
  98. console.error('Failed to fetch YouTube RSS:', errorData.error);
  99. return null;
  100. }
  101. const data = await response.json();
  102. console.log('Successfully fetched YouTube RSS data:', data);
  103. return data;
  104. } catch (error) {
  105. console.error('Error fetching YouTube RSS:', error);
  106. return null;
  107. }
  108. };
  109. // Function to fetch YouTube channel name from page metadata with fallback
  110. export const fetchYouTubeChannelName = async (url: string): Promise<string | null> => {
  111. // First, try to extract name from URL if it's an @username format
  112. const urlName = extractChannelNameFromUrl(url);
  113. if (urlName) {
  114. console.log('Extracted channel name from URL:', urlName);
  115. return urlName;
  116. }
  117. // If we can't extract from URL, return null instead of trying CORS proxies
  118. // which are often blocked or unreliable
  119. console.log('Could not extract channel name from URL, manual entry required');
  120. return null;
  121. };