Current section

Files

Jump to
midas_sdk src midas sdk google calendar.gleam
Raw

src/midas/sdk/google/calendar.gleam

import gleam/bit_array
import gleam/dynamic
import gleam/http
import gleam/http/request
import gleam/http/response
import gleam/json
import gleam/option.{type Option}
import gleam/result.{try}
import gleam/string
import midas/task as t
import snag
const api_host = "www.googleapis.com"
fn base_request(token) {
request.new()
|> request.set_host(api_host)
|> request.prepend_header("Authorization", string.append("Bearer ", token))
}
fn get(token, path) {
base_request(token)
|> request.set_path(path)
|> request.set_body(<<>>)
}
fn post(token, path, mime, content) {
base_request(token)
|> request.set_method(http.Post)
|> request.set_path(path)
|> request.prepend_header("content-type", mime)
|> request.set_body(content)
}
// https://developers.google.com/calendar/api/v3/reference/events/list
pub fn list_events(token, calendar_id, time_min) {
let request = list_events_request(token, calendar_id, time_min)
use response <- t.do(t.fetch(request))
use response <- t.try(list_events_response(response))
t.Done(response)
}
pub fn list_events_request(token, calendar_id, time_min) {
let path = "/calendar/v3/calendars/" <> calendar_id <> "/events"
get(token, path)
|> request.set_query([
#("timeMin", time_min),
#("orderBy", "startTime"),
#("singleEvents", "true"),
])
}
pub fn list_events_response(response: response.Response(BitArray)) {
use json <- try(
bit_array.to_string(response.body)
|> result.replace_error(snag.new("not utf8 encoded")),
)
let decoder = dynamic.field("items", dynamic.list(event_decoder))
use message <- try(
json.decode_bits(response.body, decoder)
|> result.map_error(fn(reason) {
snag.new(string.inspect(reason))
|> snag.layer("failed to decode message")
}),
)
Ok(message)
}
pub type Event {
Event(
summary: String,
location: Option(String),
start: DateOrDatetime,
end: DateOrDatetime,
)
}
pub fn event_decoder(raw) {
dynamic.decode4(
Event,
dynamic.field("summary", dynamic.string),
dynamic.optional_field("location", dynamic.string),
dynamic.field("start", date_or_datetime_decoder),
dynamic.field("end", date_or_datetime_decoder),
)(raw)
}
pub type DateOrDatetime {
Date(String)
Datetime(String)
}
pub fn date_or_datetime_decoder(raw) {
dynamic.any([
dynamic.decode1(Date, dynamic.field("date", dynamic.string)),
dynamic.decode1(Datetime, dynamic.field("dateTime", dynamic.string)),
])(raw)
}