ews

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: MIT Imports: 13 Imported by: 0

README

go-ews — клиент Exchange Web Services для Go

Библиотека для работы с Microsoft Exchange Web Services (EWS) из Go. Реализует SOAP-клиент, типы запросов/ответов и набор готовых операций над почтовым ящиком, календарём и персонами.

Модуль: github.com/vihapr/go-ews

Минимальная версия Go: 1.21.


Содержание


Установка

go get github.com/vihapr/go-ews

Импорт:

import (
    "github.com/vihapr/go-ews"
    "github.com/vihapr/go-ews/ewsutil"
)

Создание клиента

c := ews.NewClient(
    "https://outlook.office365.com/EWS/Exchange.asmx",
    "email@exchangedomain",
    "password",
    &ews.Config{
        Dump:    false, // логировать запросы/ответы в stdout
        NTLM:    false, // использовать NTLM-аутентификацию
        SkipTLS: false, // пропустить проверку TLS-сертификата
    },
)

Config — опциональная структура, можно передать nil для значений по умолчанию (Basic-аутентификация, без дампа).

Методы клиента

ews.Client — интерфейс с тремя методами:

Метод Назначение
SendAndReceive(body []byte) ([]byte, error) Синхронный SOAP-вызов без контекста (context.Background)
SendAndReceiveContext(ctx, body) ([]byte, error) SOAP-вызов с поддержкой отмены/таймаута через ctx
GetEWSAddr() string URL EWS-эндпоинта
GetUsername() string Имя аутентифицированного пользователя

SendAndReceive теперь делегирует в SendAndReceiveContext(context.Background(), ...). HTTP ≠ 200 оборачивается в *ews.HTTPError{Status, StatusCode} или *ews.SoapError{Fault}.


Аутентификация

Тип Флаг Когда использовать
Basic NTLM: false Office 365, Exchange Online, cloud-инсталляции
NTLM NTLM: true On-premises Exchange в AD-домене

Для on-premises Exchange с NTLM имя пользователя обычно передаётся как DOMAIN\username, например MYCOMPANY\ivan.ivanov.


Поддержка context.Context

Начиная с версии с batch-операциями интерфейс Client расширён методом SendAndReceiveContext(ctx, body). Это позволяет:

  • отменять долгий HTTP-вызов через ctx.Done();
  • ставить таймаут на транспорт (context.WithTimeout);
  • пробрасывать дедлайн из вышележащего обработчика.

Все batch-методы библиотеки принимают context.Context первым аргументом. Одиночные (CreateCalendarItem, DeleteCalendarItem, UpdateCalendarItemTime, GetCalendarItemChangeKey) оставлены без контекста для обратной совместимости и внутри используют context.Background().

При заранее отменённом контексте библиотека возвращает ctx.Err() без выполнения HTTP-запроса.


Календарь — одиночные операции

Создать событие
item := ews.CalendarItem{
    Subject:                    "Planning Meeting",
    Body:                       ews.Body{BodyType: "Text", Body: []byte("Agenda")},
    ReminderIsSet:              true,
    ReminderMinutesBeforeStart: 15,
    UID:                        "11223344-5566-7788-99aa-bbccddeeff00", // опц. — см. раздел про iCalUid
    Start:                      start,
    End:                        end,
    IsAllDayEvent:              false,
    LegacyFreeBusyStatus:       ews.BusyTypeBusy,
    Location:                   "Conference Room 721",
    RequiredAttendees:          []ews.Attendees{{Attendee: attendees}},
    OptionalAttendees:          []ews.Attendees{{Attendee: optional}},
    Resources:                  []ews.Attendees{{Attendee: rooms}},
    Attachments:                &ews.Attachments{Attachments: files}, // опц.
}
id, err := ews.CreateCalendarItem(c, item)
Удалить событие
id, err := ews.DeleteCalendarItem(c, "AAMkAGY...")
Обновить время события
updatedID, err := ews.UpdateCalendarItemTime(c, "AAMkAGY...", start, end)

Внутри резолвит текущий ChangeKey через GetCalendarItemChangeKey и формирует UpdateItem с полями calendar:Start и calendar:End.

Получить ChangeKey
changeKey, err := ews.GetCalendarItemChangeKey(c, "AAMkAGY...")

Реализован как тонкая обёртка над GetCalendarItemsChangeKeys (batch-версия) для одного id.


Календарь — пакетные операции (batch)

Позволяют до 50 операций в одном SOAP-запросе. Снижают число HTTP-вызовов к Exchange и подходят для массовой синхронизации событий (sync absence-фонов, массовые напоминания и т.п.).

Все batch-методы принимают context.Context первым аргументом.

Создать несколько событий
items := []ews.CalendarItem{
    {Subject: "Event A", UID: "uid-a", Start: s1, End: e1, LegacyFreeBusyStatus: "Busy"},
    {Subject: "Event B", UID: "uid-b", Start: s2, End: e2, LegacyFreeBusyStatus: "OOF"},
}
results, err := ews.CreateCalendarItems(ctx, c, items)
if err != nil {
    // ошибка всего запроса: HTTP ≠ 200, ошибка маршалинга, превышение лимита и т.п.
    return
}
for _, r := range results {
    if r.Error != nil {
        // частичная ошибка — конкретный элемент не создан, остальные в порядке
        log.Printf("item[%d] failed: %v", r.Index, r.Error)
        continue
    }
    log.Printf("item[%d] created: id=%s changeKey=%s", r.Index, r.ItemID, r.ChangeKey)
}

Тип результата:

