UNPKG

@sugarcube/plugin-twitter

Version:
139 lines (120 loc) 4.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.search = exports.friends = exports.followers = exports.feed = exports.tweets = exports.parseApiErrors = void 0; var _fp = require("lodash/fp"); var _dashp = require("dashp"); var _core = require("@sugarcube/core"); var _utils = require("./utils"); var _entities = require("./entities"); // The requests within a 15 minutes window in milliseconds. const rateLimit = requests => 15 * 60 / requests * 1000; // FIXME: Refactor to uncouple everything from the logger. const apiErrors = (0, _fp.curry)((log, user, e) => { if (/401/.test(e.message)) { log.warn(`Failed to fetch ${user}: ${e.message}`); return []; } if (e[0] && e[0].code === 34) { log.warn(`Failed to fetch ${user}: ${e[0].message}`); return []; } throw e; }); const parseApiErrors = e => { if (e[0] && e[0].message != null) return e[0].message; if (e[0]) return JSON.stringify(e[0]); if (e.message != null) return e.message; return JSON.stringify(e); }; exports.parseApiErrors = parseApiErrors; const tweets = (0, _fp.curry)((cfg, tweetIds) => { const delay = rateLimit(300); const op = (0, _utils.throttle)(delay, (0, _utils.request)(cfg, "statuses/lookup.json")); const params = { id: tweetIds.join(","), map: true, tweet_mode: "extended" }; return (0, _dashp.flowP)([op], params); }); exports.tweets = tweets; const feed = (0, _fp.curry)((cfg, user) => { const count = cfg.twitter.tweet_count; const retweets = cfg.twitter.tweet_count; const delay = rateLimit(1500); const op = (0, _utils.throttle)(delay, (0, _utils.request)(cfg, "statuses/user_timeline.json")); const params = { count, include_rts: retweets, [(0, _fp.isNaN)(Number(user)) ? "screen_name" : "user_id"]: user }; const decisions = (0, _core.createFeatureDecisions)(); const transform = decisions.canNcube() ? _entities.tweetNcube : _entities.tweetLegacy; return (0, _dashp.flowP)([op, (0, _fp.map)(transform)], params); }); exports.feed = feed; const followers = (cfg, log, users) => { const recurseDepth = cfg.twitter.recurse_depth; const delay = rateLimit(15); const op = (0, _utils.recurse)(recurseDepth, "screen_name", (0, _utils.cursorify)((0, _utils.throttle)(delay, (0, _utils.request)(cfg, "followers/list.json")))); return (0, _dashp.foldP)((memo, user) => { const params = { screen_name: user, count: 200, include_user_entities: true }; return (0, _dashp.flowP)([op, (0, _dashp.tapP)(rs => log.info(`Fetched ${(0, _fp.size)(rs)} followers of ${user}.`)), (0, _dashp.caughtP)(apiErrors(log, user)), (0, _fp.flow)([_entities.followersTransform, (0, _fp.concat)(memo)])], params); }, [], users); }; exports.followers = followers; const friends = (cfg, log, users) => { const recurseDepth = cfg.twitter.recurse_depth; const delay = rateLimit(15); const op = (0, _utils.recurse)(recurseDepth, "screen_name", (0, _utils.cursorify)((0, _utils.throttle)(delay, (0, _utils.request)(cfg, "friends/list.json")))); return (0, _dashp.foldP)((memo, user) => { const params = { screen_name: user, count: 200, include_user_entities: true }; return (0, _dashp.flowP)([op, (0, _dashp.tapP)(rs => log.info(`Fetched ${(0, _fp.size)(rs)} friends of ${user}.`)), (0, _dashp.caughtP)(apiErrors(log, user)), (0, _fp.flow)([_entities.friendsTransform, (0, _fp.concat)(memo)])], params); }, [], users); }; exports.friends = friends; const search = (0, _fp.curry)((cfg, log, queries) => { const modifiers = ["twitter.language", "twitter.geocode"].reduce((memo, key) => { switch (key) { case "twitter.language": return (0, _fp.get)(key, cfg) ? (0, _fp.merge)(memo, { lang: (0, _fp.get)(key, cfg) }) : memo; case "twitter.geocode": return (0, _fp.get)(key, cfg) ? (0, _fp.merge)(memo, { geocode: (0, _fp.get)(key, cfg) }) : memo; default: return memo; } }, {}); const delay = rateLimit(180); const op = (0, _utils.throttle)(delay, (0, _utils.request)(cfg, "search/tweets.json")); return (0, _dashp.foldP)((memo, query) => { const q = (0, _fp.flow)([(0, _fp.split)(" "), (0, _fp.map)(encodeURIComponent), (0, _fp.join)("+")])(query); const params = (0, _fp.merge)({ count: 100, q }, modifiers); return (0, _dashp.flowP)([op, (0, _dashp.tapP)(rs => log.info(`Fetched ${(0, _fp.size)(rs.statuses)} tweets for the term ${query}`)), (0, _fp.flow)([(0, _fp.property)("statuses"), _entities.searchTransform, (0, _fp.map)((0, _fp.merge)({ query })), (0, _fp.concat)(memo)])], params); }, [], queries); }); exports.search = search; var _default = { feed, followers, friends, search }; exports.default = _default;