├── requirements.txt ├── vercel.json ├── README.md └── api.py /requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | cloudscraper 3 | beautifulsoup4 4 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "builds": [ 4 | { 5 | "src": "api.py", 6 | "use": "@vercel/python" 7 | } 8 | ], 9 | "routes": [ 10 | { 11 | "src": "/(.*)", 12 | "dest": "api.py" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FacebookAPI 2 | 3 | Welcome to the **FacebookAPI** repository! This project is designed to simplify the integration and usage of Facebook's API, providing developers with robust tools and utilities to interact with Facebook's platform. 4 | 5 | ## Features 6 | 7 | - Easy-to-use methods for Facebook Graph API integration. 8 | - Support for authentication and token management. 9 | - Utilities for managing posts, comments, likes, and more. 10 | - Examples and documentation to help you get started quickly. 11 | 12 | ## Installation 13 | 14 | To get started, clone the repository and install the required dependencies: 15 | 16 | ```bash 17 | git clone https://github.com/TheSmartDevs/FacebookAPI.git 18 | cd FacebookAPI 19 | npm install 20 | ``` 21 | 22 | ## 🛠️ Usage 23 | 24 | Here's a quick example to demonstrate how to use FacebookAPI: 25 | 26 | ```javascript 27 | const FacebookAPI = require('facebook-api'); 28 | 29 | // Initialize the API with your access token 30 | const api = new FacebookAPI({ accessToken: 'your-access-token' }); 31 | 32 | // Fetch user profile 33 | api.getUserProfile() 34 | .then(profile => console.log(profile)) 35 | .catch(error => console.error(error)); 36 | ``` 37 | 38 | ## 📝 Documentation 39 | 40 | Not Available Soon Adding....... 41 | 42 | ## 🤝 Contributing 43 | 44 | We welcome contributions! If you'd like to contribute, please follow these steps: 45 | 46 | 1. Fork the repository. 47 | 2. Create a new feature branch (`git checkout -b feature-name`). 48 | 3. Commit your changes (`git commit -m 'Add feature'`). 49 | 4. Push to the branch (`git push origin feature-name`). 50 | 5. Open a Pull Request. 51 | 52 | 53 | ## 💬 Support 54 | 55 | If you have any questions or need help, feel free to open an issue in this repository or contact us. 56 | 57 | --- 58 | 59 | Happy coding! 😊 60 | -------------------------------------------------------------------------------- /api.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, request, jsonify 2 | import cloudscraper 3 | from bs4 import BeautifulSoup 4 | import re 5 | from urllib.parse import urljoin 6 | import socket 7 | import sys 8 | import logging 9 | import requests 10 | 11 | app = Flask(__name__) 12 | 13 | # Configure logging to show warnings and errors, but reduce noise 14 | log = logging.getLogger('werkzeug') 15 | log.setLevel(logging.WARNING) 16 | 17 | def get_local_ip(): 18 | """Get the machine's local IP address.""" 19 | try: 20 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 21 | s.connect(("8.8.8.8", 80)) # Connect to a public IP to get local IP 22 | ip = s.getsockname()[0] 23 | s.close() 24 | return ip 25 | except Exception: 26 | return "0.0.0.0" # Fallback to default 27 | 28 | def get_facebook_thumbnail_url(video_url): 29 | """ 30 | Fetches the thumbnail download URL for a given Facebook video URL. 31 | 32 | Args: 33 | video_url (str): The Facebook video URL 34 | 35 | Returns: 36 | str: The thumbnail download URL or None if not found 37 | """ 38 | api_url = "https://vidthumbnail.com/facebook/download" 39 | payload = {"videoUrl": video_url} 40 | 41 | try: 42 | response = requests.post(api_url, data=payload, headers={ 43 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" 44 | }) 45 | 46 | if response.status_code != 200: 47 | return None 48 | 49 | soup = BeautifulSoup(response.text, 'html.parser') 50 | download_button = soup.find('a', class_='btn py-3 px-4 facebook btn-lg w-100') 51 | 52 | if not download_button: 53 | return None 54 | 55 | download_url = download_button.get('href') 56 | if not download_url: 57 | return None 58 | 59 | if download_url.startswith('/'): 60 | download_url = urljoin("https://vidthumbnail.com", download_url) 61 | 62 | return download_url 63 | 64 | except Exception: 65 | return None 66 | 67 | def get_fb_video_links(fb_url): 68 | """ 69 | Fetches download links for a given Facebook video URL using savef.app API. 70 | 71 | Args: 72 | fb_url (str): The Facebook video URL 73 | 74 | Returns: 75 | dict: Same format as FDown.net response with links, title, and thumbnail 76 | """ 77 | api_url = "https://savef.app/api/ajaxSearch" 78 | payload = { 79 | "p": "home", 80 | "q": fb_url, 81 | "lang": "en", 82 | "web": "savef.app", 83 | "v": "v2", 84 | "w": "" 85 | } 86 | headers = { 87 | "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 88 | "Origin": "https://savef.app", 89 | "Referer": "https://savef.app/", 90 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" 91 | } 92 | 93 | try: 94 | response = requests.post(api_url, data=payload, headers=headers) 95 | response.raise_for_status() 96 | html_content = response.json().get("data", "") 97 | 98 | soup = BeautifulSoup(html_content, "html.parser") 99 | download_links = [] 100 | 101 | for link in soup.select("a.download-link-fb"): 102 | quality = link.find_previous("td", class_="video-quality").text.strip() 103 | # Map savef.app quality to FDown.net style (HD or SD) 104 | normalized_quality = "HD" if "720p" in quality else "SD" 105 | href = link["href"] 106 | download_links.append({'quality': normalized_quality, 'url': href}) 107 | 108 | if not download_links: 109 | return {"error": "No downloadable video links found from savef.app."} 110 | 111 | # Get thumbnail URL 112 | thumbnail_url = get_facebook_thumbnail_url(fb_url) 113 | 114 | return { 115 | "links": download_links, 116 | "title": "Unknown Title", # Title not available from savef.app 117 | "thumbnail": thumbnail_url if thumbnail_url else "Not available" 118 | } 119 | 120 | except Exception as e: 121 | return {"error": f"Failed to fetch download links from savef.app: {str(e)}"} 122 | 123 | def get_fdown_download_links(fb_url): 124 | """ 125 | Scrape FDown.net to get download links, title, and thumbnail for a given Facebook video URL. 126 | If FDown.net fails, use savef.app as a fallback. 127 | 128 | Args: 129 | fb_url (str): The Facebook video URL to download. 130 | 131 | Returns: 132 | dict: Contains download links, video title, thumbnail URL, or error message. 133 | """ 134 | try: 135 | base_url = "https://fdown.net/" 136 | session = cloudscraper.create_scraper() 137 | headers = { 138 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36', 139 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8', 140 | 'Accept-Language': 'en-US,en;q=0.9', 141 | 'Referer': base_url, 142 | 'Connection': 'keep-alive', 143 | 'Upgrade-Insecure-Requests': '1', 144 | 'DNT': '1' 145 | } 146 | 147 | # Fetch main page 148 | response = session.get(base_url, headers=headers, timeout=5) 149 | response.raise_for_status() 150 | 151 | # Submit form to download.php 152 | form_data = {'URLz': fb_url} 153 | action_url = urljoin(base_url, "download.php") 154 | post_response = session.post(action_url, data=form_data, headers=headers, timeout=5) 155 | post_response.raise_for_status() 156 | 157 | # Parse response 158 | soup = BeautifulSoup(post_response.text, 'html.parser') 159 | 160 | # Check for errors 161 | error_div = soup.find('div', class_='alert-danger') 162 | if error_div: 163 | error_text = error_div.get_text(strip=True).lower() 164 | if "private" in error_text or "invalid" in error_text or "not found" in error_text: 165 | # Try fallback API 166 | return get_fb_video_links(fb_url) 167 | return {"error": "Unknown error from FDown.net"} 168 | 169 | # Extract video title 170 | title = None 171 | title_tag = soup.find('title') 172 | if title_tag: 173 | title = title_tag.get_text(strip=True) 174 | else: 175 | # Fallback to h1 or h2 if title tag is missing 176 | heading = soup.find(['h1', 'h2']) 177 | if heading: 178 | title = heading.get_text(strip=True) 179 | # Clean up title (remove site branding if present) 180 | if title and "FDown" in title: 181 | title = title.replace(" - FDown", "").strip() 182 | if not title: 183 | title = "Unknown Title" 184 | 185 | # Extract download links 186 | download_links = [] 187 | sd_link = soup.find('a', id='sdlink') 188 | hd_link = soup.find('a', id='hdlink') 189 | 190 | if sd_link and sd_link.get('href'): 191 | download_links.append({'quality': 'SD', 'url': sd_link['href']}) 192 | 193 | if hd_link and hd_link.get('href'): 194 | download_links.append({'quality': 'HD', 'url': hd_link['href']}) 195 | 196 | # Fallback: Extract .mp4 links using regex 197 | if not download_links: 198 | link_pattern = re.compile(r'(https?://[^\s\'"]+\.mp4[^\'"\s]*)') 199 | matches = link_pattern.findall(post_response.text) 200 | for i, link in enumerate(set(matches), 1): 201 | download_links.append({'quality': f'Quality_{i}', 'url': link}) 202 | 203 | if not download_links: 204 | # Try fallback API 205 | return get_fb_video_links(fb_url) 206 | 207 | # Get thumbnail URL 208 | thumbnail_url = get_facebook_thumbnail_url(fb_url) 209 | 210 | return { 211 | "links": download_links, 212 | "title": title, 213 | "thumbnail": thumbnail_url if thumbnail_url else "Not available" 214 | } 215 | 216 | except Exception as e: 217 | # Try fallback API 218 | return get_fb_video_links(fb_url) 219 | 220 | @app.route('/', methods=['GET']) 221 | def welcome(): 222 | """ 223 | Root endpoint with a basic welcome message. 224 | """ 225 | return jsonify({ 226 | "status": "success", 227 | "message": "Welcome to the Facebook Video Downloader API!", 228 | "endpoint": "/dl?url=", 229 | "example": "/dl?url=https://www.facebook.com/some-public-video", 230 | "response_format": { 231 | "links": [{"quality": "HD/SD", "url": "download_url"}], 232 | "title": "video_title", 233 | "thumbnail": "thumbnail_url" 234 | } 235 | }), 200 236 | 237 | @app.route('/dl', methods=['GET']) 238 | def download_links(): 239 | """ 240 | API endpoint to get download links, title, and thumbnail for a Facebook video URL. 241 | 242 | Query Parameter: 243 | url: The Facebook video URL (e.g., /dl?url=https://www.facebook.com/video-url) 244 | 245 | Response JSON: 246 | {"links": [{"quality": "HD", "url": "link"}, ...], "title": "Video Title", "thumbnail": "thumbnail_url"} or {"error": "message"} 247 | """ 248 | try: 249 | fb_url = request.args.get('url', '').strip() 250 | if not fb_url: 251 | return jsonify({"error": "Missing 'url' query parameter"}), 400 252 | 253 | result = get_fdown_download_links(fb_url) 254 | if "error" in result: 255 | return jsonify(result), 400 256 | 257 | return jsonify(result), 200 258 | 259 | except Exception as e: 260 | return jsonify({"error": f"Server error: {str(e)}"}), 500 261 | 262 | if __name__ == "__main__": 263 | port = 5000 264 | ip = get_local_ip() 265 | print(f"Starting Flask server on http://{ip}:{port}/", flush=True) 266 | try: 267 | app.run(host="0.0.0.0", port=port, debug=True) 268 | except Exception as e: 269 | print(f"Failed to start server: {str(e)}", flush=True) 270 | sys.exit(1) 271 | --------------------------------------------------------------------------------