type CreateItemResult struct {
    Index     int      // позиция во входном слайсе
    ItemID    string   // пустая строка при ошибке
    ChangeKey string
    Error     error    // nil при успехе
}
Удалить несколько событий
results, err := ews.DeleteCalendarItems(ctx, c, []string{"AAMkAAA=", "AAMkBBB="})
type DeleteItemResult struct {
    Index  int
    ItemID string // эхо входного id
    Error  error
}
Обновить время нескольких событий
items := []ews.UpdateCalendarItemInput{
    {ItemID: "AAMkAAA=", ChangeKey: "ck-aaa", Start: s1, End: e1},
    {ItemID: "AAMkBBB=", ChangeKey: "",        Start: s2, End: e2}, // ChangeKey будет зарезолвлен
}
results, err := ews.UpdateCalendarItemsTime(ctx, c, items)
type UpdateCalendarItemInput struct {
    ItemID    string
    ChangeKey string // если пусто — резолвится одним batch-запросом GetItem
    Start     time.Time
    End       time.Time
}

type UpdateItemResult struct {
    Index     int
    ItemID    string // новый id/ChangeKey после апдейта
    ChangeKey string
    Error     error
}

Если у одного или нескольких элементов ChangeKey пустой, библиотека делает один дополнительный batch-запрос GetCalendarItemsChangeKeys для резолва. Если хотя бы один id не зарезолвился — весь батч отменяется (Exchange всё равно отвергнет апдейт без валидного ChangeKey на каждый элемент).

Резолв ChangeKey для набора событий
keys, failed, err := ews.GetCalendarItemsChangeKeys(ctx, c, []string{"AAMkAAA=", "AAMkBBB="})
// keys     = map[itemID]changeKey — успешно найденные
// failed   = []string             — id, не найденные на сервере (ResponseClass=Error или пустой ChangeKey)

iCalUid и дедупликация событий

Поле UID в структуре CalendarItem соответствует iCalUid события в календаре Exchange. Используется для серверной и клиентской дедупликации:

  • Exchange сохраняет переданный UID как iCalUid события.
  • Повторный CreateItem с тем же UID воспринимается Outlook/mobile-клиентами как апдейт того же события, дубль не плодится.
  • При ретраях (повторных отправках) идемпотентность достигается именно через UID.
item := ews.CalendarItem{
    Subject: "Absence",
    UID:     "11223344-5566-7788-99aa-bbccddeeff00", // iCalUid
    Start:   start,
    End:     end,
}

Поле имеет тег xml:"t:UID,omitempty", поэтому вызовы без UID сериализуются байт-в-байт как раньше (обратная совместимость).

Позиция <t:UID> в XML соответствует EWS-схеме CalendarItemType — перед <t:Start>, рядом с другими strongly-typed свойствами.


Контракт ошибок batch-методов

Все batch-методы (CreateCalendarItems, DeleteCalendarItems, UpdateCalendarItemsTime, GetCalendarItemsChangeKeys) следуют одному контракту:

Top-level error (второе возвращаемое значение) непусто только при:

  • ошибке маршалинга запроса или анмаршалинга ответа;
  • HTTP ≠ 200 (включая 429 и 5xx — проброс *ews.HTTPError / *ews.SoapError, вышележащий код сам делает ретраи);
  • превышении лимита Max*ItemsPerRequest;
  • пустом конверте ответа (ни одного *ResponseMessage);
  • невозможности зарезолвить ChangeKey (только для UpdateCalendarItemsTime);
  • отмене контекста (ctx.Err() пробрасывается как есть).

В этих случаях слайс результатов — nil.

Частичные ошибки (ResponseClass="Error" на отдельных элементах батча) не заваливают весь вызов. Соответствующая позиция в слайсе результатов содержит Error != nil, остальные элементы — штатные.

Проброс *ews.HTTPError делает батч-методы совместимыми с throttling / retry / circuit-breaker декораторами вышележащего сервиса — retry-логика реагирует на стандартный тип ошибки.


Лимиты EWS

Exchange ограничивает число операций в одном batch-запросе. Библиотека объявляет константы и принудительно проверяет входные слайсы:

Константа Значение Применима к
MaxCreateItemsPerRequest 50 CreateCalendarItems
MaxDeleteItemsPerRequest 50 DeleteCalendarItems
MaxUpdateItemsPerRequest 50 UpdateCalendarItemsTime
MaxGetItemsPerRequest 50 GetCalendarItemsChangeKeys

При превышении возвращается явная ошибка — библиотека не режет входной слайс молча. Вышележащий код (например, almanac ThrottledClient) сам формирует батчи нужного размера.


Email

err := ewsutil.SendEmail(c,
    []string{"alice@example.com", "bob@example.com"},
    "Тема письма",
    "Тело письма plain text",
)

Доступность и помещения

GetUserAvailability

Запрос занятости пользователей в диапазоне времени. Возвращает free/busy и опционально детали событий (тема, место).

req := &ews.GetUserAvailabilityRequest{
    TimeZone:         ews.TimeZone{Bias: -180, /* ... */},
    MailboxDataArray: ews.MailboxDataArray{MailboxData: mb},
    FreeBusyViewOptions: ews.FreeBusyViewOptions{
        TimeWindow:      ews.TimeWindow{StartTime: from, EndTime: to},
        RequestedView:   ews.RequestedViewDetailed, // или FreeBusy, FreeBusyMerged, DetailedMerged
    },
}
resp, err := ews.GetUserAvailability(c, req)
GetRoomLists

Список распределительных групп помещений. Полезен как лёгкий health-check.

resp, err := ews.GetRoomLists(c)

Персоны и фотографии

Метод Описание
ews.FindPeople(c, q) Поиск персон по строке
ews.GetPersona(c, personaID) Получить детальную информацию о персоне
ewsutil.GetUserPhoto(c, email) Бинарное содержимое фотографии
ewsutil.GetUserPhotoBase64(c, email) Base64-представление фотографии
ewsutil.GetUserPhotoURL(c, email) Прямой URL для скачивания фотографии

Утилиты ewsutil

Тонкие обёртки над операциями ews для типовых сценариев:

