Sincronizando eventos entre contas do Outlook usando Python

Rafael Sermenho
GDG Campinas
Published in
3 min readNov 20, 2017

--

Olá pessoal! Neste texto eu vou demonstrar uma forma de criar um script em Python para sincronizar eventos entre duas contas do Outlook usando a lib PyExchange.

O código completo pode ser baixado aqui.

A primeira coisa a ser feita é instalar o PyExchange e para isso vamos utilizar o pip:

pip install pyexchange

O próximo passo é começar o script importando os módulos que serão necessários:

from datetime import datetime
from pytz import timezone
from pyexchange import Exchange2010Service, ExchangeNTLMAuthConnection

Então, devemos configurar os dados da conta de origem:

originURL = u'https://nomeDoServidor.outlook.com/EWS/Exchange.asmx'
originUsername = u'nomeDoUsuario'
originPassword = u"passwordDoUsuario"

Note que na URL sempre devemos incluir o sufixo “/EWS/Exchange.asmx”.

Após definir os dados da conta, podemos configurar a conexão e iniciar o serviço usando a lib PyExchange:

originConnection = ExchangeNTLMAuthConnection(url=originURL, username=originUsername, password=originPassword)
originService = Exchange2010Service(originConnection)

Com o serviço instanciado, só falta obter uma instância do calendário e listar todos os eventos, conforme nosso filtro:

originCalendar = originService.calendar()originEvents = originCalendar.list_events(
start=timezone("America/Sao_Paulo").localize(datetime(2017, 11, 1, 0, 0, 0)),
end=timezone("America/Sao_Paulo").localize(datetime(2017, 11, 17, 0, 0, 0)),
details=True
)

No exemplo acima, estou listando todos os eventos entre 01/11/2017 e 17/11/2017 no timezone de São Paulo.

Dando continuidade, criei uma classe chamada Event para armazenar os dados dos nossos eventos. Não se esqueça de adicionar a linha abaixo no início para importar a classe:

from Event import Event

Note que na classe Event foi preciso implementar o método __eq__ para verificarmos se os eventos são iguais:

class Event:
def __init__(self, start, end, subject, location, html_body, text_body, attendees, required_attendees, optional_attendees, recurrence, recurrence_interval, recurrence_end_date, recurrence_days):
self.start = start
self.end = end
self.subject = subject
self.location = location
self.html_body = html_body
self.text_body = text_body
self.attendees = attendees
self.required_attendees = required_attendees
self.optional_attendees = optional_attendees
self.recurrence = recurrence
self.recurrence_interval = recurrence_interval
self.recurrence_end_date = recurrence_end_date
self.recurrence_days = recurrence_days

def __eq__(self, other):
return self.start == other.start and self.end == other.end \
and self.subject == other.subject and self.location == other.location \
and self.html_body == other.html_body and self.text_body == other.text_body \
and self.attendees == other.attendees and self.required_attendees == other.required_attendees \
and self.optional_attendees == other.optional_attendees and self.recurrence == other.recurrence \
and self.recurrence_interval == other.recurrence_interval and self.recurrence_end_date == other.recurrence_end_date \
and self.recurrence_days == other.recurrence_days

O código abaixo cria uma lista de eventos e imprime no console algumas informações sobre os itens inseridos:

originList = list()
for originEvent in originEvents.events:
event = Event(originEvent.start, originEvent.end, originEvent.subject, originEvent.location, originEvent.html_body, originEvent.text_body, originEvent.attendees, originEvent.required_attendees, originEvent.optional_attendees, originEvent.recurrence, originEvent.recurrence_interval, originEvent.recurrence_end_date, originEvent.recurrence_days)
originList.append(event);
print "{start} {end} - {subject}".format(
start=originEvent.start,
end=originEvent.end,
subject=originEvent.subject
)

Agora que já temos os eventos da primeira conta do Outlook, vamos pegar os eventos da segunda conta da mesma forma:

destinyURL = u'https://outroServidor.outlook.com/EWS/Exchange.asmx'
destinyUsername = u'nomeUsuario'
originPassword = u'passwordUsuario'
# Set up the connection to Exchange
destinyConnection = ExchangeNTLMAuthConnection(url=destinyURL,
username=destinyUsername,
password=originPassword)
destinyService = Exchange2010Service(destinyConnection)destinyCalendar = destinyService.calendar()destinyEvents = destinyCalendar.list_events(
start=timezone("America/Sao_Paulo").localize(datetime(2017, 11, 1, 0, 0, 0)),
end=timezone("America/Sao_Paulo").localize(datetime(2017, 11, 17, 0, 0, 0)),
details=True
)
destinyList = list()
for destinyEvent in destinyEvents.events:
event = Event(destinyEvent.start, destinyEvent.end, destinyEvent.subject, destinyEvent.location, destinyEvent.html_body, destinyEvent.text_body, destinyEvent.attendees, destinyEvent.required_attendees, destinyEvent.optional_attendees, destinyEvent.recurrence, destinyEvent.recurrence_interval, destinyEvent.recurrence_end_date, destinyEvent.recurrence_days)
destinyList.append(event);
print "{start} {end} - {subject}".format(
start=destinyEvent.start,
end=destinyEvent.end,
subject=destinyEvent.subject
)

Com as duas listas de eventos prontas, como faço para saber quais eventos devo incluir? A forma que eu encontrei foi a seguinte:

Iterar a lista de origem e para cada ocorrência verificar se o evento está na lista de destino. Caso não esteja, basta usar os métodos da PyExchange para criar o evento:

for event in originList:
if event not in destinyList:
event = destinyService.calendar().new_event(
subject=originEvent.subject,
start=originEvent.start,
end=originEvent.end,
location=originEvent.location,
html_body = originEvent.html_body,
text_body = originEvent.text_body,
recurrence = originEvent.recurrence,
recurrence_interval = originEvent.recurrence_interval,
recurrence_end_date = originEvent.recurrence_end_date,
recurrence_days = originEvent.recurrence_days
)
event.create()

O mesmo procedimento deve ser feito para incluirmos os eventos da lista de destino na lista de origem:

event = originService.calendar().new_event(
subject=destinyEvent.subject,
start=destinyEvent.start,
end=destinyEvent.end,
location=destinyEvent.location,
html_body = destinyEvent.html_body,
text_body = destinyEvent.text_body,
recurrence = destinyEvent.recurrence,
recurrence_interval = destinyEvent.recurrence_interval,
recurrence_end_date = destinyEvent.recurrence_end_date,
recurrence_days = destinyEvent.recurrence_days
)
event.create()

Pronto! Dessa forma nossa agenda de eventos está sincronizada entre duas contas do Outlook.

Se você tiver alguma sugestão de melhoria, deixe seu comentário e vamos trocar uma ideia a respeito.

--

--