Documentation
¶
Overview ¶
Package icalendar is an ergonomic wrapper around the iCalendar (RFC 5545) and iMIP/iTIP (RFC 6047 / RFC 5546) formats for Go email clients and schedulers.
It turns the low-level property bag exposed by the underlying parser (github.com/arran4/golang-ical) into a flat, easy-to-render Event struct, and provides the glue most mail clients end up writing by hand:
- Parse an .ics attachment into one Event (ParseICS) or a whole Calendar of them (Parse).
- Build outgoing invites: REQUEST (NewRequest), CANCEL (NewCancel) and REPLY (Event.Reply) calendars, serialized back to RFC-compliant bytes.
- Generate an RFC 6047 RSVP reply from a received invite (GenerateRSVP) — the dance Google Calendar and Outlook require to register attendance.
- Expand recurring events: parse an RRULE (ParseRRule) and enumerate the concrete occurrences in a window (Event.Occurrences).
- Compute availability: merge events into busy intervals and the free gaps between them (FreeBusy, BusyPeriods).
The package name is icalendar and the import path is github.com/floatpane/go-icalendar.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GenerateRSVP ¶
GenerateRSVP turns a received invite (originalData) into an RFC 6047 (iMIP) reply on behalf of userEmail. response must be one of "ACCEPTED", "DECLINED" or "TENTATIVE" (the PartStatAccepted/PartStatDeclined/PartStatTentative values).
It reproduces exactly what Google Calendar and Outlook expect from a reply:
- METHOD:REPLY at the calendar level;
- only the responding attendee left in each VEVENT (all others removed);
- that attendee's PARTSTAT set to response and RSVP=TRUE;
- a fresh DTSTAMP.
Working from the original bytes (rather than a re-serialized Event) keeps the UID, SEQUENCE, recurrence and organizer of the invite byte-for-byte, which is what lets the organizer's calendar match the reply to the original event.
Types ¶
type Attendee ¶
type Attendee struct {
Email string // address, without the "mailto:" scheme
Name string // CN parameter, if any
Role string // ROLE parameter (e.g. REQ-PARTICIPANT)
PartStat PartStat // PARTSTAT parameter
RSVP bool // RSVP parameter
}
Attendee is a single ATTENDEE on a VEVENT.
type Calendar ¶
type Calendar struct {
Method string // METHOD (REQUEST, REPLY, CANCEL, ...)
ProdID string // PRODID
Version string // VERSION (almost always "2.0")
Events []*Event
}
Calendar is a parsed (or constructed) VCALENDAR: a method, some bookkeeping headers, and the events it carries.
func NewCalendar ¶
func NewCalendar() *Calendar
NewCalendar returns an empty PUBLISH calendar ready for Calendar.Add.
func NewCancel ¶
NewCancel builds a METHOD:CANCEL calendar for e, marking it CANCELLED and bumping its SEQUENCE so recipients treat it as a newer update than the original invite (RFC 5546 §3.2.5).
func NewRequest ¶
NewRequest builds a METHOD:REQUEST calendar inviting attendees to e — the message an organizer sends to schedule a meeting. The event's Status defaults to CONFIRMED when unset.
func Parse ¶
Parse reads .ics data and returns every VEVENT it contains, along with the calendar-level method and headers. Unlike ParseICS it does not require any events to be present — an empty calendar yields a Calendar with no Events and a nil error.
type Event ¶
type Event struct {
UID string
Summary string // event title (SUMMARY)
Description string
Location string
Start time.Time
End time.Time
AllDay bool // DTSTART/DTEND were VALUE=DATE (no time component)
Organizer string // organizer email
OrganizerName string // organizer CN, if any
Attendees []Attendee
Status string // CONFIRMED, TENTATIVE, CANCELLED
Method string // REQUEST, REPLY, CANCEL (mirrors the calendar METHOD)
Sequence int // SEQUENCE; bump on every update to an existing UID
URL string
Categories []string
Stamp time.Time // DTSTAMP
Created time.Time // CREATED
Modified time.Time // LAST-MODIFIED
// Recurrence is the parsed RRULE, or nil for a one-off event.
Recurrence *RRule
// RDates and ExDates are explicit additional / excluded occurrence starts.
RDates []time.Time
ExDates []time.Time
}
Event is a parsed (or hand-built) VEVENT, flattened for easy rendering.
Status and Method are kept as plain strings (rather than the typed Status and Method) because they are read straight from the wire and may carry values an older or non-conforming producer emitted; compare them against the typed constants with string conversion, e.g. ev.Status == string(StatusConfirmed).
func ParseICS ¶
ParseICS extracts the first VEVENT from .ics data. It is the convenience entry point for mail clients, which overwhelmingly deal with single-event invites; use Parse when a calendar may hold several events.
func (*Event) Duration ¶
Duration is the wall-clock length of the event. It is zero when either endpoint is unset.
func (*Event) IsRecurring ¶
IsRecurring reports whether the event carries an RRULE or any RDATE.
func (*Event) Occurrences ¶
Occurrences returns the concrete start times of this event within the half-open window [from, to), merging the RRULE expansion with any RDATE and removing any EXDATE. A non-recurring event yields its single start if it falls in the window. Results are sorted and de-duplicated; pass limit > 0 to cap the count (0 means unlimited, subject to an internal safety bound).
func (*Event) Reply ¶
Reply builds a METHOD:REPLY calendar for this event on behalf of userEmail, from the parsed Event rather than the original bytes. Prefer GenerateRSVP when you still hold the invite's raw .ics; use Reply when you only have an Event in hand. status is the responder's PartStat (typically Accepted, Declined or Tentative).
type Method ¶
type Method string
Method is an iTIP/iMIP method (RFC 5546) declared at the VCALENDAR level.
type PartStat ¶
type PartStat string
PartStat is an attendee participation status (PARTSTAT). The Accepted / Declined / Tentative values are also the legal responses to GenerateRSVP and Event.Reply.
type Period ¶
Period is a half-open time interval [Start, End).
func BusyPeriods ¶
BusyPeriods expands every event (including recurrences) into its occurrences within [from, to), clips each to the window, and merges overlapping or touching intervals into a sorted, non-overlapping list of busy time.
Events with zero duration, and all-day events, are honored: an all-day event contributes its full DTSTART–DTEND span. CANCELLED events are skipped.
func FreeBusy ¶
FreeBusy returns the busy intervals within [from, to) (as BusyPeriods) and the free gaps between them that fill the rest of the window.
type RRule ¶
type RRule struct {
Freq Frequency
Interval int
Count int
Until time.Time
ByMonth []time.Month
ByMonthDay []int // day-of-month; negative counts from the end (-1 = last)
ByDay []WeekDay
ByHour []int
ByMinute []int
BySetPos []int // 1-based position within a period; negative from the end
WeekStart time.Weekday
}
RRule is a parsed RRULE recurrence (RFC 5545 §3.3.10). A zero Interval is treated as 1. Count and Until are mutually exclusive bounds; a zero value for each means "unbounded by that mechanism".
func ParseRRule ¶
ParseRRule parses an RRULE value such as "FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE;COUNT=10". A leading "RRULE:" prefix is tolerated. WeekStart defaults to Monday (RFC 5545's default).
func (*RRule) Between ¶
Between enumerates occurrence start times of a rule anchored at dtstart, returning those in the half-open window [from, to). dtstart is always the first occurrence. If limit > 0, at most limit times are returned.
Expansion covers the common, real-world rules: FREQ DAILY/WEEKLY/MONTHLY/ YEARLY (and the sub-day frequencies), INTERVAL, COUNT/UNTIL, BYMONTH, BYMONTHDAY, BYDAY (including ordinals like 2MO / -1FR), and BYSETPOS. Unsupported parts (BYWEEKNO, BYYEARDAY) are ignored.