Функция Эквивалент
ewsutil.CreateEvent(...) ews.CreateCalendarItem (text body)
ewsutil.CreateHTMLEvent(...) ews.CreateCalendarItem (HTML body + files)
ewsutil.DeleteCalendarEvent(c, id) ews.DeleteCalendarItem
ewsutil.UpdateEventTime(c, id, s, e) ews.UpdateCalendarItemTime
ewsutil.ListUsersEvents(c, users, from, d) ews.GetUserAvailability
ewsutil.SendEmail(c, to, subject, body) ews.CreateMessageItem
ewsutil.FindPeople(c, q) ews.FindPeople
ewsutil.GetPersona(c, id) ews.GetPersona
ewsutil.GetUserPhoto* см. таблицу выше

Поддерживаемые операции

Категория Операция Поддержка
Почта и календарь CreateItem Email, Calendar
DeleteItem Calendar (single + batch)
UpdateItem Calendar Start/End (single + batch)
GetItem IdOnly / ChangeKey (single + batch)
Доступность GetUserAvailability FreeBusy, Detailed
GetRoomLists Health-check, список помещений
Персон FindPeople Поиск
GetPersona Детали персоны
Фотографии GetUserPhoto Binary, Base64, URL

Не все поля EWS-схем отображены — покрываются поля, необходимые для текущих потребителей (notificator, almanac).


Ссылки

Documentation

Overview

Package wrapping Exchange Web Service (EWS)

https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/ews-operations-in-exchange

Index

Constants

View Source
const (
	RequestedViewNone           = "None"
	RequestedViewMergedOnly     = "MergedOnly"
	RequestedViewFreeBusy       = "FreeBusy"
	RequestedViewFreeBusyMerged = "FreeBusyMerged"
	RequestedViewDetailed       = "Detailed"
	RequestedViewDetailedMerged = "DetailedMerged"
)
View Source
const (
	BusyTypeFree      = "Free"
	BusyTypeTentative = "Tentative"
	BusyTypeBusy      = "Busy"
	BusyTypeOOF       = "OOF"
	BusyTypeNoData    = "NoData"
)
View Source
const MaxCreateItemsPerRequest = 50

MaxCreateItemsPerRequest — лимит числа элементов в одном EWS CreateItem. Exchange документирует потолок 50; больше — ErrorTooManyObjectsOpened.

View Source
const MaxDeleteItemsPerRequest = 50

MaxDeleteItemsPerRequest — лимит числа элементов в одном EWS DeleteItem. Exchange документирует потолок 50 (общий лимит на batch-операцию).

View Source
const MaxGetItemsPerRequest = 50

MaxGetItemsPerRequest — лимит числа элементов в одном EWS GetItem. Exchange документирует потолок 50 (общий лимит на batch-операцию).

View Source
const MaxUpdateItemsPerRequest = 50

MaxUpdateItemsPerRequest — лимит числа элементов в одном EWS UpdateItem. Exchange документирует потолок 50 (общий лимит на batch-операцию).

Variables

This section is empty.

Functions

func GetCalendarItemChangeKey added in v0.0.18

func GetCalendarItemChangeKey(c Client, id string) (string, error)

GetCalendarItemChangeKey resolves the current ChangeKey of a calendar item by its ID via the GetItem operation. Exchange requires a valid ChangeKey on UpdateItem requests; use this helper to obtain one when only the item ID is known.

Реализован как тонкая обёртка над batch-версией GetCalendarItemsChangeKeys (см. spec §2.5).

https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/getitem-operation

func GetCalendarItemsChangeKeys added in v0.0.19

func GetCalendarItemsChangeKeys(ctx context.Context, c Client, ids []string) (map[string]string, []string, error)

GetCalendarItemsChangeKeys резолвит ChangeKey для набора item id одним GetItem-запросом.

Возвращает:

  • map[itemID]changeKey для успешно найденных элементов;
  • слайс id, которые не удалось найти (ResponseClass=Error или пустой ChangeKey в ответе);
  • top-level error при ошибке маршалинга, HTTP ≠ 200, пустом конверте, превышении лимита или отмене контекста.

В случае top-level error остальные возвращаемые значения — nil/пустые.

https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/getitem-operation

func NewError

func NewError(resp *http.Response) error

func UpdateCalendarItemTime added in v0.0.17

func UpdateCalendarItemTime(c Client, id string, start, end time.Time) (string, error)

UpdateCalendarItemTime updates only the start and end time of a calendar item https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/updateitem-operation

Types

type AdditionalProperties

type AdditionalProperties struct {
	FieldURI []FieldURI `xml:"t:FieldURI,omitempty"`
}

type ArrayOfAttendeeConflictData

type ArrayOfAttendeeConflictData struct {
	UnknownAttendeeConflictData     string                    `xml:"UnknownAttendeeConflictData"`
	IndividualAttendeeConflictData  string                    `xml:"IndividualAttendeeConflictData"`
	TooBigGroupAttendeeConflictData string                    `xml:"TooBigGroupAttendeeConflictData"`
	GroupAttendeeConflictData       GroupAttendeeConflictData `xml:"GroupAttendeeConflictData"`
}

type Attachments added in v0.0.16

type Attachments struct {
	XMLName     xml.Name         `xml:"t:Attachments"`
	Attachments []FileAttachment `xml:"t:FileAttachment"`
}

type Attendee

type Attendee struct {
	Mailbox Mailbox `xml:"t:Mailbox"`
}

type AttendeeType

type AttendeeType string
const (
	AttendeeTypeOrganizer AttendeeType = "Organizer"
	AttendeeTypeRequired  AttendeeType = "Required"
	AttendeeTypeOptional  AttendeeType = "Optional"
	AttendeeTypeRoom      AttendeeType = "Room"
	AttendeeTypeResource  AttendeeType = "Resource"
)

type Attendees

type Attendees struct {
	Attendee []Attendee `xml:"t:Attendee"`
}

type BasePoint

type BasePoint string
const (
	BasePointBeginning BasePoint = "Beginning"
	BasePointEnd       BasePoint = "End"
)

type BaseShape

type BaseShape string
const (
	BaseShapeIdOnly        BaseShape = "IdOnly"
	BaseShapeDefault       BaseShape = "Default"
	BaseShapeAllProperties BaseShape = "AllProperties"
)

type Body

