facebook-event-scraper
Version:
A slim module for scraping Facebook event data in milliseconds.
163 lines (162 loc) • 8.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCategories = exports.getEndTimestampAndTimezone = exports.getOnlineDetails = exports.getHosts = exports.getLocation = exports.getUserStats = exports.getTicketUrl = exports.getBasicData = exports.getDescription = void 0;
const json_1 = require("./json");
const getDescription = (html) => {
const { jsonData } = (0, json_1.findJsonInString)(html, 'event_description');
if (!jsonData) {
throw new Error('No event description found, please verify that your event URL is correct');
}
return jsonData.text;
};
exports.getDescription = getDescription;
const getBasicData = (html) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
const { jsonData } = (0, json_1.findJsonInString)(html, 'event', (candidate) => candidate.day_time_sentence);
if (!jsonData) {
throw new Error('No event data found, please verify that your URL is correct and the event is accessible without authentication');
}
return {
id: jsonData.id,
name: jsonData.name,
photo: ((_a = jsonData.cover_media_renderer) === null || _a === void 0 ? void 0 : _a.cover_photo)
? {
url: jsonData.cover_media_renderer.cover_photo.photo.url,
id: jsonData.cover_media_renderer.cover_photo.photo.id,
imageUri: (_c = (_b = jsonData.cover_media_renderer.cover_photo.photo.image) === null || _b === void 0 ? void 0 : _b.uri) !== null && _c !== void 0 ? _c : (_d = jsonData.cover_media_renderer.cover_photo.photo.full_image) === null || _d === void 0 ? void 0 : _d.uri
}
: null,
photos: ((_e = jsonData.cover_media_renderer) === null || _e === void 0 ? void 0 : _e.cover_media)
? jsonData.cover_media_renderer.cover_media.map((photo) => {
var _a, _b, _c;
return ({
url: photo.url,
id: photo.id,
imageUri: (_b = (_a = photo.image) === null || _a === void 0 ? void 0 : _a.uri) !== null && _b !== void 0 ? _b : (_c = photo.full_image) === null || _c === void 0 ? void 0 : _c.uri
});
})
: [],
video: ((_f = jsonData.cover_media_renderer) === null || _f === void 0 ? void 0 : _f.cover_video)
? {
url: jsonData.cover_media_renderer.cover_video.url,
id: jsonData.cover_media_renderer.cover_video.id,
thumbnailUri: (_g = jsonData.cover_media_renderer.cover_video.image) === null || _g === void 0 ? void 0 : _g.uri
}
: null,
formattedDate: jsonData.day_time_sentence,
startTimestamp: jsonData.start_timestamp,
isOnline: jsonData.is_online,
isCanceled: jsonData.is_canceled,
url: jsonData.url,
// Sibling events, for multi-date events
siblingEvents: (_j = (_h = jsonData.comet_neighboring_siblings) === null || _h === void 0 ? void 0 : _h.map((sibling) => ({
id: sibling.id,
startTimestamp: sibling.start_timestamp,
endTimestamp: sibling.end_timestamp,
parentEvent: { id: sibling.parent_event.id }
}))) !== null && _j !== void 0 ? _j : [],
// If parent exists, and its not the same as the current event, set the parentEvent field
parentEvent: jsonData.parent_if_exists_or_self &&
jsonData.parent_if_exists_or_self.id !== jsonData.id
? { id: jsonData.parent_if_exists_or_self.id }
: null
};
};
exports.getBasicData = getBasicData;
const getTicketUrl = (html) => {
var _a;
const { jsonData } = (0, json_1.findJsonInString)(html, 'event', (candidate) => candidate.event_buy_ticket_url);
// If the event doesnt have a ticket URL, jsonData will be null
return (_a = jsonData === null || jsonData === void 0 ? void 0 : jsonData.event_buy_ticket_url) !== null && _a !== void 0 ? _a : null;
};
exports.getTicketUrl = getTicketUrl;
const getUserStats = (html) => {
const { jsonData: usersRespondedJsonData } = (0, json_1.findJsonInString)(html, 'event_connected_users_public_responded');
// usersRespondedJsonData can be undefined if the host decides to hide the guest list
return {
usersResponded: usersRespondedJsonData === null || usersRespondedJsonData === void 0 ? void 0 : usersRespondedJsonData.count
};
};
exports.getUserStats = getUserStats;
// Only called for non-online events
const getLocation = (html) => {
var _a, _b, _c, _d, _e, _f, _g, _h;
const { jsonData, startIndex } = (0, json_1.findJsonInString)(html, 'event_place', (candidate) => 'location' in candidate);
// If there is no start index, it means the event_place field wasn't found in the HTML
if (startIndex === -1) {
throw new Error('No location information found, please verify that your event URL is correct');
}
// If jsonData is null, it means we did find the event_place field but it was set to null. This happens for events with no locations set
if (jsonData === null) {
return null;
}
return {
id: jsonData.id,
name: jsonData.name,
description: (_b = (_a = jsonData.best_description) === null || _a === void 0 ? void 0 : _a.text) !== null && _b !== void 0 ? _b : null,
url: (_c = jsonData.url) !== null && _c !== void 0 ? _c : null,
coordinates: jsonData.location
? {
latitude: jsonData.location.latitude,
longitude: jsonData.location.longitude
}
: null,
countryCode: (_f = (_e = (_d = jsonData.location) === null || _d === void 0 ? void 0 : _d.reverse_geocode) === null || _e === void 0 ? void 0 : _e.country_alpha_two) !== null && _f !== void 0 ? _f : null,
type: jsonData.place_type,
address: (_h = (_g = jsonData.address) === null || _g === void 0 ? void 0 : _g.street) !== null && _h !== void 0 ? _h : null,
city: jsonData.city
? {
name: jsonData.city.contextual_name,
id: jsonData.city.id
}
: null
};
};
exports.getLocation = getLocation;
const getHosts = (html) => {
const { jsonData } = (0, json_1.findJsonInString)(html, 'event_hosts_that_can_view_guestlist',
// We check for profile_picture field since there are other event_hosts_that_can_view_guestlist keys which have more limited host data (doesnt include profile_picture).
(candidate) => { var _a; return (_a = candidate === null || candidate === void 0 ? void 0 : candidate[0]) === null || _a === void 0 ? void 0 : _a.profile_picture; });
if (jsonData === null) {
// This happens if the event is hosted by an external provider, eg https://www.facebook.com/events/252144510602906.
// TODO: See if we can get any other data about the host (eg URL). Look at event_host_context_row_info field
return [];
}
return jsonData.map((host) => ({
id: host.id,
name: host.name,
url: host.url,
type: host.__typename,
photo: {
imageUri: host.profile_picture.uri
}
}));
};
exports.getHosts = getHosts;
const getOnlineDetails = (html) => {
const { jsonData } = (0, json_1.findJsonInString)(html, 'online_event_setup', (candidate) => 'third_party_url' in candidate && 'type' in candidate);
if (jsonData === null) {
throw new Error('No online event details found, please verify that your event URL is correct');
}
return { url: jsonData.third_party_url, type: jsonData.type };
};
exports.getOnlineDetails = getOnlineDetails;
const getEndTimestampAndTimezone = (html, expectedStartTimestamp) => {
const { jsonData } = (0, json_1.findJsonInString)(html, 'data', (candidate) => 'end_timestamp' in candidate &&
'tz_display_name' in candidate &&
candidate.start_timestamp === expectedStartTimestamp);
if (jsonData === null) {
throw new Error('No end date & timezone details found, please verify that your event URL is correct');
}
// If event doesnt have an end date, end_timestamp will be set to 0
return {
endTimestamp: jsonData.end_timestamp || null,
timezone: jsonData.tz_display_name
};
};
exports.getEndTimestampAndTimezone = getEndTimestampAndTimezone;
const getCategories = (html) => {
const { jsonData } = (0, json_1.findJsonInString)(html, 'discovery_categories');
return jsonData;
};
exports.getCategories = getCategories;