UNPKG

@flowdegree/swarmapp-api

Version:

A javascript wrapper for swarmapp (foursquare) API

531 lines (522 loc) 17.3 kB
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) { if (typeof require !== "undefined") return require.apply(this, arguments); throw new Error('Dynamic require of "' + x + '" is not supported'); }); // src/utils/index.ts var between = (min, max) => { return Math.floor(Math.random() * (max - min) + min); }; var createLatLngString = (lat, lng) => { return `${lat},${lng}`; }; function getLL() { return this.config.ll; } function log(message) { let _prefix = `${(/* @__PURE__ */ new Date()).toLocaleString()} - `; _prefix += typeof this?.user?.firstName != "undefined" ? this?.user?.firstName : this?.user?.id; console.log(`${_prefix}) `, message); } function error(error2) { let _prefix = `${(/* @__PURE__ */ new Date()).toLocaleString()} - `; _prefix += typeof this?.user?.firstName != "undefined" ? this?.user?.firstName : "unknown user"; _prefix += " - Error: "; switch (error2?.meta?.code) { case 401: console.error(`${_prefix} [${error2.meta.errorType}] ${error2.meta.errorDetail}`); throw new Error(error2); default: console.error(JSON.stringify(`${_prefix} ${error2}`, null, 4)); throw new Error(error2); } } // src/api/main.ts async function initialize() { try { const response = await this.getUser(); this.user = response?.data?.response?.user; return true; } catch (error2) { this.error("Could not authenticate user"); return false; } } // src/api/users.ts import axios from "axios"; import querystring from "querystring"; async function getFriends(user_id = "self") { this.config.user_id = user_id || this.user?.id; try { const result = await axios.get(this.basePath + "users/" + user_id + "/friends", { "params": this.config }); return result.data.response.friends; } catch (error2) { console.log(`error occured while getting friends`); this.error(error2); return null; } } async function getFollowings(user_id = "self") { this.config.user_id = user_id || this.user?.id; this.config.m = "foursquare"; this.config.user_id = user_id; try { const result = await axios.get(this.basePath + "users/" + user_id + "/following", { "params": this.config }); return result.data.response.following; } catch (error2) { console.log(`error occured while getting followings`); this.error(error2); return null; } } async function getFollowers(user_id = "self") { this.user_id = user_id || this.user?.id; this.config.m = "foursquare"; this.config.user_id = user_id; try { const result = await axios.get(this.basePath + "users/" + user_id + "/followers", { "params": this.config }); return result.data.response.followers; } catch (error2) { console.log(`error occured while getting followers`); this.error(error2); return null; } } async function getUser(user_id = "self") { try { const result = await axios.get(`${this.basePath}users/${user_id}`, { "params": this.config }); return result; } catch (error2) { console.log(`error occured while getting user`); this.error(error2); throw new Error("Error getting user data, maybe an authentication error ?"); return; } } async function getUserProfile(user_id = "self") { try { const result = await axios.get(`${this.basePath}users/${user_id}/profile`, { "params": this.config }); return result; } catch (error2) { console.log(`error occured while getting user`); this.error(error2); throw new Error("Error getting user data, maybe an authentication error ?"); } } async function getCheckins(user_id = "self", limit = 100, afterTimestamp) { if (typeof afterTimestamp !== "undefined") { this.config.afterTimeStamp = afterTimestamp; } this.config.user_id = user_id; this.config.limit = limit; try { const result = await axios.get(`${this.basePath}users/${user_id}/checkins`, { "params": this.config }); return result; } catch (error2) { console.log(`error occured while getting checkins`); this.error(error2); return; } } async function addFriendByID(user_id) { try { const userIdStr = user_id.toString(); const parameters = { oauth_token: this.config.oauth_token, v: this.config.v }; const result = await this.getUserProfile(userIdStr); const newFriend = result?.data?.response?.user; if (newFriend?.relationship === "none") { const postUrl = `${this.basePath}users/${userIdStr}/request`; console.log(`Adding friend by id ${newFriend.handle}...`); const result2 = await axios.post(`${postUrl}?${querystring.stringify(parameters)}`); return result2.data.response.user; } else { return false; } } catch (error2) { console.log(`error occured while adding friend by id ${user_id}`); return false; } } async function getLastSeen(user_id = "self", limit = 100) { this.config.user_id = user_id; this.config.limit = limit; try { return getUser(user_id); } catch (error2) { console.log(`error occured while getting last seen`); this.error(error2); } } async function getGeos(user_id = "self") { this.config.user_id = user_id; delete this.config.afterTimeStamp; try { const response = await axios.get(this.basePath + "/users/" + user_id + "/map", { "params": this.config }); return response.data.response; } catch (error2) { console.log(`error occured while getting geos`); this.error(error2); } } // src/api/checkins.ts import axios2 from "axios"; import querystring2 from "querystring"; async function checkIn(venue_id, silent = false) { if (silent) { this.config.broadcast = "private"; } this.config.venueId = venue_id; const venue_info = await this.getVenue(venue_id); this.config.ll = createLatLngString(venue_info.location.lat, venue_info.location.lng); try { const result = await axios2.post(this.basePath + "checkins/add", querystring2.stringify(this.config)); const checkin = result.data.response?.checkin; return checkin; } catch (error2) { console.log(`error occured while checking in`); this.error(error2); return; } } async function getRecent(limit = 100, ll) { this.config.limit = limit; this.config.afterTimeStamp = (Math.floor(Date.now() / 1e3) - 1 * 24 * 60 * 60).toString(); if (typeof ll !== "undefined") { this.config.ll = ll; } try { const result = await axios2.get(this.basePath + "checkins/recent", { params: this.config, paramsSerializer: (params) => { return querystring2.stringify(params); } }); return result.data.response.recent; } catch (error2) { console.log(`error occured while getting recent`); this.error(error2); return; } } async function likeCheckin(checkin_id) { try { const result = await axios2.post(this.basePath + "checkins/" + checkin_id + "/like", querystring2.stringify(this.config)); return result; } catch (error2) { this.error(error2.response.data); return; } } // src/api/venues.ts import axios3 from "axios"; import querystring3 from "querystring"; async function getVenue(venue_id) { try { const result = await axios3.get(`${this.basePath}venues/${venue_id}/`, { "params": this.config }); return result.data.response.venue; } catch (error2) { console.log(`error occured while getting venue`); throw new Error("Error getting venue data, maybe an authentication error ?"); return; } } async function getTrending(limit = 50, ll, near, radius = 1e5) { this.config.limit = limit; this.config.radius = radius; if (typeof ll !== "undefined") { this.config.ll = ll; } else { this.config.near = near; } try { const result = await axios3.get(this.basePath + "venues/trending", { params: this.config, paramsSerializer: (params) => { return querystring3.stringify(params); } }); return result.data.response.venues; } catch (error2) { console.log(`error occured while getting trending venues`); this.error(error2); return; } } // src/api/authentication.ts import axios4 from "axios"; import querystring4 from "querystring"; async function login(username, password, client_id, client_secret) { const params = { client_id, client_secret, username, password, grant_type: "password" }; try { const response = await axios4.post(this.basePath + "/oauth2/access_token", null, { params }); this.config.access_token = response.data.access_token; return response.data.access_token; } catch (error2) { console.log(`error occured while logging in`); this.error(error2); return; } } async function initiatemultifactorlogin(username, password, client_id, client_secret) { const params = { ...this.config, client_id, client_secret, username, password }; console.log(password); try { const response = await axios4.post(this.basePath + "private/initiatemultifactorlogin", querystring4.stringify(params)); this.flowId = response.data.flowId; return response.data; } catch (error2) { console.log(`error occured while initiating multifactor login`); this.error(error2); return error2; } } async function completemultifactorlogin(code, client_id, client_secret) { const params = { ...this.config, client_id, client_secret, code, flowId: this.flowId }; try { const response = await axios4.post(this.basePath + "private/completemultifactorlogin", querystring4.stringify(params)); this.config.oauth_token = response.data.oauth_token; return response.data.access_token; } catch (error2) { console.log(`error occured while completing multifactor login`); this.error(error2); return; } } // src/api/private.ts import axios5 from "axios"; import querystring5 from "querystring"; async function private_log() { const FormData = __require("form-data"); const formData = new FormData(); formData.append("altAcc", this.config.altAcc); formData.append("llAcc", this.config.llAcc); formData.append("floorLevel", this.config.floorLevel); formData.append("alt", this.config.alt); formData.append("csid", "1243"); formData.append("v", this.config.v); formData.append("oauth_token", this.config.oauth_token); formData.append("m", this.config.m); formData.append("ll", this.config.ll); formData.append("background", "true"); const script = [{ "name": "ios-metrics", "csid": 1243, "ctc": 4, "metrics": [{ "rid": "642a1e4371f95f2eb16b8eda", "n": "SwarmTimelineFeedViewController", "im": "3-3", "vc": 1 }], "event": "background", "cts": 1680481860378182e-6 }]; const stringified = JSON.stringify(script); formData.append("loglines", stringified, { filename: "loglines", contentType: "application/json" }); try { const result = await axios5.post(this.basePath + "private/log", formData, { headers: { ...formData.getHeaders() } }); return result; } catch (error2) { console.log(`error occured while private logging`); this.error(error2); return; } } async function register_device() { const params = { limitAdsTracking: "1", carrier: "stc", hasWatch: "1", csid: "1242", alt: "11.791945", llAcc: "14.825392", otherDeviceIds: "6054750ee01fbc1e3492a745,61187d1fceb2110097a0fc02", ll: "21.530136,39.172863", altAcc: "17.547791", locationAuthorizationStatus: "authorizedwheninuse", token: "ec0718c5d042b63587c14d461bb077d1262811456c4799558e1df2616f02cc9a", oauth_token: "DW233H4JWJZ0E14QU01LFWUZL4RDQPLAF10BAJEI2FTWNOKH", iosSettings: "0", m: "swarm", floorLevel: "2146959360", measurementSystem: "metric", uniqueDevice: "6054750ee01fbc1e3492a745", v: "20221101", backgroundRefreshStatus: "available" }; try { const result = await axios5.post(this.basePath + "/private/registerdevice ", querystring5.stringify(params)); const registeration = result.data.response?.checkin; return registeration; } catch (error2) { console.log(`error occured while registering device`); this.error(error2); return; } } // src/index.ts var SwarmappApi = class { config; basePath; headers; user; flowId; initialize; getFriends; getFollowings; getFollowers; getUser; addFriendByID; getLastSeen; getGeos; getUserProfile; checkIn; getRecent; getCheckins; likeCheckin; completemultifactorlogin; initiatemultifactorlogin; getTrending; getVenue; log; error; getLL; login; register_device; private_log; constructor(oauth_token) { this.config = { m: "swarm", v: "20221101", // A random coordinate to use between calls imitating regular behavior ll: createLatLngString("26.30" + between(34e10, 499999999999), "50.1" + between(287e10, 3119999999999)), //latitude/longitude altAcc: "30.000000", llAcc: "14.825392", floorLevel: "2146959360", alt: "12.275661" }; this.basePath = "https://api.foursquare.com/v2/"; this.headers = { "User-Agent": "com.foursquare.robin.ios.phone:20230316.2230.52:20221101:iOS 16.1.1:iPhone13,4" }; if (oauth_token) { this.config.oauth_token = oauth_token; } this.initialize = initialize.bind(this); this.getFriends = getFriends.bind(this); this.getFollowings = getFollowings.bind(this); this.getFollowers = getFollowers.bind(this); this.getUser = getUser.bind(this); this.error = error.bind(this); this.log = log.bind(this); this.getLL = getLL.bind(this); this.checkIn = checkIn.bind(this); this.getRecent = getRecent.bind(this); this.getCheckins = getCheckins.bind(this); this.addFriendByID = addFriendByID.bind(this); this.completemultifactorlogin = completemultifactorlogin.bind(this); this.initiatemultifactorlogin = initiatemultifactorlogin.bind(this); this.getTrending = getTrending.bind(this); this.getVenue = getVenue.bind(this); this.getLastSeen = getLastSeen.bind(this); this.getGeos = getGeos.bind(this); this.getUserProfile = getUserProfile.bind(this); this.login = login.bind(this); this.register_device = register_device.bind(this); this.private_log = private_log.bind(this); this.likeCheckin = likeCheckin.bind(this); } // TODO: move to client async addHereNow(checkin, females_only = true) { const hereNow = checkin?.venue?.hereNow; const friendships = []; if (hereNow?.count > 0) { console.log(`Found ${hereNow.count} friends from ${checkin.venue.name}...`); for (const group of hereNow.groups) { console.log(`${group.count} friends in ${group.name} group...`); if (group.count > 0) { const filteredItems = females_only ? group.items.filter((item) => item.user?.gender === "female") : group.items; const friendNames = filteredItems.map((friend) => `${friend.user.firstName} (${friend.user.handle}) # ${friend.user.id}`); console.log(`Adding ${filteredItems.length} friends from ${group.name}...`); console.log(friendNames.join(", ")); const newFriendships = await Promise.all( filteredItems.map(async (item) => { return await this.addFriendByID(item.user.id); }) ); friendships.push(...newFriendships); console.log(`Added ${newFriendships.length} friends from ${group.name}...`); console.log(friendNames); } } } return { "hereNow": hereNow, "friendships": friendships }; } // auto add trending function // TODO: maybe move it to the client, not the library async autoAddTrending(location_name, limit_trending) { try { const trending = await this.getTrending(limit_trending, void 0, location_name); const resultPromises = trending.map(async (venue) => { if (venue.hereNow.count > 0) { const checkin = await this.checkIn(venue.id, true); return this.addHereNow(checkin); } return null; }); const result = await Promise.all(resultPromises); return result.filter((item) => item !== null); } catch (error2) { console.log("An error occurred while auto adding trending:"); this.error("An error occurred:", error2); return []; } } // TODO: move to client async likeUnliked(limit = 40) { try { const succeeded = []; const failed = []; const recent = await this.getRecent(limit); const likePromises = recent.map(async (checkin) => { if (!checkin.like) { try { const liked_result = await this.likeCheckin(checkin.id); succeeded.push(liked_result); } catch (likeError) { failed.push(checkin.id); } } else { failed.push(checkin.id); } }); await Promise.all(likePromises); return { succeeded, failed }; } catch (error2) { console.error("An error occurred:", error2); return { succeeded: [], failed: [] }; } } }; export { SwarmappApi as default };