type Body struct {
	BodyType string `xml:"BodyType,attr"`
	Body     []byte `xml:",chardata"`
}

type BusinessPhoneNumbers

type BusinessPhoneNumbers struct {
	PhoneNumberAttributedValue PhoneNumberAttributedValue `xml:"PhoneNumberAttributedValue"`
}

type BusyType

type BusyType string

type CalendarEvent

type CalendarEvent struct {
	StartTime            Time                 `xml:"StartTime"`
	EndTime              Time                 `xml:"EndTime"`
	BusyType             BusyType             `xml:"BusyType"`
	CalendarEventDetails CalendarEventDetails `xml:"CalendarEventDetails"`
}

type CalendarEventArray

type CalendarEventArray struct {
	CalendarEvent []CalendarEvent `xml:"CalendarEvent"`
}

type CalendarEventDetails

type CalendarEventDetails struct {
	ID            string `xml:"ID"`
	Subject       string `xml:"Subject"`
	Location      string `xml:"Location"`
	IsMeeting     bool   `xml:"IsMeeting"`
	IsRecurring   bool   `xml:"IsRecurring"`
	IsException   bool   `xml:"IsException"`
	IsReminderSet bool   `xml:"IsReminderSet"`
	IsPrivate     bool   `xml:"IsPrivate"`
}

type CalendarItem

type CalendarItem struct {
	Subject                    string              `xml:"t:Subject"`
	Body                       Body                `xml:"t:Body"`
	ReminderIsSet              bool                `xml:"t:ReminderIsSet"`
	ReminderMinutesBeforeStart int                 `xml:"t:ReminderMinutesBeforeStart"`
	UID                        string              `xml:"t:UID,omitempty"`
	MeetingTimeZone            *MeetingTimeZone    `xml:"t:MeetingTimeZone,omitempty"`
	StartTimeZone              *TimeZoneDefinition `xml:"t:StartTimeZone,omitempty"`
	EndTimeZone                *TimeZoneDefinition `xml:"t:EndTimeZone,omitempty"`
	Start                      time.Time           `xml:"t:Start"`
	End                        time.Time           `xml:"t:End"`
	IsAllDayEvent              bool                `xml:"t:IsAllDayEvent"`
	LegacyFreeBusyStatus       string              `xml:"t:LegacyFreeBusyStatus"`
	Location                   string              `xml:"t:Location"`
	RequiredAttendees          []Attendees         `xml:"t:RequiredAttendees"`
	OptionalAttendees          []Attendees         `xml:"t:OptionalAttendees"`
	Resources                  []Attendees         `xml:"t:Resources"`
	Attachments                *Attachments        `xml:"t:Attachments,omitempty"`
}

type CalendarItemResponse added in v0.0.13

type CalendarItemResponse struct {
	ItemId ResponseItemId `xml:"ItemId"`
}

type Client

type Client interface {
	SendAndReceive(body []byte) ([]byte, error)
	SendAndReceiveContext(ctx context.Context, body []byte) ([]byte, error)
	GetEWSAddr() string
	GetUsername() string
}

func NewClient

func NewClient(ewsAddr, username, password string, config *Config) Client

type Config

type Config struct {
	Dump    bool
	NTLM    bool
	SkipTLS bool
}

type CreateItem

type CreateItem struct {
	XMLName                struct{}          `xml:"m:CreateItem"`
	MessageDisposition     string            `xml:"MessageDisposition,attr"`
	SendMeetingInvitations string            `xml:"SendMeetingInvitations,attr"`
	SavedItemFolderId      SavedItemFolderId `xml:"m:SavedItemFolderId"`
	Items                  Items             `xml:"m:Items"`
}

type CreateItemResponse

type CreateItemResponse struct {
	ResponseMessages ResponseMessages `xml:"ResponseMessages"`
}

type CreateItemResult added in v0.0.19

type CreateItemResult struct {
	Index     int
	ItemID    string
	ChangeKey string
	Error     error
}

CreateItemResult — результат одного элемента batch-Create.

Index соответствует позиции входного CalendarItem в слайсе, переданном в CreateCalendarItems. При успешном создании ItemID/ChangeKey заполнены, Error == nil. При неудаче ItemID/ChangeKey пустые, Error описывает причину.

func CreateCalendarItems added in v0.0.19

func CreateCalendarItems(ctx context.Context, c Client, items []CalendarItem) ([]CreateItemResult, error)

CreateCalendarItems создаёт несколько событий в одном SOAP-запросе.

Возвращает по одному CreateItemResult на каждый входной CalendarItem в том же порядке. Частичные ошибки (один ResponseClass="Error" в батче) не заваливают весь вызов: такие элементы возвращаются с Error != nil, остальные — со штатными ItemID/ChangeKey.

Второе возвращаемое значение (top-level error) непусто только при:

  • ошибке маршалинга запроса или анмаршалинга ответа;
  • HTTP ≠ 200 (проброс *ews.HTTPError / *ews.SoapError — almanac делает ретраи);
  • превышении лимита MaxCreateItemsPerRequest;
  • пустом конверте ответа (ни одного CreateItemResponseMessage);
  • отмене контекста.

В этих случаях []CreateItemResult — nil.

https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/createitem-operation

type DeleteItem added in v0.0.15

type DeleteItem struct {
	XMLName                  struct{} `xml:"m:DeleteItem"`
	DeleteType               string   `xml:"DeleteType,attr"`
	SendMeetingCancellations string   `xml:"SendMeetingCancellations,attr"`
	ItemIds                  ItemIds  `xml:"m:ItemIds"`
}

type DeleteItemId added in v0.0.15

type DeleteItemId struct {
	Id string `xml:"Id,attr"`
}

type DeleteItemResponse added in v0.0.15

type DeleteItemResponse struct {
	ResponseMessages DeleteResponseMessages `xml:"ResponseMessages"`
}

type DeleteItemResponseMessage added in v0.0.15

