Our Production Director had asked if Rock was capable of having individual, room-specific calendar subscriptions for each of our large-format rooms so he could keep an eye on events in those rooms from his native calendar application. Rock can't natively do this, but with a little elbow grease, here's how you can accomplish this. 

We are using this to accomplish room-specific calendars, but you could easily modify this to pull an "all events" type calendar as well.

NOTE: there is a bug (#4635) that prevents occurrence exceptions from being exported properly. Since the code I used to accomplish this is using a lot of the built-in C# functions, I'm not expecting that bug fix to break this. If it does, however, I'll update the recipe.


  1. Create a location attribute to indicate a "large-format room"
  2. Import & update workflows to generate the calendars
  3. Attach the workflow as a trigger on a Reservation Location 
  4. Create a block for the iCal links to live on

Create a location attribute to indicate a "large-format room"

  1. Go to Admin Tools > System Settings and then click "Entity Attributes"
  2. In the top-right hand corner of the block, select the entity type Location
  3. Create a new entity attribute
    • Field type: Boolean
    • Name: Large-Format Room
    • Key: LargeFormatRoom
    • Default Value: No
    • Control Type: Checkbox
  4. Take note of the attribute Id when are you finished, as we'll need that to update the workflow


      1. Go to Admin Tools > Check-In and click Named Locations
      2. For each of your large-format rooms, edit and check the box on the new attribute just created


      Import & update workflows to generate the calendars

      There are two workflows used to accomplish this. There's a helper workflow that creates a single calendar when passed a Location Id, then there's the primary workflow that is triggered each time a reservation is changed that calls the helper workflow. 

      1. Import the two different workflows that are in the attached .zip file
        • Process Large-Format Rooms for Calendar Creation_202104071138.json
        • HELPER - Create Calendar (.ics) from Location Id_202104071141.json
      2. Note the WorkflowTypeId of the HELPER - Create Calendar (.ics) from Location Id workflow
      3. Open and Edit the Process Large-Format Rooms for Calendar Creation workflow
      4. Expand the only action and change two things:
        • The Id in the WHERE av.AttributeId = ##### line. This will be the Attribute Id from step 4 of the first section.
        • The Workflow Type Id in the entity command. This will be the WorkflowTypeId noted in step 2 of the current section.Screen_Shot_2021-04-07_at_2.13.13_PM.png
      5. Save that workflow, then open and edit the HELPER - Create Calendar (.ics) from Location Id workflow
      6. You'll need to update two things here:
        • Change the FolderPath attribute to where you would like the calendar .ics files to be stored. I highly recommend using a file path that is already exposed to public access, i.e. C:/inetpub/wwwroot/Content/ExternalSite/. Ours is C:/inetpub/wwwroot/Content/ExternalSite/Calendars/, but whatever path you choose, it has to pre-exist AND include the trailing forward slash in the attribute. I went into our Windows server and created the Calendars folder (which you could also do via File Manager in CMS configuration). 
        • In the Generate Calendar action, you'll need to edit the C# just a bit since I am including reservation attributes that are unique to our system. Screen_Shot_2021-04-07_at_2.30.36_PM.png
      7. Save the workflow.

      Attach the workflow as a trigger on a Reservation Location

      1. Go to Admin Tools > General Settings, then click on Workflow Triggers
      2. Create a new Workflow Trigger
        • Trigger Type: Post-Save
        • Entity Type: Reservation Location
        • Workflow Type: Process Large-Format Rooms for Calendar CreationScreen_Shot_2021-04-07_at_2.37.21_PM.png
      3. Save the Trigger

      Create a block for the iCal links to live on

      We created a page under Room Management called iCal Subscriptions that shows as a header tab within Room Management for easy access. Ultimately, the page is just an HTML block. I've included the contents of the HTML block in the attached .zip file, but for the purpose of this tutorial, I'm going to focus on the HTML block. You can decide where you want it to live. :)

      1. Create a new HTML block
      2. Under the Block Properties (gear icon), ensure that the following Enabled Lava Commands are checked:
        • Execute
        • RockEntity
      3. Edit the HTML of the block and copy/paste the content from the attached htmlBlockContents.liquid file
      4. Change the file paths in the contentScreen_Shot_2021-04-07_at_2.48.16_PM.png

      Here's what that block's resulting content looks like:


      Bonus Content

      The buttons that are resulting from the HTML block use some Javascript, with the help of clipboard.js, to enable a "click to copy" functionality. Here's what you can do to set that up in two easy steps.

      1. Add the clipboard.js script to the Header Content under the Advanced Settings of the Page Properties
      <script src="https://cdn.rawgit.com/zenorocha/clipboard.js/v2.0.8/dist/clipboard.min.js"></script>


      1. Edit the Block Properties of the HTML Block, and add the contents from the postHTMLBlockContent.html file to the Post-HTML under the Advanced Settings of the block


      And there you have it! Any time a ReservationLocation gets saved, the workflow will trigger and update the calendar files. You can then copy the URLs from the results of the HTML block in section 4 and subscribe to those URLs in Apple's Calendar or Google Calendar (and likely other calendar applications :) ).