OhMyDitzzy
Add: twitter downloader
54f33eb
import axios from "axios";
import { sendSuccess, ErrorResponses } from "../../lib/response-helper.js";
import * as cheerio from 'cheerio';
import FormData from 'form-data';
export class Twitter {
constructor() {
this.CREATED_BY = "Ditzzy";
this.NOTE = "Thank you for using this scrape, I hope you appreciate me for making this scrape by not deleting wm";
}
wrapResponse(data) {
return {
created_by: this.CREATED_BY,
note: this.NOTE,
results: data
};
}
async download(link) {
try {
const formData = new FormData();
formData.append('page', link);
formData.append('ftype', 'all');
formData.append('ajax', '1');
const response = await axios.post('https://twmate.com/id2/', formData, {
headers: {
...formData.getHeaders(),
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
});
const html = response.data;
const $ = cheerio.load(html);
const result = {
media: []
};
const videoTable = $('.files-table tbody tr');
if (videoTable.length > 0) {
const titleElement = $('.info-container h4');
if (titleElement.length) {
const fullTitle = titleElement.text().trim();
const separatorIndex = fullTitle.indexOf(' - ');
if (separatorIndex !== -1) {
result.username = fullTitle.substring(0, separatorIndex).trim();
result.caption = fullTitle.substring(separatorIndex + 3).trim();
} else {
result.caption = fullTitle;
}
}
const thumbnailElement = $('.thumb-container img');
if (thumbnailElement.length) {
result.thumbnail = thumbnailElement.attr('src');
}
const likesElement = $('.info-container p span:contains("Suka")');
if (likesElement.length) {
result.likes = likesElement.text().replace('Suka : ', '').trim();
}
videoTable.each((_, element) => {
const quality = $(element).find('td:nth-child(1)').text().trim();
const type = $(element).find('td:nth-child(2)').text().trim();
const url = $(element).find('td:nth-child(3) a').attr('href');
if (url) {
result.media.push({
type,
quality,
url
});
}
});
} else {
$('.card.icard').each((_, card) => {
$(card).find('.card-body a.btn-dl').each((_, link) => {
const downloadUrl = $(link).attr('href');
const qualityText = $(link).text().trim();
const quality = qualityText.replace('Unduh ', '').replace(/\s+/g, '');
if (downloadUrl) {
result.media.push({
type: 'image',
quality,
url: downloadUrl
});
}
});
});
}
return this.wrapResponse(result);
} catch (error) {
throw new Error(`Failed to download: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
}
/** @type {import("../../types/plugin").ApiPluginHandler} */
const handler = {
name: "Twitter Downloader",
description: "Download Twitter Media, Support Photo too",
version: "1.0.0",
method: "GET",
category: ["downloader"],
alias: ["twitter", "tw"],
tags: ["social-media", "video", "downloader"],
parameters: {
query: [
{
name: "url",
type: "string",
required: true,
description: "Your Twitter URL",
example: "https://x.com/ClashofClans/status/2013235147978494164?s=20"
}
],
body: [],
headers: []
},
responses: {
200: {
status: 200,
description: "Successfully retrieved Twitter data",
example: {
status: 200,
author: "Ditzzy",
note: "Thank you for using this API!",
results: {}
}
},
400: {
status: 400,
description: "Invalid Twitter URL provided",
example: {
status: 400,
message: "Invalid URL - must be a valid Twitter URL"
}
},
404: {
status: 404,
description: "Missing required parameter",
example: {
status: 404,
message: "Missing required parameter: ..."
}
},
500: {
status: 500,
description: "Server error or Twitter API unavailable",
example: {
status: 500,
message: "An error occurred, please try again later."
}
}
},
exec: async (req, res) => {
const { url } = req.query
if (!url) return ErrorResponses.missingParameter(res, "url");
const regex = /^https?:\/\/(?:www\.)?(?:x\.com|twitter\.com)\/[a-zA-Z0-9_]+\/status\/(\d+)(?:\?.*)?$/;
if (!regex.test(url)) return ErrorResponses.invalidUrl(res, "Invalid URL - must be a valid Twitter URL");
const tw = new Twitter();
try {
const download = await tw.download(url);
if (download.results.media.length === 0) return ErrorResponses.notFound(res, "Twitter link is invalid, private or Server returned null data");
return sendSuccess(res, download.results);
} catch (e) {
console.error("Twitter download error:", e);
return ErrorResponses.notFound(res, "Twitter link is invalid or Server returned null data");
}
}
}
export default handler;