{"action":"created","comment":{"url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls/comments/28179104","id":28179104,"diff_hunk":"@@ -0,0 +1,123 @@\n+---\n+layout: post\n+category :\n+tagline: \"\"\n+tags : [iCal, calendar, ics, Ember, Rails]\n+title: \"iCal subscriptions with Ember and Rails Part 1\"\n+description: \"How to subscribe to your application's events by setting up an .ics endpoint\"\n+author: faizaan_shamsi\n+---\n+{% include JB/setup %}\n+\n+#### Introduction\n+\n+You've built a feature that creates events/schedules/todos. Your users are clamoring to have those events added to their Calendar application. Let's look at how we can do that in the context of a Rails app.\n+\n+#### The iCalendar format\n+\n+We are going to want to create an endpoint in our app that responds with the `.ics` format: [iCalendar](http://en.wikipedia.org/wiki/ICalendar). Most calendar apps such as Apple Calendar and Google Calendar can import an `.ics` file or subscribe to an `.ics` URL. The important thing to note is that we will be returning a VCALENDAR with multiple objects (most likely `VEVENT` or `VTODO`) inside it. You'll have to choose the object that is correct for your use case by looking at the required and optional attributes that best match. We'll be using `VEVENT`.\n+\n+#### Builing iCalendar objects in Ruby\n+\n+Let us assume we have a `Meeting` class in Rails as follows:\n+\n+{% highlight ruby %}\n+\n+class Meeting < ActiveRecord::Base\n+  validates :start_time,  presence: true\n+  validates :duration,    presence: true\n+  validates :description, presence: true\n+  validates :location,    presence: true\n+end\n+\n+{% endhighlight %}\n+\n+We have meeting objects that we would like to turn into `VEVENT` objects. We're going to use the [icalendar](https://github.com/icalendar/icalendar) gem to help us. The important thing to note is that based on the type of object (`VEVENT`, `VTODO`, etc.) there are different required and optional parameters. We can view these by inspecting the source for the [`Icalendar::Event`](https://github.com/icalendar/icalendar/blob/master/lib/icalendar/event.rb) we will be creating. The main things to note:","path":"_posts/2015-04-10-iCal-subscriptions-with-ember-and-rails.md","position":35,"original_position":35,"commit_id":"96dfc3f161c636a98818a37b6945815b3c7872e5","original_commit_id":"96dfc3f161c636a98818a37b6945815b3c7872e5","user":{"login":"HeroicEric","id":602204,"avatar_url":"https://avatars.githubusercontent.com/u/602204?v=3","gravatar_id":"","url":"https://api.github.com/users/HeroicEric","html_url":"https://github.com/HeroicEric","followers_url":"https://api.github.com/users/HeroicEric/followers","following_url":"https://api.github.com/users/HeroicEric/following{/other_user}","gists_url":"https://api.github.com/users/HeroicEric/gists{/gist_id}","starred_url":"https://api.github.com/users/HeroicEric/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HeroicEric/subscriptions","organizations_url":"https://api.github.com/users/HeroicEric/orgs","repos_url":"https://api.github.com/users/HeroicEric/repos","events_url":"https://api.github.com/users/HeroicEric/events{/privacy}","received_events_url":"https://api.github.com/users/HeroicEric/received_events","type":"User","site_admin":false},"body":"80 char lines","created_at":"2015-04-10T20:47:26Z","updated_at":"2015-04-10T20:47:26Z","html_url":"https://github.com/greenfieldhq/greenfieldhq.github.io/pull/8#discussion_r28179104","pull_request_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls/8","_links":{"self":{"href":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls/comments/28179104"},"html":{"href":"https://github.com/greenfieldhq/greenfieldhq.github.io/pull/8#discussion_r28179104"},"pull_request":{"href":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls/8"}}},"pull_request":{"url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls/8","id":33074132,"html_url":"https://github.com/greenfieldhq/greenfieldhq.github.io/pull/8","diff_url":"https://github.com/greenfieldhq/greenfieldhq.github.io/pull/8.diff","patch_url":"https://github.com/greenfieldhq/greenfieldhq.github.io/pull/8.patch","issue_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/issues/8","number":8,"state":"open","locked":false,"title":"WIP FS ical integration","user":{"login":"faizaanshamsi","id":3848451,"avatar_url":"https://avatars.githubusercontent.com/u/3848451?v=3","gravatar_id":"","url":"https://api.github.com/users/faizaanshamsi","html_url":"https://github.com/faizaanshamsi","followers_url":"https://api.github.com/users/faizaanshamsi/followers","following_url":"https://api.github.com/users/faizaanshamsi/following{/other_user}","gists_url":"https://api.github.com/users/faizaanshamsi/gists{/gist_id}","starred_url":"https://api.github.com/users/faizaanshamsi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/faizaanshamsi/subscriptions","organizations_url":"https://api.github.com/users/faizaanshamsi/orgs","repos_url":"https://api.github.com/users/faizaanshamsi/repos","events_url":"https://api.github.com/users/faizaanshamsi/events{/privacy}","received_events_url":"https://api.github.com/users/faizaanshamsi/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-04-10T19:02:53Z","updated_at":"2015-04-10T20:47:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2fc8138ad3f19f99ef34d1e826dcdd0bec876a47","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls/8/commits","review_comments_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls/8/comments","review_comment_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls/comments{/number}","comments_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/issues/8/comments","statuses_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/statuses/96dfc3f161c636a98818a37b6945815b3c7872e5","head":{"label":"greenfieldhq:fs-ical-integration","ref":"fs-ical-integration","sha":"96dfc3f161c636a98818a37b6945815b3c7872e5","user":{"login":"greenfieldhq","id":7207275,"avatar_url":"https://avatars.githubusercontent.com/u/7207275?v=3","gravatar_id":"","url":"https://api.github.com/users/greenfieldhq","html_url":"https://github.com/greenfieldhq","followers_url":"https://api.github.com/users/greenfieldhq/followers","following_url":"https://api.github.com/users/greenfieldhq/following{/other_user}","gists_url":"https://api.github.com/users/greenfieldhq/gists{/gist_id}","starred_url":"https://api.github.com/users/greenfieldhq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/greenfieldhq/subscriptions","organizations_url":"https://api.github.com/users/greenfieldhq/orgs","repos_url":"https://api.github.com/users/greenfieldhq/repos","events_url":"https://api.github.com/users/greenfieldhq/events{/privacy}","received_events_url":"https://api.github.com/users/greenfieldhq/received_events","type":"Organization","site_admin":false},"repo":{"id":18532488,"name":"greenfieldhq.github.io","full_name":"greenfieldhq/greenfieldhq.github.io","owner":{"login":"greenfieldhq","id":7207275,"avatar_url":"https://avatars.githubusercontent.com/u/7207275?v=3","gravatar_id":"","url":"https://api.github.com/users/greenfieldhq","html_url":"https://github.com/greenfieldhq","followers_url":"https://api.github.com/users/greenfieldhq/followers","following_url":"https://api.github.com/users/greenfieldhq/following{/other_user}","gists_url":"https://api.github.com/users/greenfieldhq/gists{/gist_id}","starred_url":"https://api.github.com/users/greenfieldhq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/greenfieldhq/subscriptions","organizations_url":"https://api.github.com/users/greenfieldhq/orgs","repos_url":"https://api.github.com/users/greenfieldhq/repos","events_url":"https://api.github.com/users/greenfieldhq/events{/privacy}","received_events_url":"https://api.github.com/users/greenfieldhq/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/greenfieldhq/greenfieldhq.github.io","description":"","fork":false,"url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io","forks_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/forks","keys_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/teams","hooks_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/hooks","issue_events_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/issues/events{/number}","events_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/events","assignees_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/assignees{/user}","branches_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/branches{/branch}","tags_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/tags","blobs_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/statuses/{sha}","languages_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/languages","stargazers_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/stargazers","contributors_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/contributors","subscribers_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/subscribers","subscription_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/subscription","commits_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/contents/{+path}","compare_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/merges","archive_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/downloads","issues_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/issues{/number}","pulls_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls{/number}","milestones_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/milestones{/number}","notifications_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/labels{/name}","releases_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/releases{/id}","created_at":"2014-04-07T20:10:35Z","updated_at":"2015-03-25T19:55:29Z","pushed_at":"2015-04-10T20:37:12Z","git_url":"git://github.com/greenfieldhq/greenfieldhq.github.io.git","ssh_url":"git@github.com:greenfieldhq/greenfieldhq.github.io.git","clone_url":"https://github.com/greenfieldhq/greenfieldhq.github.io.git","svn_url":"https://github.com/greenfieldhq/greenfieldhq.github.io","homepage":null,"size":1584,"stargazers_count":0,"watchers_count":0,"language":"CSS","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"greenfieldhq:master","ref":"master","sha":"85d4ad177c88f6d68f43c2b218e9185e4f0ee684","user":{"login":"greenfieldhq","id":7207275,"avatar_url":"https://avatars.githubusercontent.com/u/7207275?v=3","gravatar_id":"","url":"https://api.github.com/users/greenfieldhq","html_url":"https://github.com/greenfieldhq","followers_url":"https://api.github.com/users/greenfieldhq/followers","following_url":"https://api.github.com/users/greenfieldhq/following{/other_user}","gists_url":"https://api.github.com/users/greenfieldhq/gists{/gist_id}","starred_url":"https://api.github.com/users/greenfieldhq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/greenfieldhq/subscriptions","organizations_url":"https://api.github.com/users/greenfieldhq/orgs","repos_url":"https://api.github.com/users/greenfieldhq/repos","events_url":"https://api.github.com/users/greenfieldhq/events{/privacy}","received_events_url":"https://api.github.com/users/greenfieldhq/received_events","type":"Organization","site_admin":false},"repo":{"id":18532488,"name":"greenfieldhq.github.io","full_name":"greenfieldhq/greenfieldhq.github.io","owner":{"login":"greenfieldhq","id":7207275,"avatar_url":"https://avatars.githubusercontent.com/u/7207275?v=3","gravatar_id":"","url":"https://api.github.com/users/greenfieldhq","html_url":"https://github.com/greenfieldhq","followers_url":"https://api.github.com/users/greenfieldhq/followers","following_url":"https://api.github.com/users/greenfieldhq/following{/other_user}","gists_url":"https://api.github.com/users/greenfieldhq/gists{/gist_id}","starred_url":"https://api.github.com/users/greenfieldhq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/greenfieldhq/subscriptions","organizations_url":"https://api.github.com/users/greenfieldhq/orgs","repos_url":"https://api.github.com/users/greenfieldhq/repos","events_url":"https://api.github.com/users/greenfieldhq/events{/privacy}","received_events_url":"https://api.github.com/users/greenfieldhq/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/greenfieldhq/greenfieldhq.github.io","description":"","fork":false,"url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io","forks_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/forks","keys_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/teams","hooks_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/hooks","issue_events_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/issues/events{/number}","events_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/events","assignees_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/assignees{/user}","branches_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/branches{/branch}","tags_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/tags","blobs_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/statuses/{sha}","languages_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/languages","stargazers_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/stargazers","contributors_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/contributors","subscribers_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/subscribers","subscription_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/subscription","commits_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/contents/{+path}","compare_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/merges","archive_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/downloads","issues_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/issues{/number}","pulls_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls{/number}","milestones_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/milestones{/number}","notifications_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/labels{/name}","releases_url":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/releases{/id}","created_at":"2014-04-07T20:10:35Z","updated_at":"2015-03-25T19:55:29Z","pushed_at":"2015-04-10T20:37:12Z","git_url":"git://github.com/greenfieldhq/greenfieldhq.github.io.git","ssh_url":"git@github.com:greenfieldhq/greenfieldhq.github.io.git","clone_url":"https://github.com/greenfieldhq/greenfieldhq.github.io.git","svn_url":"https://github.com/greenfieldhq/greenfieldhq.github.io","homepage":null,"size":1584,"stargazers_count":0,"watchers_count":0,"language":"CSS","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls/8"},"html":{"href":"https://github.com/greenfieldhq/greenfieldhq.github.io/pull/8"},"issue":{"href":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/issues/8"},"comments":{"href":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/issues/8/comments"},"review_comments":{"href":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls/8/comments"},"review_comment":{"href":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/pulls/8/commits"},"statuses":{"href":"https://api.github.com/repos/greenfieldhq/greenfieldhq.github.io/statuses/96dfc3f161c636a98818a37b6945815b3c7872e5"}}}}