Msg.Calendar.Events (msg v0.3.8)
Interact with Microsoft Graph Calendar Events API.
Provides functions to create, read, update, and delete calendar events for both user calendars (personal) and group calendars (shared). Supports open extensions for tagging events with custom metadata.
Required Permissions
User Calendars
- Application:
Calendars.ReadWrite- read/write all users' calendars - Delegated:
Calendars.ReadWrite- read/write user's calendars
Group Calendars
- Application: ❌ Not supported
- Delegated:
Calendars.ReadWrite.Shared- required for group calendar access
Authentication
- User calendars (
/users/{user_id}/events): Works with application-only authentication - Group calendars (
/groups/{group_id}/calendar/events): Requires delegated permissions
Examples
# User calendar with application-only authentication
app_client = Msg.Client.new(%{
client_id: "...",
client_secret: "...",
tenant_id: "..."
})
{:ok, events} = Msg.Calendar.Events.list(app_client, user_id: "user@contoso.com")
# Group calendar with delegated permissions (refresh token)
delegated_client = Msg.Client.new(refresh_token, credentials)
{:ok, events} = Msg.Calendar.Events.list(delegated_client, group_id: "group-id")
# Create event with extension
event = %{subject: "Team Meeting", start: %{...}, end: %{...}}
extension = %{extension_name: "com.example.metadata", project_id: "123"}
{:ok, created} = Msg.Calendar.Events.create_with_extension(
app_client, event, extension, user_id: "user@contoso.com"
)References
Summary
Functions
Creates a new calendar event.
Creates a calendar event with an open extension in a single optimized operation.
Deletes a calendar event.
Gets a single calendar event.
Gets a calendar event with a specific extension.
Lists calendar events.
Updates an existing calendar event.
Functions
@spec create(Req.Request.t(), map(), keyword()) :: {:ok, map()} | {:error, term()}
Creates a new calendar event.
Parameters
client- Authenticated Req.Request clientevent- Map with event properties::subject(required) - Event title:start(required) - Start datetime map withdate_timeandtime_zone:end(required) - End datetime map withdate_timeandtime_zone:body(optional) - Event body/description:location(optional) - Location information:attendees(optional) - List of attendees:is_all_day(optional) - Boolean
opts- Keyword list of options::user_id- User ID or UPN (for personal calendar):group_id- Group ID (for group calendar)
Note: Either :user_id or :group_id is required.
Returns
{:ok, event}- Created event with generated ID{:error, :unauthorized}- Invalid or expired token{:error, {:invalid_request, message}}- Validation error{:error, term}- Other errors
Examples
event = %{
subject: "Team Meeting",
start: %{
date_time: "2025-01-15T14:00:00",
time_zone: "Pacific Standard Time"
},
end: %{
date_time: "2025-01-15T15:00:00",
time_zone: "Pacific Standard Time"
}
}
{:ok, created} = Msg.Calendar.Events.create(client, event,
user_id: "user@contoso.com"
)
@spec create_with_extension(Req.Request.t(), map(), map(), keyword()) :: {:ok, map()} | {:error, term()}
Creates a calendar event with an open extension in a single optimized operation.
This function creates the event first, then immediately adds the extension.
Parameters
client- Authenticated Req.Request clientevent- Event data map (seecreate/3)extension- Extension data map::extension_name(required) - Unique name (e.g., "com.example.metadata")- Custom properties as needed
opts- Keyword list of options::user_id- User ID or UPN (for personal calendar):group_id- Group ID (for group calendar)
Note: Either :user_id or :group_id is required.
Returns
{:ok, event}- Created event with extension{:error, term}- Error
Examples
event = %{subject: "Project Milestone", start: %{...}, end: %{...}}
extension = %{
extension_name: "com.example.metadata",
project_id: "proj_abc123",
resource_id: "res_xyz789"
}
{:ok, event_with_ext} = Msg.Calendar.Events.create_with_extension(
client, event, extension, user_id: "user@contoso.com"
)
@spec delete(Req.Request.t(), String.t(), keyword()) :: :ok | {:error, term()}
Deletes a calendar event.
Parameters
client- Authenticated Req.Request clientevent_id- ID of event to deleteopts- Keyword list of options::user_id- User ID or UPN (for personal calendar):group_id- Group ID (for group calendar)
Note: Either :user_id or :group_id is required.
Returns
:ok- Event deleted successfully (204 status){:error, :not_found}- Event doesn't exist{:error, term}- Other errors
Examples
:ok = Msg.Calendar.Events.delete(client, event_id, user_id: "user@contoso.com")
:ok = Msg.Calendar.Events.delete(client, event_id, group_id: "group-id-here")
@spec get(Req.Request.t(), String.t(), keyword()) :: {:ok, map()} | {:error, term()}
Gets a single calendar event.
Parameters
client- Authenticated Req.Request clientevent_id- ID of the event to retrieveopts- Keyword list of options::user_id- User ID or UPN (for personal calendar):group_id- Group ID (for group calendar):expand_extensions- Boolean, include extensions in response:select- List of fields to select
Note: Either :user_id or :group_id is required.
Returns
{:ok, event}- Event map{:error, :not_found}- Event doesn't exist{:error, term}- Other errors
Examples
{:ok, event} = Msg.Calendar.Events.get(client, "event-id",
user_id: "user@contoso.com",
expand_extensions: true
)
{:ok, event} = Msg.Calendar.Events.get(client, "event-id",
group_id: "group-id-here"
)
@spec get_with_extensions(Req.Request.t(), String.t(), String.t(), keyword()) :: {:ok, map()} | {:error, term()}
Gets a calendar event with a specific extension.
Note: Microsoft Graph does not support listing all extensions on calendar events. To retrieve an extension, you must know its ID. Use this function to get an event along with a specific extension by providing the extension ID.
Parameters
client- Authenticated Req.Request clientevent_id- ID of the eventextension_id- ID of the extension to retrieve (e.g., "com.example.metadata")opts- Keyword list of options::user_id- User ID or UPN (for personal calendar):group_id- Group ID (for group calendar)
Note: Either :user_id or :group_id is required.
Returns
{:ok, event}- Event map withextensionsfield populated with the requested extension{:error, :not_found}- Event or extension doesn't exist{:error, term}- Other errors
Examples
{:ok, event} = Msg.Calendar.Events.get_with_extensions(client, event_id,
"com.example.metadata",
user_id: "user@contoso.com"
)
ext = List.first(event["extensions"])
project_id = ext["projectId"]
@spec list( Req.Request.t(), keyword() ) :: {:ok, [map()]} | {:ok, map()} | {:error, term()}
Lists calendar events.
Parameters
client- Authenticated Req.Request clientopts- Keyword list of options::user_id- User ID or UPN (for personal calendar):group_id- Group ID (for group calendar):start_datetime- Filter events starting after this DateTime:end_datetime- Filter events starting before this DateTime:auto_paginate- Boolean, default true (fetch all pages):filter- OData filter string:select- List of fields to select:orderby- OData orderby string
Note: Either :user_id or :group_id is required.
Returns
{:ok, [event]}- List of events (when auto_paginate: true){:ok, %{items: [event], next_link: url}}- First page with next link (when auto_paginate: false){:error, term}- Error
Examples
# List user calendar events
{:ok, events} = Msg.Calendar.Events.list(client,
user_id: "user@contoso.com",
start_datetime: ~U[2025-01-01 00:00:00Z],
end_datetime: ~U[2025-12-31 23:59:59Z]
)
# List group calendar events
{:ok, events} = Msg.Calendar.Events.list(client,
group_id: "group-id-here",
auto_paginate: true
)
Updates an existing calendar event.
Parameters
client- Authenticated Req.Request clientevent_id- ID of event to updateupdates- Map of fields to updateopts- Keyword list of options::user_id- User ID or UPN (for personal calendar):group_id- Group ID (for group calendar)
Note: Either :user_id or :group_id is required.
Returns
{:ok, event}- Updated event{:error, :not_found}- Event doesn't exist{:error, term}- Other errors
Examples
{:ok, updated} = Msg.Calendar.Events.update(client, event_id,
%{subject: "Updated Title"},
user_id: "user@contoso.com"
)