type DeleteItemResponseMessage struct {
	DeleteResponseClass ResponseClass `xml:"ResponseClass,attr"`
	MessageText         string        `xml:"MessageText"`
	ResponseCode        string        `xml:"ResponseCode"`
}

type DeleteItemResult added in v0.0.19

type DeleteItemResult struct {
	Index  int
	ItemID string
	Error  error
}

DeleteItemResult — результат одного элемента batch-Delete.

ItemID — эхо входного id (Exchange не возвращает новых id для Delete). При неудаче Error описывает причину (например, ErrorItemNotFound для уже удалённого события).

func DeleteCalendarItems added in v0.0.19

func DeleteCalendarItems(ctx context.Context, c Client, ids []string) ([]DeleteItemResult, error)

DeleteCalendarItems удаляет несколько событий в одном SOAP-запросе.

Возвращает по одному DeleteItemResult на каждый входной id в том же порядке. Частичные ошибки (один ResponseClass="Error" в батче, например ErrorItemNotFound для уже удалённого) не заваливают весь вызов — такие элементы возвращаются с Error != nil, остальные с пустым Error.

Top-level error непусто при ошибке маршалинга, HTTP ≠ 200, пустом конверте, превышении лимита или отмене контекста — в этих случаях []DeleteItemResult — nil. См. CreateCalendarItems для подробностей.

https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/deleteitem-operation

type DeleteResponseMessages added in v0.0.15

type DeleteResponseMessages struct {
	DeleteItemResponseMessage DeleteItemResponseMessage `xml:"DeleteItemResponseMessage"`
}

type Departments

type Departments struct {
	StringAttributedValue StringAttributedValue `xml:"StringAttributedValue"`
}

type DistinguishedFolderId

type DistinguishedFolderId struct {
	// List of values:
	// https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/distinguishedfolderid
	Id string `xml:"Id,attr"`
}

type Email

type Email struct {
	Name        string `xml:"t:Name"`
	Address     string `xml:"t:Address"`
	RoutingType string `xml:"t:RoutingType"`
}

type EmailAddress

type EmailAddress struct {
	Name         string `xml:"Name"`
	EmailAddress string `xml:"EmailAddress"`
	RoutingType  string `xml:"RoutingType"`
	MailboxType  string `xml:"MailboxType"`
	ItemId       ItemId `xml:"ItemId"`
}

type Fault

type Fault struct {
	Faultcode   string `xml:"faultcode"`
	Faultstring string `xml:"faultstring"`
	Detail      detail `xml:"detail"`
}

type FieldURI

type FieldURI struct {
	// List of possible values:
	// https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/fielduri
	FieldURI string `xml:"FieldURI,attr,omitempty"`
}

type FileAttachment added in v0.0.16

type FileAttachment struct {
	XMLName     xml.Name `xml:"t:FileAttachment"`
	ContentId   string   `xml:"t:ContentId,omitempty"`
	Name        string   `xml:"t:Name,omitempty"`
	Content     string   `xml:"t:Content,omitempty"` // base64 content
	ContentType string   `xml:"t:ContentType,omitempty"`
}

type FindPeopleRequest

type FindPeopleRequest struct {
	XMLName             struct{}            `xml:"m:FindPeople"`
	PersonaShape        *PersonaShape       `xml:"m:PersonaShape,omitempty"`
	IndexedPageItemView IndexedPageItemView `xml:"m:IndexedPageItemView"`
	ParentFolderId      ParentFolderId      `xml:"m:ParentFolderId"`
	QueryString         string              `xml:"m:QueryString,omitempty"`
}

type FindPeopleResponse

type FindPeopleResponse struct {
	Response
	People                    People `xml:"People"`
	TotalNumberOfPeopleInView int    `xml:"TotalNumberOfPeopleInView"`
	FirstMatchingRowIndex     int    `xml:"FirstMatchingRowIndex"`
	FirstLoadedRowIndex       int    `xml:"FirstLoadedRowIndex"`
}

type FreeBusyResponse

type FreeBusyResponse struct {
	ResponseMessage ResponseMessage `xml:"ResponseMessage"`
	FreeBusyView    FreeBusyView    `xml:"FreeBusyView"`
}

type FreeBusyResponseArray

type FreeBusyResponseArray struct {
	FreeBusyResponse []FreeBusyResponse `xml:"FreeBusyResponse"`
}

type FreeBusyView

type FreeBusyView struct {
	FreeBusyViewType   string             `xml:"FreeBusyViewType"`
	MergedFreeBusy     string             `xml:"MergedFreeBusy"`
	CalendarEventArray CalendarEventArray `xml:"CalendarEventArray"`
	WorkingHours       WorkingHours       `xml:"WorkingHours"`
}

type FreeBusyViewOptions

type FreeBusyViewOptions struct {
	TimeWindow                      TimeWindow `xml:"t:TimeWindow"`
	MergedFreeBusyIntervalInMinutes int        `xml:"t:MergedFreeBusyIntervalInMinutes,omitempty"`
	RequestedView                   string     `xml:"t:RequestedView"`
}

type GetItem added in v0.0.18

type GetItem struct {
	XMLName   struct{}   `xml:"m:GetItem"`
	ItemShape ItemShape  `xml:"m:ItemShape"`
	ItemIds   GetItemIds `xml:"m:ItemIds"`
}

GetItem represents a SOAP request for the GetItem operation. https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/getitem-operation

Зарезервирован для обратной совместимости с тестами и потребителями, рассчитывающими на синглтон-запрос. Публичная функция GetCalendarItemChangeKey теперь делегирует в batch-версию GetCalendarItemsChangeKeys (см. get_item_batch.go).

type GetItemIds added in v0.0.18

type GetItemIds struct {
	ItemId ItemId `xml:"t:ItemId"`
}

GetItemIds wraps the list of ItemId elements for a GetItem request.

type GetItemResponse added in v0.0.18

type GetItemResponse struct {
	ResponseMessages GetItemResponseMessages `xml:"ResponseMessages"`
}

GetItemResponse is the top-level body of a GetItem SOAP response.

type GetItemResponseMessage added in v0.0.18

