-
-
Notifications
You must be signed in to change notification settings - Fork 435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature Request] Twitter feeds? #454
Comments
Been doing some more research. Here's the blog article explaining how a dev implemented RSS feeds from twitter back in the day (and here is his Gist. I've also taken a brief look at the Feedbro source (available, once you install the Feedbro extension, at |
Relevant snippet of feedbro.min.jsI don't fully understand it, but seeing an authtoken and a bunch of references to graphQL, I'm wondering if Feedbro is abusing a workaround in Twitter's social network sharing graphQL implementation to extract images and stringified text? Click me to see the code; I am very very long (~760 lines JS)feedbro.TwPlugin.authToken = "AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA";
feedbro.TwPlugin.cachedToken = null;
feedbro.TwPlugin.prototype.canParse = function (b) {
if (b == undefined || b == "") {
return false
}
b = this.mapUrl(b);
var c = b.substring(0, 20);
var a = b.substring(20);
return c == "https://twitter.com/" && a != "notifications" && a != "home" && a.indexOf("messages") != 0 && a.indexOf("i/bookmarks") != 0
};
feedbro.TwPlugin.prototype.mapUrl = function (a) {
if (a && a.substring(0, 26) == "https://mobile.twitter.com") {
a = "https://twitter.com/" + a.substring(27)
}
return a
};
feedbro.TwPlugin.prototype.parse = function (d, c, a, e) {
var b = this;
d.url = this.mapUrl(d.url);
this.getCachedGuestToken(function (f) {
b.doParse(d, c, a, e)
})
};
feedbro.TwPlugin.prototype.getCachedGuestToken = function (a) {
if (feedbro.TwPlugin.cachedToken == null || this.isTokenExpired(feedbro.TwPlugin.cachedToken)) {
this.getGuestToken(function (b) {
if (b && b.token) {
feedbro.TwPlugin.cachedToken = b
} else {
feedbro.TwPlugin.cachedToken = {
remaining: 0,
init: 0
}
}
a(b)
})
} else {
feedbro.TwPlugin.cachedToken.lastUse = new Date().getTime();
a(feedbro.TwPlugin.cachedToken)
}
};
feedbro.TwPlugin.prototype.getGuestToken = function (a) {
fetchTimeout("https://api.twitter.com/1.1/guest/activate.json", 20000, {
method: "POST",
credentials: "omit",
headers: {
authorization: "Bearer " + feedbro.TwPlugin.authToken,
"accept-language": "en-US,en;q=0.5",
accept: "text/html,application/json,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
}
}).then(function (b) {
return b.json()
}).then(function (c) {
var b = new Date().getTime();
if (c == null) {
c = {}
}
a({
token: c.guest_token,
remaining: 187,
init: b,
reset: b + (15 * 60 * 1000),
lastUse: b
})
})["catch"](a)
};
feedbro.TwPlugin.prototype.isTokenExpired = function (b) {
var d = 2 * 60 * 60 * 1000;
var c = 1 * 60 * 60 * 1000;
var a = new Date().getTime();
return b == null || b.init < (a - d) || b.remaining < 10 || a > b.reset || b.lastUse < (a - c)
};
feedbro.TwPlugin.prototype.doParse = function (f, d, a, g) {
var b = this;
try {
this.getUrl(f.url, a, function (l, j, h, k) {
try {
if (j && j.globalObjects) {
d(f.url, l, b.parseTweets(j, h, k), a, g, true)
} else {
d(f.url, l, b.parseTimeline(j, h, k), a, g, true)
}
} catch (i) {
d(f.url, l, "", a, g, true)
}
})
} catch (c) {
var e = new feedbro.FetchWrapper(500);
a.error = {};
a.error.message = "Internal Server Error";
a.error.code = 500;
a.status = 500;
d(f.url, e, "", a, g, true)
}
};
feedbro.TwPlugin.prototype.getUserProfile = function (c, a, e) {
var d = c.match(/^https:\/\/twitter\.com\/(\w+)/)[1];
var b = "https://twitter.com/i/api/graphql/7mjxD3-C6BxitPMVQ6w0-Q/UserByScreenName?variables=%7B%22screen_name%22%3A%22" + d + "%22%2C%22withSafetyModeUserFields%22%3Atrue%2C%22withSuperFollowsUserFields%22%3Atrue%7D";
this.loadJson(b, a, function (g, f) {
e(f, c)
})
};
feedbro.TwPlugin.prototype.getThread = function (c, a, d) {
var b = this;
this.getUserProfile(c, a, function (f, e) {
b.loadThread(e, f, a, d)
})
};
feedbro.TwPlugin.prototype.loadThread = function (a, c, i, h) {
var f = 0;
var d = a.match(/status\/(\d+)/);
if (d) {
f = d[1]
}
var e = 0;
if (c && c.data && c.data.user) {
if (c.data.user.result) {
e = c.data.user.result.rest_id
} else {
e = c.data.user.rest_id
}
}
var b = {
focalTweetId: f,
with_rux_injections: false,
includePromotedContent: true,
withCommunity: true,
withQuickPromoteEligibilityTweetFields: true,
withBirdwatchNotes: false,
withSuperFollowsUserFields: true,
withDownvotePerspective: false,
withReactionsMetadata: false,
withReactionsPerspective: false,
withSuperFollowsTweetFields: true,
withVoice: true,
withV2Timeline: false,
__fs_dont_mention_me_view_api_enabled: false,
__fs_interactive_text_enabled: true,
__fs_responsive_web_uc_gql_enabled: false
};
var g = "https://twitter.com/i/api/graphql/LJ_TjoWGgNTXCl7gfx4Njw/TweetDetail?variables=" + encodeURIComponent(JSON.stringify(b));
this.loadJson(g, i, function (l, j) {
var k;
if (c && c.data && c.data.user) {
if (c.data.user.result) {
k = c.data.user.result.legacy
} else {
if (c.data.user.legacy) {
k = c.data.user.legacy
}
}
}
if (k) {
h(l, j, a, e != 0 ? (k.name + " (@" + k.screen_name + ") Thread " + f + " | Twitter") : "")
} else {
h(l, j, a, "Suspended")
}
})
};
feedbro.TwPlugin.prototype.loadUserTweets = function (c, e, a, g) {
var d = 0;
if (e && e.data && e.data.user) {
if (e.data.user.result) {
d = e.data.user.result.rest_id
} else {
d = e.data.user.rest_id
}
}
var f = {
userId: d,
count: 40,
includePromotedContent: true,
withQuickPromoteEligibilityTweetFields: true,
withSuperFollowsUserFields: true,
withBirdwatchPivots: false,
withDownvotePerspective: false,
withReactionsMetadata: false,
withReactionsPerspective: false,
withSuperFollowsTweetFields: true,
withVoice: true,
withV2Timeline: false,
__fs_interactive_text: false,
__fs_dont_mention_me_view_api_enabled: false
};
var b = "https://twitter.com/i/api/graphql/DhQ8lYnLh5T5K8aVUgHVnQ/UserTweets?variables=" + encodeURIComponent(JSON.stringify(f));
this.loadJson(b, a, function (j, h) {
var i;
if (e && e.data && e.data.user) {
if (e.data.user.result) {
i = e.data.user.result.legacy
} else {
if (e.data.user.legacy) {
i = e.data.user.legacy
}
}
}
if (i) {
g(j, h, c, d != 0 ? (i.name + " (@" + i.screen_name + ") | Twitter") : "")
} else {
g(j, h, c, "Suspended")
}
})
};
feedbro.TwPlugin.prototype.getUserTweets = function (c, a, d) {
var b = this;
this.getUserProfile(c, a, function (f, e) {
b.loadUserTweets(e, f, a, d)
})
};
feedbro.TwPlugin.prototype.getListTweets = function (d, a, f) {
var b = d.match(/^https:\/\/twitter\.com\/i\/lists\/(\d+)/)[1];
var e = {
listId: b,
count: 20,
withSuperFollowsUserFields: true,
withBirdwatchPivots: false,
withDownvotePerspective: false,
withReactionsMetadata: false,
withReactionsPerspective: false,
withSuperFollowsTweetFields: true,
__fs_interactive_text: false,
__fs_dont_mention_me_view_api_enabled: false
};
var c = "https://twitter.com/i/api/graphql/mwIBwcZV981Bnjb2lPNYfw/ListLatestTweetsTimeline?variables=" + encodeURIComponent(JSON.stringify(e));
this.loadJson(c, a, function (h, g) {
f(h, g, d, "List " + b)
})
};
feedbro.TwPlugin.prototype.getHashtagTweets = function (g, d, i) {
var e = g.indexOf("hashtag/") + 8;
var c = g.indexOf("?", e);
var h = g.substring(e, c > 0 ? c : g.length);
var f = "https://api.twitter.com/2/search/adaptive.json?include_profile_interstitial_type=1&include_blocking=1&include_blocked_by=1&include_followed_by=1&include_want_retweets=1&include_mute_edge=1&include_can_dm=1&include_can_media_tag=1&skip_status=1&cards_platform=Web-12&include_cards=1&include_ext_alt_text=true&include_reply_count=1&tweet_mode=extended&include_entities=true&include_user_entities=true&include_ext_media_color=true&include_ext_media_availability=true&send_error_codes=true&simple_quoted_tweet=true&q=%23" + h + "&count=20&query_source=hashtag_click&pc=1&spelling_corrections=1&ext=mediaStats%2ChighlightedLabel%2CcameraMoment&include_quote_count=true";
if (g.indexOf("&f=live") != -1) {
f = f + "&tweet_search_mode=live"
}
this.loadJson(f, d, function (b, a) {
i(b, a, g, "#" + decodeURIComponent(h) + " - Search")
})
};
feedbro.TwPlugin.prototype.getSearchTweets = function (g, d, i) {
var e = g.indexOf("q=") + 2;
var c = g.indexOf("&", e);
var h = g.substring(e, c > 0 ? c : g.length);
var f = "https://api.twitter.com/2/search/adaptive.json?include_profile_interstitial_type=1&include_blocking=1&include_blocked_by=1&include_followed_by=1&include_want_retweets=1&include_mute_edge=1&include_can_dm=1&include_can_media_tag=1&skip_status=1&cards_platform=Web-12&include_cards=1&include_ext_alt_text=true&include_reply_count=1&tweet_mode=extended&include_entities=true&include_user_entities=true&include_ext_media_color=true&include_ext_media_availability=true&send_error_codes=true&simple_quoted_tweet=true&q=" + h + "&count=20&query_source=typed_query&pc=1&spelling_corrections=1&ext=mediaStats%2ChighlightedLabel%2CcameraMoment&include_quote_count=true";
if (g.indexOf("&f=live") != -1) {
f = f + "&tweet_search_mode=live"
}
this.loadJson(f, d, function (b, a) {
i(b, a, g, decodeURIComponent(h) + " - Search")
})
};
feedbro.TwPlugin.prototype.getExploreTweets = function (c, a, d) {
var b = "https://api.twitter.com/2/guide.json?include_profile_interstitial_type=1&include_blocking=1&include_blocked_by=1&include_followed_by=1&include_want_retweets=1&include_mute_edge=1&include_can_dm=1&include_can_media_tag=1&skip_status=1&cards_platform=Web-12&include_cards=1&include_ext_alt_text=true&include_reply_count=1&tweet_mode=extended&include_entities=true&include_user_entities=true&include_ext_media_color=true&include_ext_media_availability=true&send_error_codes=true&simple_quoted_tweet=true&include_page_configuration=true&count=20&ext=mediaStats%2ChighlightedLabel%2CcameraMoment&include_quote_count=true";
this.loadJson(b, a, function (f, e) {
d(f, e, c, "Explore")
})
};
feedbro.TwPlugin.prototype.loadJson = function (c, b, d) {
var a = new feedbro.FetchWrapper(500);
fetchTimeout(c, 20000, {
method: "GET",
credentials: "omit",
headers: {
authorization: "Bearer " + feedbro.TwPlugin.authToken,
"accept-language": "en-US,en;q=0.5",
accept: "*/*",
"x-guest-token": feedbro.TwPlugin.cachedToken ? feedbro.TwPlugin.cachedToken.token : "",
"x-twitter-client-language": "en",
"x-twitter-active-user": "yes",
"cache-control": "no-cache"
}
}).then(function (e) {
a.status = e.status + 0;
if (e.status == 200) {
if (feedbro.TwPlugin.cachedToken) {
feedbro.TwPlugin.cachedToken.remaining = parseInt(e.headers.get("x-rate-limit-remaining") || "0", 10);
feedbro.TwPlugin.cachedToken.reset = parseInt(e.headers.get("x-rate-limit-reset"), 10) * 1000
}
return e.json()
} else {
throw new Error(e.status + 0)
}
}).then(function (e) {
d(a, e)
})["catch"](function (e) {
if (e.name == "AbortError") {
b.error = {};
b.error.message = "Network error";
b.error.code = 398;
b.status = 398;
a.status = 0
}
d(a, null)
})
};
feedbro.TwPlugin.prototype.getUrl = function (c, a, d) {
var b = c.substring(20);
if (b.indexOf("i/lists/") == 0) {
this.getListTweets(c, a, d)
} else {
if (b.indexOf("hashtag/") == 0) {
this.getHashtagTweets(c, a, d)
} else {
if (b.indexOf("search?") == 0) {
this.getSearchTweets(c, a, d)
} else {
if (b.indexOf("explore") == 0) {
this.getExploreTweets(c, a, d)
} else {
if (b != "notifications" && b.indexOf("messages") != 0 && b.indexOf("i/bookmarks") != 0) {
this.getUserTweets(c, a, d)
} else {
d(undefined)
}
}
}
}
}
};
feedbro.TwPlugin.prototype.parseTweets = function (B, c, C) {
var t = '<?xml version="1.0" encoding="UTF-8"?>\n<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">\n<channel>\n';
if (B != undefined) {
var j = /#(\D\S+)/g;
var g = /@(\w+)/g;
var r = /\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim;
var k = [];
var b;
var q = B.globalObjects.tweets;
var n = B.globalObjects.users;
var u,
a,
D,
m = Object.keys(q);
var y;
var w;
var p;
var e;
var s;
var o;
var f;
var x;
var A;
var l;
var h;
var v;
var z;
m.sort(function (E, i) {
return new Date(q[i].created_at).getTime() - new Date(q[E].created_at).getTime()
});
try {
for (u = 0; u < m.length; u++) {
a = q[m[u]];
x = a;
if (a.source == 0) {
continue
}
D = n[a.user_id_str];
o = D;
f = a.id_str;
s = a.created_at;
if (a.retweeted_status_id_str != undefined) {
z = a.retweeted_status_id_str;
a = q[z];
D = n[a.user_id_str];
q[z].source = 0
}
A = undefined;
e = undefined;
if (a.is_quote_status) {
A = a.full_text;
if (q[a.quoted_status_id_str] != undefined) {
e = q[a.quoted_status_id_str];
q[a.quoted_status_id_str].source = 0
}
}
y = undefined;
w = undefined;
v = this.getContent(a);
y = v.card;
w = v.media;
p = this.getAuthorHeader(D, x.retweeted_status_id_str != undefined ? o : null, a);
b = {
author: o.name + " (@" + o.screen_name + ")",
publishedDate: new Date(s),
guid: o.screen_name + "-" + f,
link: "https://twitter.com/" + o.screen_name + "/status/" + f,
content: a.full_text,
title: this._strings.truncate((A || a.full_text).replace(r, ""), 100, "…")
};
b.content = "<p class='tweet-text'>" + b.content + "</p>";
b.content = feedbro.Strings.linkify(b.content, true, "twitter-tweet-link");
b.content = b.content.replace(j, this.hashtagMapper);
b.content = b.content.replace(g, this.usernameMapper);
if (w && !y) {
b.content += w
}
if (y) {
b.content += y
}
if (e) {
h = "";
D = n[e.user_id_str];
v = this.getContent(e);
l = e.full_text;
l = feedbro.Strings.linkify(l, true, "twitter-tweet-link");
l = l.replace(j, this.hashtagMapper);
l = l.replace(g, this.usernameMapper);
h += "<div class='twitter-quoted-tweet'>";
h += " <div class='twitter-quoted-author'>";
h += " <img class='twitter-authorimage-quoted' src='" + D.profile_image_url_https + "'>";
h += " <span class='twitter-author-name-quoted'>" + D.name + "</span>";
h += " <span class='twitter-author-username-quoted'><a target='_blank' class='twitter-username' href='https://twitter.com/" + D.screen_name + "' rel='noopener noreferrer'>@" + D.screen_name + "</a></span>";
h += " <span class='twitter-timestamp-quoted'> · " + this.getDateTag(e.created_at, D, e.id_str) + "</span>";
h += " </div>";
h += " <div class='twitter-quoted-content'>" + l + "</div>";
if (v.media && !v.card) {
h += v.media
} else {
if (v.card) {
h += v.card
}
}
h += "</div>";
b.content += h
}
b.content = p + b.content;
if (A) {
b.content += "</div>"
}
k.push(b)
}
} catch (d) {}
return feedbro.Strings.toRSS(C + " | Twitter", c, k)
} else {
t += " <title>No Content Found</title>\n";
t += " <link>" + c.replace(/&/g, "&") + "</link>\n"
}
t += "</channel>\n</rss>";
return t
};
feedbro.TwPlugin.prototype.getSizeAttribute = function (a) {
if (a && a.original_info) {
return "width='" + a.original_info.width + "' height='" + a.original_info.height + "' "
} else {
return ""
}
};
feedbro.TwPlugin.prototype.getContent = function (l) {
var f,
d,
a,
h,
g,
b,
m,
c,
k,
i;
if (l.extended_entities && l.extended_entities.media) {
d = this.getMedia(l)
}
if (l.card && l.card.binding_values && l.card.name != "promo_website") {
f = this.createCardWithAttributes(l.card.binding_values, l.card.url)
}
return {
card: f,
media: d
}
};
feedbro.TwPlugin.prototype.linkMapper = function (b, a) {
return "<a target='_blank' class='twitter-tweet-link' rel='noopener noreferrer' href='" + b + "'>" + a + "</a>"
};
feedbro.TwPlugin.prototype.hashtagMapper = function (a, b) {
return "<a target='_blank' class='twitter-hashtag' rel='noopener noreferrer' href='https://twitter.com/hashtag/" + b + "?src=hashtag_click'>#" + b + "</a>"
};
feedbro.TwPlugin.prototype.usernameMapper = function (b, a) {
return "<a target='_blank' class='twitter-username' rel='noopener noreferrer' href='https://twitter.com/" + a + "'>" + b + "</a>"
};
feedbro.TwPlugin.prototype.parseTimeline = function (b, a, d) {
var c = this.parseTwitterTimeline(b, d);
if (c.title == null && a != null) {
c.title = a.substring(a.lastIndexOf("/") + 1) + " | Twitter"
}
return feedbro.Strings.toRSS(c.title || "User | Twitter", a || "", c.items)
};
feedbro.TwPlugin.prototype.parseTwitterTimeline = function (s, c) {
var l = [];
var f,
k;
var e,
g,
q,
d,
b,
m,
a = c,
p;
if (s.data.user) {
if (s.data.user.result.timeline_v2) {
f = s.data.user.result.timeline_v2.timeline.instructions
} else {
f = s.data.user.result.timeline.timeline.instructions
}
} else {
if (s.data.list) {
f = s.data.list.tweets_timeline.timeline.instructions
} else {
if (s.data.threaded_conversation_with_injections) {
f = s.data.threaded_conversation_with_injections.instructions
}
}
}
for (e = 0; e < f.length; e++) {
k = f[e];
if (k.entries) {
for (g = 0; g < k.entries.length; g++) {
l.push(k.entries[g])
}
} else {
if (k.entry && k.type == "TimelinePinEntry") {
l.push(k.entry)
}
}
}
var o = [];
var n = /\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim;
for (e = 0; e < l.length; e++) {
q = l[e];
if (q.content.entryType == "TimelineTimelineItem") {
if (q.content.itemContent.tweet_results == null) {
continue
}
b = q.content.itemContent.tweet_results.result;
if (b == null || b.tombstone) {
continue
}
var h;
if (b.core == null && b.tweet && b.tweet.legacy) {
d = b.tweet.core.user_results.result.legacy;
h = b.tweet.legacy
} else {
if (b.core) {
d = b.core.user_results.result.legacy;
h = b.legacy
} else {
continue
}
}
if (h.retweeted_status_result) {
m = this.getRetweet(h.retweeted_status_result.result, d);
p = h.retweeted_status_result.result.legacy.full_text
} else {
m = this.getAuthorHeader(d, null, h);
m += this.getTweetBody(h) + this.getMedia(h) + this.getCard(b) + this.getQuote(b);
p = h.full_text
}
p = this._strings.truncate(p.replace(n, ""), 100, "…");
var r = {
publishedDate: new Date(h.created_at),
author: d.name + " (@" + d.screen_name + ")",
content: m,
title: p,
link: "https://twitter.com/" + d.screen_name + "/status/" + h.id_str
};
o.push(r);
if (a == null) {
a = d.name + " (@" + d.screen_name + ") | Twitter"
}
}
}
return {
title: a,
items: o
}
};
feedbro.TwPlugin.prototype.createTweetTextHtml = function (d) {
var c = d.full_text;
c = c.replace(/#(\D\S+)/g, this.hashtagMapper);
c = c.replace(/@(\w+)/g, this.usernameMapper);
if (d.entities && d.entities.urls && d.entities.urls.length > 0) {
var a,
b = d.entities.urls;
for (a = 0; a < b.length; a++) {
c = c.replace(b[a].url, "<a class='twitter-tweet-link' target='_blank' rel='noopener noreferrer' href='" + b[a].expanded_url + "'>" + b[a].display_url + "</a>")
}
}
return c
};
feedbro.TwPlugin.prototype.getAuthorHeader = function (b, d, a) {
var c = "<header>";
if (d != null) {
c += " <div class='twitter-retweet-header'>" + d.name + " Retweeted</div>"
}
c += " <a target='_blank' href='https://twitter.com/" + b.screen_name + "' rel='noopener noreferrer'>";
c += " <img class='twitter-authorimage' alt='' src='" + b.profile_image_url_https + "'>";
c += " </a><span class='twitter-fullname'>" + b.name + "</span>";
c += " <span><a target='_blank' class='twitter-username' href='https://twitter.com/" + b.screen_name + "' rel='noopener noreferrer'>@" + b.screen_name + "</a></span>";
c += "</header>";
return c
};
feedbro.TwPlugin.prototype.getDateTag = function (f, d, h) {
var b = new Date(f);
if (isNaN(b) || d == null) {
return ""
}
var c = this._months[b.getMonth()] + " " + b.getDate();
var a = b.getHours(),
e = b.getMinutes();
var g = (a < 10 ? "0" + a : a) + ":" + (e < 10 ? "0" + e : e) + " " + c + ", " + b.getFullYear();
return "<a class='twitter-timestamp' title='" + g + "' href='https://twitter.com/" + d.screen_name + "/status/" + h + "' target='_blank' rel='noopener noreferrer'>" + c + "</a>"
};
feedbro.TwPlugin.prototype.getRetweet = function (a, d) {
if (a == null || a.core == null || a.core.user_results == null || a.core.user_results.result == null || a.core.user_results.result.legacy == null || a.legacy == null || a.tombstone || a.legacy.tombstone) {
return "<div class='twitter-deleted-tweet'>This tweet is not available.</div>"
}
var c = a.core.user_results.result.legacy;
var b = a.legacy;
return this.getAuthorHeader(c, d, b) + this.getTweetBody(b) + this.getMedia(b) + this.getCard(a) + this.getQuote(a)
};
feedbro.TwPlugin.prototype.getQuote = function (e) {
if (e.quoted_status_result) {
var a = e.quoted_status_result;
if (a.result.tombstone) {
return "<div class='twitter-quoted-tweet'>This tweet was deleted by the Tweet author.</div>"
} else {
var c = a.result.core.user_results.result.legacy;
var b = a.result.legacy;
var d = this.createTweetTextHtml(b) + this.getMedia(b);
return this.getQuoteHtml(c, d, b.created_at, b.id_str)
}
} else {
return ""
}
};
feedbro.TwPlugin.prototype.getQuoteHtml = function (a, c, d, e) {
var b = "";
b += "<div class='twitter-quoted-tweet'>";
b += " <div class='twitter-quoted-author'>";
b += " <img class='twitter-authorimage-quoted' alt='' src='" + a.profile_image_url_https + "'>";
b += " <span class='twitter-author-name-quoted'>" + a.name + "</span>";
b += " <span class='twitter-author-username-quoted'><a target='_blank' class='twitter-username' href='https://twitter.com/" + a.screen_name + "' rel='noopener noreferrer'>@" + a.screen_name + "</a></span>";
b += " <span class='twitter-timestamp-quoted'> · " + this.getDateTag(d, a, e) + "</span>";
b += " </div>";
b += " <div class='twitter-quoted-content'>" + c + "</div>";
b += "</div>";
return b
};
feedbro.TwPlugin.prototype.getCard = function (b) {
if (b.card && !b.quoted_status_result && b.card.name != "promo_website") {
var e = b.card;
var f,
d,
c = b.card.legacy.binding_values,
a = {};
for (f = 0; f < c.length; f++) {
d = c[f];
a[d.key] = d.value
}
return this.createCardWithAttributes(a, e.legacy.url)
} else {
return ""
}
};
feedbro.TwPlugin.prototype.createCardWithAttributes = function (b, f) {
var i,
d,
c,
h,
g;
i = "<div class='twitter-card'>";
i += "<a target='_blank' rel='noopener noreferrer' class='twitter-card-url' href='" + f + "'>";
if (b.photo_image_full_size) {
g = b.photo_image_full_size.image_value;
d = g.url
} else {
if (b.photo_image_full_size_large) {
g = b.photo_image_full_size_large.image_value;
d = g.url
} else {
if (b.photo_image_full_size_small) {
g = b.photo_image_full_size_small.image_value;
d = g.url
}
}
}
if (b.thumbnail_image_large) {
h = b.thumbnail_image_large.image_value
} else {
if (b.thumbnail_image) {
h = b.thumbnail_image.image_value
}
}
if (d) {
c = "width='" + g.width + "' height='" + g.height + "'";
i += "<div class='twitter-card-image'><img alt='' src='" + d + "' " + c + "></div>"
} else {
if (h) {
i += "<div class='twitter-thumb'><img alt='' class='twitter-thumb-image' src='" + h.url + "'></div>"
}
}
if (b.title && b.title.string_value) {
i += "<div class='twitter-card-title'>" + this._strings.escapeHtml(b.title.string_value) + "</div>"
}
if (b.description && b.description.string_value) {
i += "<div class='twitter-card-description'>" + this._strings.escapeHtml(b.description.string_value) + "</div>"
}
if (b.domain) {
i += "<div class='twitter-card-url'>" + b.domain.string_value + "</div>"
}
i += "</a></div>";
return i
};
feedbro.TwPlugin.prototype.getTweetBody = function (a) {
return "<p class='tweet-text'>" + this.createTweetTextHtml(a) + "</p>"
};
feedbro.TwPlugin.prototype.getMedia = function (g) {
if (g.extended_entities && g.extended_entities.media) {
var f = g.extended_entities.media[0];
var e,
b,
d = "";
if (f.type == "photo") {
b = this.getSizeAttribute(f);
d = "<div class='twitter-media-photo'><img alt='' class='twitter-media-photo' " + b + "src='" + f.media_url_https + "'></div>"
} else {
if ((f.type == "video" || f.type == "animated_gif") && f.video_info && f.video_info.variants && f.video_info.variants.length > 0) {
var c = f.video_info.variants;
var a = c[0];
if (a.bitrate == undefined) {
a.bitrate = 0
}
for (e = 1; e < c.length; e++) {
if (c[e].bitrate > a.bitrate) {
a = c[e]
}
}
b = this.getSizeAttribute(f);
d = "<div>";
d += '<div class="youtubevideo" data-link="' + a.url + '"><img alt="" src="' + f.media_url_https + '" ' + b + ' class="thumb"><div class="play"></div></div>';
d += "</div>"
}
}
return d
} else {
return ""
}
};
feedbro.TwPlugin.prototype.testParse = function (b, c) {
var a = this;
fetch(b).then(function (d) {
return d.json()
}).then(function (d) {
c(a.parseTimeline(d), a.parseTimelineHtml(d))
})
};
feedbro.TwPlugin.prototype.parseTimelineHtml = function (d, a) {
var e = this.parseTwitterTimeline(d) |
I'm getting the Twitter feed through Nitter, with images, videos and so on. |
Originally posted by @Darthagnon in #23 (comment)
The text was updated successfully, but these errors were encountered: