Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Export ical format for Facebook page's events by cognitom. Modifications: pageId as parameter, restriction to public events, improved timezone adjustment, ignore exceptions
original code by cogitom:
This script reads future events (plus several days into the past) from Facebook pages
and creates a subscribable iCalendar
Improvements upon the original version:
- fixed start and endtime reading
- timezone adjustment done on facebook's side (more reliable)
- restrict to public events
- more detailed location (include venue or link to facebook page, depending on what is available)
- ignore exeptions (e.g. no events)
require_once 'path/to/facebook.php';
require_once 'path/to/iCalcreator.class.php';
$config = array(
'appId' => 'xxxx',//change to your fb app id
'secret' => 'yyyy',//change to your fb app secret
'pageId' => $_GET['fbpage'],//get the pageid from passed parameter 'fbpage'
'timezone' => 'Europe/Berlin',
'timezoneDif' => 9*60*60,
$facebook = new Facebook(array('appId'=>$config['appId'], 'secret'=>$config['secret']));
$page = $facebook->api('/'.$config['pageId']);
$v = new vcalendar(array('unique_id'=>$config['pageId']));
$v->setProperty('method', 'PUBLISH' );
$v->setProperty('x-wr-calname', $page['name']);
$v->setProperty('X-WR-CALDESC', $page['name']);
$v->setProperty('X-WR-TIMEZONE', $config['timezone']);
try {
$cons = $facebook->api('/'.$config['pageId'].'/events');
$event_ids = array();
//the times given here - unlike the ones retrieved from an event object - are already adjusted to your local time.
$start_times = array();
$end_times = array();
foreach ($cons['data'] as $con) {
$event_ids[] = $con['id'];
$start_times += array($con['id'] => preg_replace('/[-T:]/', '', $con['start_time']));
$end_times += array($con['id'] => preg_replace('/[-T:]/', '', $con['end_time']));
$events = $facebook->api('?date_format=U&ids='.implode(',', $event_ids));
foreach ($events as $event){
//only add public events
if ($event['privacy'] == "OPEN"){
$etz = $config['timezone'];
$e = & $v->newComponent('vevent');
$e->setProperty('dtstart', $start_times[$event['id']]);
$e->setProperty('dtend', $end_times[$event['id']]);
$location = $event['location'];
// include street address or link to facebook page in location
if ($event['venue']){
$venues = $event['venue'];
if (!$venues['id']){
foreach ($venues as $vn) {
$venue = $venue.", ".$vn;
} else {
$getid = $facebook->api('/'.$venues['id']);
$venue = " (".$getid['link'].")";
$location = $location." @ ".$venue;
$e->setProperty('location', $location);
$e->setProperty('summary', $event['name']);
$e->setProperty('description', $event['description']);
$e->setProperty('url', ''.$event['id']);
} catch (Exception $e) {
//ignore Exeptions (e.g. if there are no events)

This comment has been minimized.

Copy link

akostadinov commented Nov 17, 2014

Google said: We could not parse the calendar at the url requested.
Any ideas?

update: I think I figured, I enclosed $e->setProperty('dtend', $end_times[$event['id']]); into an if condition to avoid setting a blank DTEND if no end time is specified in event. I can't immediately check in google but joomla's jevent module at lest seems to chew it better now. I see it working now in google and joomla jevents. See my fork -

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.