type GetItemResponseMessage struct {
	ResponseClass ResponseClass `xml:"ResponseClass,attr"`
	MessageText   string        `xml:"MessageText"`
	ResponseCode  string        `xml:"ResponseCode"`
	Items         ResponseItems `xml:"Items"`
}

GetItemResponseMessage carries the result for a single requested item.

type GetItemResponseMessages added in v0.0.18

type GetItemResponseMessages struct {
	GetItemResponseMessage GetItemResponseMessage `xml:"GetItemResponseMessage"`
}

GetItemResponseMessages wraps the per-item response messages.

type GetPersonaRequest

type GetPersonaRequest struct {
	XMLName   struct{}  `xml:"m:GetPersona"`
	PersonaId PersonaId `xml:"m:PersonaId"`
}

type GetRoomListsRequest

type GetRoomListsRequest struct {
	XMLName struct{} `xml:"m:GetRoomLists"`
}

type GetRoomListsResponse

type GetRoomListsResponse struct {
	Response
	RoomLists RoomLists `xml:"RoomLists"`
}

func GetRoomLists

func GetRoomLists(c Client) (*GetRoomListsResponse, error)

type GetUserAvailabilityRequest

type GetUserAvailabilityRequest struct {
	XMLName             struct{}            `xml:"m:GetUserAvailabilityRequest"`
	TimeZone            TimeZone            `xml:"t:TimeZone"`
	MailboxDataArray    MailboxDataArray    `xml:"m:MailboxDataArray"`
	FreeBusyViewOptions FreeBusyViewOptions `xml:"t:FreeBusyViewOptions"`
}

type GetUserAvailabilityResponse

type GetUserAvailabilityResponse struct {
	FreeBusyResponseArray FreeBusyResponseArray `xml:"FreeBusyResponseArray"`
	SuggestionsResponse   SuggestionsResponse   `xml:"SuggestionsResponse"`
}

type GetUserPhotoRequest

type GetUserPhotoRequest struct {
	XMLName       struct{} `xml:"m:GetUserPhoto"`
	Email         string   `xml:"m:Email"`
	SizeRequested string   `xml:"m:SizeRequested"`
}

type GetUserPhotoResponse

type GetUserPhotoResponse struct {
	Response
	HasChanged  bool   `xml:"HasChanged"`
	PictureData string `xml:"PictureData"`
}

type GroupAttendeeConflictData

type GroupAttendeeConflictData struct {
	NumberOfMembers             int `xml:"NumberOfMembers"`
	NumberOfMembersAvailable    int `xml:"NumberOfMembersAvailable"`
	NumberOfMembersWithConflict int `xml:"NumberOfMembersWithConflict"`
	NumberOfMembersWithNoData   int `xml:"NumberOfMembersWithNoData"`
}

type HTTPError

type HTTPError struct {
	Status     string
	StatusCode int
}

func (HTTPError) Error

func (s HTTPError) Error() string

type IndexedPageItemView

type IndexedPageItemView struct {
	MaxEntriesReturned int       `xml:"MaxEntriesReturned,attr,omitempty"`
	Offset             int       `xml:"Offset,attr"`
	BasePoint          BasePoint `xml:"BasePoint,attr"`
}

type ItemChange added in v0.0.17

type ItemChange struct {
	XMLName struct{} `xml:"t:ItemChange"`
	ItemId  ItemId   `xml:"t:ItemId"`
	Updates Updates  `xml:"t:Updates"`
}

type ItemChanges added in v0.0.19

type ItemChanges struct {
	XMLName struct{}     `xml:"m:ItemChanges"`
	Items   []ItemChange `xml:"t:ItemChange"`
}

ItemChanges — обёртка вокруг списка ItemChange.

Когда поле parent'а имеет тег xml:"m:ItemChanges", а сам элемент слайса ItemChange несёт собственный XMLName с t:ItemChange, Go-кодер игнорирует тег слайса и рендерит каждый <t:ItemChange> напрямую под <m:UpdateItem>, пропуская обязательный элемент <m:ItemChanges>. Exchange в таком случае отвергает запрос с HTTP 500 (ErrorInvalidArgument, "The request is invalid."). Явная обёртка с собственным XMLName заставляет Go выдать корректную структуру <m:ItemChanges><t:ItemChange>...</t:ItemChange></m:ItemChanges>.

type ItemId

type ItemId struct {
	Id        string `xml:"Id,attr"`
	ChangeKey string `xml:"ChangeKey,attr,omitempty"`
}

type ItemIds added in v0.0.15

type ItemIds struct {
	ItemId DeleteItemId `xml:"t:ItemId"`
}

type ItemIdsList added in v0.0.19

type ItemIdsList struct {
	XMLName struct{} `xml:"m:ItemIds"`
	ItemId  []ItemId `xml:"t:ItemId"`
}

ItemIdsList — plural-версия ItemIds для batch-операций (Delete, Get).

Существующий ItemIds (singular) остаётся для DeleteCalendarItem(c, id) без изменений; см. spec §2.4.

type ItemShape added in v0.0.18

type ItemShape struct {
	BaseShape BaseShape `xml:"t:BaseShape"`
}

ItemShape describes the set of properties to return for items in GetItem/FindItem responses.

type Items

type Items struct {
	Message      []Message      `xml:"t:Message"`
	CalendarItem []CalendarItem `xml:"t:CalendarItem"`
}

type Mailbox

type Mailbox struct {
	EmailAddress string `xml:"t:EmailAddress"`
}

type MailboxData

type MailboxData struct {
	Email            Email        `xml:"t:Email"`
	AttendeeType     AttendeeType `xml:"t:AttendeeType"`
	ExcludeConflicts bool         `xml:"t:ExcludeConflicts"`
}

type MailboxDataArray

type MailboxDataArray struct {
	MailboxData []MailboxData `xml:"t:MailboxData"`
}

type MeetingTimeZone added in v0.0.19

type MeetingTimeZone struct {
	Name string `xml:"Name,attr,omitempty"`
}

