10

Microsoft Outlook and other calendar clients have the ability to subscribe to "Internet Calendars".

In the case of Outlook, it accepts a URL (either http: or webcal:). Once configured correctly, the "Internet Calendar" appears in Outlook client stays up-to-date.

I would like to know how to publish an "Internet Calendar" on my own. I am using Java. I am already creating ".ics files" events using the iCal4j library. I vaguely assume that I need to create a servlet that sends a stream of ics events.

Any example or reference documentation to get me started would be appreciated.

Community
  • 1
  • 1
Frederic Fortier
  • 750
  • 8
  • 21
  • 1
    What is "ICS events"/"ics events"? Please define and/or link acronyms such as this. Do you mean ".ics" files as mentioned in [rfc 2445](http://tools.ietf.org/html/rfc2445)? – Basil Bourque Dec 17 '15 at 18:56
  • Hi Frederic, I'm also looking for pointer to solve this problem. I could implement Zapier to do that for me but I'd rather build my own servlet to handle the feed. Do you have a solution yet? Best regards, Thomas – Thomas Dittmar Nov 23 '16 at 02:40
  • I was not able to do it. I did not research it much further. I ended up sending those calendar invites via SMTP which turned to be sufficient. – Frederic Fortier Dec 01 '16 at 10:57
  • What exactly is your problem? With iCal4j you should be able to create calendar files containing multiple events which you can just save to a file or stream via HTTP from your server application. You can even write it to a static resource file _myCalendar.ics_ directly on your web server. If anything in the calendar changes, just overwrite that file. Any user can add its URL to his calendar application. As long as you do not wish to enable users to have write access to the calendar there should not be any problem with this approach. If this helps, please let me know and I will write an answer. – kriegaex Jul 22 '19 at 03:23
  • I have a servlet that allows download of mycalendar.ics but when I put this http url into Outlook's internet calendar subscription then it fails to import the file without throwing any error. However, when I "Open" the ics file directly from Open Calendar option then it shows up. I am not sure what exactly is the problem here. – mod Jul 22 '19 at 06:20

1 Answers1

1

I don't know how your implementation looks like, but when I tried some dummy implementation with Spring Boot I was able to make this work. Here is the implementation I used:

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;

@Slf4j
@Controller
public class CalendarController {

  @GetMapping("/calendar.ics")
  @ResponseBody
  public byte[] getCalendars() throws IOException {
    ClassPathResource classPathResource = new ClassPathResource("Test.ics");
    InputStream inputStream = classPathResource.getInputStream();
    byte[] bytes = inputStream.readAllBytes();
    inputStream.close();
    return bytes;
  }

  @GetMapping("/downloadCalendar.ics")
  public ResponseEntity<Resource> downloadFile(HttpServletRequest request) {
    Resource resource = new ClassPathResource("Test.ics");
    String contentType = null;
    try {
      contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
    } catch (IOException ex) {
      log.info("Could not determine file type.");
    }

    if(contentType == null) {
      contentType = "application/octet-stream";
    }

    return ResponseEntity.ok()
        .contentType(MediaType.parseMediaType(contentType))
        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
        .body(resource);
  }
}

Both of the methods work fine in Outlook 2016 and above if I try to add either http://localhost:8080/calendar.ics or http://localhost:8080/downloadCalendar.ics. The Test.ics I am returning is just an exported appointment from my calendar in ics format. Also as a side note here are the headers that get sent with the request from Outlook:

headers = [
    accept: "*/*", 
    user-agent: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; Tablet PC 2.0; Microsoft Outlook 16.0.4861; ms-office; MSOffice 16)", 
    accept-encoding: "gzip, deflate", 
    host: "localhost:8080", 
    connection: "Keep-Alive"
]

I would also imagine that there might be some issues with authentication if https is used and outlook might send different headers in that case. There is some issue report in Microsoft support center here: https://support.microsoft.com/en-us/help/4025591/you-can-t-add-an-internet-calendar-in-outlook, but with a broken link to the "new modern authentication" page :). Hope this helps.

vl4d1m1r4
  • 1,688
  • 12
  • 21