package main import ( "encoding/xml" "fmt" "io" "log" "net/http" "net/http/cookiejar" "strings" "text/template" "time" ) type FolderId struct { Id string `xml:",attr"` ChangeKey string `xml:",attr"` } type CalendarItem struct { Subject string UID string Start time.Time End time.Time } type EWSCalendar struct { httpClient *http.Client url string username string password string items []CalendarItem } func NewEWSCalendar(url, username, password string) *EWSCalendar { // Prepare a cookie jar so we don't have to provide basic auth credentials multiple times. jar, err := cookiejar.New(nil) if err != nil { panic(err) } return &EWSCalendar{ httpClient: &http.Client{ Jar: jar, }, url: url, username: username, password: password, } } func (e *EWSCalendar) prepareRequest(body io.Reader) (req *http.Request, err error) { req, err = http.NewRequest(http.MethodPost, e.url, body) req.Header.Set("Content-Type", "text/xml") req.Header.Set("Accept", "text/xml") return } func (e *EWSCalendar) getCalendarFolderID() (id *FolderId, err error) { req, err := e.prepareRequest(strings.NewReader(folderIdRequest)) if err != nil { return } // For the first request we need an authentication header req.SetBasicAuth(e.username, e.password) resp, err := e.httpClient.Do(req) if err != nil { return } if resp.StatusCode != http.StatusOK { err = fmt.Errorf("unexpected status when querying folderID: %d", resp.StatusCode) return } d := xml.NewDecoder(resp.Body) defer resp.Body.Close() for { var t xml.Token t, err = d.Token() if err == io.EOF { err = nil return } else if err != nil { return } switch t := t.(type) { case xml.StartElement: if t.Name.Local == "FolderId" { id = &FolderId{} err = d.DecodeElement(id, &t) // The first one is enough return } } } } func main() { e := NewEWSCalendar("https://outlook.live.com/EWS/Exchange.asmx", "", "") id, err := e.getCalendarFolderID() if err != nil { log.Println(err) return } fmt.Println(id) } const folderIdRequest = ` AllProperties ` var calendarQuery = template.Must(template.New("calendarQuery").Parse(` IdOnly `))