MeetingTimeZone задаёт часовой пояс, в котором интерпретируются Start/End календарного события (Exchange 2007 SP1+).

Без этого элемента (и без пары StartTimeZone/EndTimeZone) EWS «прилипает» к полуночи в часовом поясе сервисного аккаунта (часто UTC). Для all-day событий это ломает отображение в Outlook: пользователь в MSK видит «03:00» вместо честного полного дня.

Поле Name принимает Microsoft timezone names (например "Russian Standard Time"); в этом случае Bias/StandardTime/DaylightTime можно не задавать — Exchange резолвит их по имени.

Deprecated с Exchange 2010 в пользу StartTimeZone/EndTimeZone, но продолжает работать на всех актуальных версиях Exchange.

type Message

type Message struct {
	ItemClass    string     `xml:"t:ItemClass"`
	Subject      string     `xml:"t:Subject"`
	Body         Body       `xml:"t:Body"`
	Sender       OneMailbox `xml:"t:Sender"`
	ToRecipients XMailbox   `xml:"t:ToRecipients"`
}

type MessageXml

type MessageXml struct {
	ExceptionType       string `xml:"ExceptionType"`
	ExceptionCode       string `xml:"ExceptionCode"`
	ExceptionServerName string `xml:"ExceptionServerName"`
	ExceptionMessage    string `xml:"ExceptionMessage"`
}

type MobilePhones

type MobilePhones struct {
	PhoneNumberAttributedValue PhoneNumberAttributedValue `xml:"PhoneNumberAttributedValue"`
}

type OfficeLocations

type OfficeLocations struct {
	StringAttributedValue StringAttributedValue `xml:"StringAttributedValue"`
}

type OneMailbox

type OneMailbox struct {
	Mailbox Mailbox `xml:"t:Mailbox"`
}

type ParentFolderId

type ParentFolderId struct {
	DistinguishedFolderId DistinguishedFolderId `xml:"t:DistinguishedFolderId"`
}

type People

type People struct {
	Persona []Persona `xml:"Persona"`
}

type Persona

type Persona struct {
	PersonaId            PersonaId            `xml:"PersonaId"`
	DisplayName          string               `xml:"DisplayName"`
	Title                string               `xml:"Title"`
	Department           string               `xml:"Department"`
	Departments          Departments          `xml:"Departments"`
	EmailAddress         EmailAddress         `xml:"EmailAddress"`
	RelevanceScore       int                  `xml:"RelevanceScore"`
	BusinessPhoneNumbers BusinessPhoneNumbers `xml:"BusinessPhoneNumbers"`
	MobilePhones         MobilePhones         `xml:"MobilePhones"`
	OfficeLocations      OfficeLocations      `xml:"OfficeLocations"`
}

type PersonaId

type PersonaId struct {
	Id string `xml:"Id,attr"`
}

type PersonaShape

type PersonaShape struct {
	BaseShape            BaseShape            `xml:"t:BaseShape,omitempty"`
	AdditionalProperties AdditionalProperties `xml:"t:AdditionalProperties,omitempty"`
}

type PhoneNumberAttributedValue

type PhoneNumberAttributedValue struct {
	Value Value `json:"Value"`
}

type Response

type Response struct {
	ResponseClass ResponseClass `xml:"ResponseClass,attr"`
	MessageText   string        `xml:"MessageText"`
	ResponseCode  string        `xml:"ResponseCode"`
	MessageXml    MessageXml    `xml:"MessageXml"`
	Items         ResponseItems `xml:"Items"`
}

type ResponseClass

type ResponseClass string
const (
	ResponseClassSuccess ResponseClass = "Success"
	ResponseClassWarning ResponseClass = "Warning"
	ResponseClassError   ResponseClass = "Error"
)

type ResponseItemId added in v0.0.13

type ResponseItemId struct {
	Id        string `xml:"Id,attr"`
	ChangeKey string `xml:"ChangeKey,attr"`
}

type ResponseItems added in v0.0.13

type ResponseItems struct {
	CalendarItem CalendarItemResponse `xml:"CalendarItem"`
}

type ResponseMessage

type ResponseMessage struct {
	Response
	DescriptiveLinkKey int `xml:"DescriptiveLinkKey"`
}

type ResponseMessages

type ResponseMessages struct {
	CreateItemResponseMessage Response `xml:"CreateItemResponseMessage"`
}

type RoomLists

type RoomLists struct {
	Address []EmailAddress `xml:"Address"`
}

type SavedItemFolderId

type SavedItemFolderId struct {
	DistinguishedFolderId DistinguishedFolderId `xml:"t:DistinguishedFolderId"`
}

type SetItemField added in v0.0.17

type SetItemField struct {
	FieldURI     FieldURI           `xml:"t:FieldURI"`
	CalendarItem updateCalendarItem `xml:"t:CalendarItem"`
}

type SoapError

type SoapError struct {
	Fault *Fault
}

func (SoapError) Error

func (s SoapError) Error() string

type StringAttributedValue

type StringAttributedValue struct {
	Value string `json:"Value"`
}

type Suggestion

type Suggestion struct {
	MeetingTime                 time.Time                   `xml:"MeetingTime"`
	IsWorkTime                  bool                        `xml:"IsWorkTime"`
	SuggestionQuality           string                      `xml:"SuggestionQuality"`
	ArrayOfAttendeeConflictData ArrayOfAttendeeConflictData `xml:"ArrayOfAttendeeConflictData"`
}

type SuggestionArray

type SuggestionArray struct {
	Suggestion []Suggestion `xml:"Suggestion"`
}

type SuggestionDayResult

type SuggestionDayResult struct {
	Date            time.Time       `xml:"Date"`
	DayQuality      string          `xml:"DayQuality"`
	SuggestionArray SuggestionArray `xml:"SuggestionArray"`
}

type SuggestionDayResultArray

type SuggestionDayResultArray struct {
	SuggestionDayResult []SuggestionDayResult `xml:"SuggestionDayResult"`
}

