Jak vyexportovat události z Facebooku do Google Calendar, aby vše fungovalo dobře?

Otevřete si Facebook a klikněte na „Události“. Adresa s exportem událostí ve formátu iCalendar je trošku nečekaně ukrytá pod ikonkou lupy:

Adresu si zkopírujte do schránky:

Odkaz bychom mohli hned dát to Google kalendáře, ale narazili bychom na několik nedostatků. Google nedokáže korektně zobrazit neveřejnou událost, místo ní uvidíte pouze nicneříkající slovo „nedostupný“:

Google nedokáže ani filtrovat události podle toho, zda jsme potvrdili účast. Takže kalendář se nám plní nejen událostmi, na které jsme účast potvrdili, ale i těmi, na které nás někdo zatím jen pozval. Navíc u událostí v letním čase uvádí o hodinu více.

Vše lze vyřešit jednoduchým filtrem facebookfilter.php, který si umístěte na server:

// load events from Facebook
$s = file_get_contents("http://www.facebook.com/ical/u.php?$_SERVER[QUERY_STRING]");

// PREG requires \n line breaks
$s = str_replace("\r\n", "\n", $s);


// fix private events bug in Google Calendar
$s = str_replace('CLASS:PRIVATE', 'CLASS:PUBLIC', $s);


// remove unconfirmed events
function filterEvents($m) {
	return strpos($m[0], 'PARTSTAT:NEEDS-ACTION') ? '' : $m[0];
}
$s = preg_replace_callback('#^BEGIN:VEVENT\n(.*?)^END:VEVENT\n#sm', 'filterEvents', $s);


// fix daylight savings bug in Google Calendar
function fixTime($m) {
	$zone = new DateTimeZone('Europe/Prague');
	$time = new DateTime($m[2], new DateTimeZone('UTC'));
	$fix = $zone->getOffset($time) - $zone->getOffset(new DateTime('20000101', $zone));
	$time->modify("-$fix seconds");
	return $m[1] . $time->format('Ymd\THis\Z');
}
$s = preg_replace_callback('#^(DTSTART:|DTEND:)(.+)#m', 'fixTime', $s);


// revert line breaks back
$s = str_replace("\n", "\r\n", $s);

header('Content-Type: text/calendar; charset=utf-8');
echo $s;

Do Google kalendáře přidáme adresu našeho filtru se stejnými parametry v URL, jako měl původní skript od Facebooku:

A je to!