type SuggestionsResponse

type SuggestionsResponse struct {
	ResponseMessage          ResponseMessage          `xml:"ResponseMessage"`
	SuggestionDayResultArray SuggestionDayResultArray `xml:"SuggestionDayResultArray"`
}

type Time

type Time string

func (Time) ToTime

func (t Time) ToTime() (time.Time, error)

type TimeWindow

type TimeWindow struct {
	StartTime time.Time `xml:"t:StartTime"`
	EndTime   time.Time `xml:"t:EndTime"`
}

type TimeZone

type TimeZone struct {
	Bias         int          `xml:"t:Bias"`
	StandardTime TimeZoneTime `xml:"t:StandardTime"`
	DaylightTime TimeZoneTime `xml:"t:DaylightTime"`
}

type TimeZoneDefinition added in v0.0.19

type TimeZoneDefinition struct {
	Id   string `xml:"Id,attr,omitempty"`
	Name string `xml:"Name,attr,omitempty"`
}

TimeZoneDefinition — современное (Exchange 2010+) описание часового пояса для StartTimeZone/EndTimeZone. Атрибут Id принимает Microsoft timezone names (например "Russian Standard Time"). Name — человекочитаемая подпись, Exchange её не интерпретирует.

type TimeZoneTime

type TimeZoneTime struct {
	Bias      int    `xml:"t:Bias"`
	Time      string `xml:"t:Time"`
	DayOrder  int16  `xml:"t:DayOrder"`
	Month     int16  `xml:"t:Month"`
	DayOfWeek string `xml:"t:DayOfWeek"`
	Year      string `xml:"Year,omitempty"`
}

type UpdateCalendarItemInput added in v0.0.19

type UpdateCalendarItemInput struct {
	ItemID    string
	ChangeKey string
	Start     time.Time
	End       time.Time
}

UpdateCalendarItemInput — вход одной операции batch-Update.

Если ChangeKey пуст, библиотека резолвит его одним batch-запросом GetItem (GetCalendarItemsChangeKeys) для ВСЕХ элементов батча с пустым ChangeKey. Если ChangeKey заполнен вызывающей стороной —额外的 GetItem не делается.

type UpdateItem added in v0.0.17

type UpdateItem struct {
	XMLName                               struct{}    `xml:"m:UpdateItem"`
	MessageDisposition                    string      `xml:"MessageDisposition,attr"`
	SendMeetingInvitationsOrCancellations string      `xml:"SendMeetingInvitationsOrCancellations,attr"`
	ConflictResolution                    string      `xml:"ConflictResolution,attr"`
	ItemChanges                           ItemChanges `xml:"m:ItemChanges"`
}

type UpdateItemResponse added in v0.0.17

type UpdateItemResponse struct {
	ResponseMessages UpdateResponseMessages `xml:"ResponseMessages"`
}

type UpdateItemResponseMessage added in v0.0.17

type UpdateItemResponseMessage struct {
	ResponseClass ResponseClass `xml:"ResponseClass,attr"`
	MessageText   string        `xml:"MessageText"`
	ResponseCode  string        `xml:"ResponseCode"`
	Items         ResponseItems `xml:"Items"`
}

type UpdateItemResult added in v0.0.19

type UpdateItemResult struct {
	Index     int
	ItemID    string
	ChangeKey string
	Error     error
}

UpdateItemResult — результат одного элемента batch-Update.

ItemID/ChangeKey — обновлённые значения после апдейта (Exchange может менять ChangeKey при каждом успешном UpdateItem). При неудаче Error != nil, остальные поля пустые.

func UpdateCalendarItemsTime added in v0.0.19

func UpdateCalendarItemsTime(ctx context.Context, c Client, items []UpdateCalendarItemInput) ([]UpdateItemResult, error)

UpdateCalendarItemsTime обновляет время набора событий в одном SOAP-запросе.

Возвращает по одному UpdateItemResult на каждый входной элемент в том же порядке. Частичные ошибки (ResponseClass="Error" на конкретном элементе) возвращаются как Error в соответствующей позиции слайса.

ChangeKey handling:

  • если входной ChangeKey заполнен — используется как есть;
  • если пуст — библиотека резолвит ChangeKey одним batch-запросом GetItem для всех элементов с пустым ChangeKey. Если хотя бы один id не зарезолвился — весь батч отменяется (Exchange всё равно отвергнет апдейт без валидного ChangeKey).

Top-level error непусто при ошибке маршалинга, HTTP ≠ 200, превышении лимита, невозможности зарезолвить ChangeKey, пустом конверте или отмене контекста. В этих случаях []UpdateItemResult — nil.

https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/updateitem-operation

type UpdateResponseMessages added in v0.0.17

type UpdateResponseMessages struct {
	UpdateItemResponseMessage UpdateItemResponseMessage `xml:"UpdateItemResponseMessage"`
}

type Updates added in v0.0.17

type Updates struct {
	SetItem []SetItemField `xml:"t:SetItemField"`
}

type Value

type Value struct {
	Number string `json:"Number"`
	Type   string `json:"Type"`
}

type WorkingHours

type WorkingHours struct {
	TimeZone           TimeZone           `xml:"TimeZone"`
	WorkingPeriodArray WorkingPeriodArray `xml:"WorkingPeriodArray"`
}

type WorkingPeriod

type WorkingPeriod struct {
	DayOfWeek          string `xml:"DayOfWeek"`
	StartTimeInMinutes int    `xml:"StartTimeInMinutes"`
	EndTimeInMinutes   int    `xml:"EndTimeInMinutes"`
}

type WorkingPeriodArray

type WorkingPeriodArray struct {
	WorkingPeriod []WorkingPeriod `xml:"WorkingPeriod"`
}

type XMailbox

type XMailbox struct {
	Mailbox []Mailbox `xml:"t:Mailbox"`
}

Directories

Path Synopsis
Utility package to contain functions like sendMail, create Calendar appointment and get user availability
Utility package to contain functions like sendMail, create Calendar appointment and get user availability

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL