Como ler e-mails do Exchange Server - um tutorial Python usando o Connect Bridge

Ana Neto Notícias da empresa, Conectores, Técnico Deixe um Comentário

"Necessidade de conectar your Python script to an Exchange servidor? Vamos mostrar-lhe uma forma fácil de o fazer, utilizando uma ferramenta chamada Connect Bridge".

Introdução

Este artigo descreve como fazer o Python se conectar ao Exchange, ou seja, como ler e-mails de um servidor Microsoft Exchange (Exchange 2010, 2013, 2016, 2019, Online) usando um script em linguagem Python.

As transferências de dados são feitas através da camada ODBC, portanto do lado do script é exatamente o mesmo que se você estivesse usando python para acessar o Microsoft SQL Server ou para acessar qualquer banco de dados via ODBC. Você simplesmente usa a função módulo de pyodbc (usamos python versão 3.7 e pyodbc versão 4.0.26.). A integração real da API é feita por uma ferramenta chamada Connect Bridge e depois no seu script Python você lê os dados como se estivesse lendo uma base de dados.

Por favor note que o Connect Bridge é um produto comercial. Você pode iniciar um período de teste gratuito para isso, por isso pode tentar esta abordagem por si mesmo sem nenhum custo.

O que é este "Connect Bridge"?

Connect Bridge é uma plataforma de integração desenvolvida pelo Connecting Software. Permite que seu script conecte qualquer software através de drivers ODBC, drivers JDBC ou Web Services...evitando a necessidade de estudar e aprender a API do programa ao qual você está tentando se conectar!

Neste artigo específico estamos usando o Connect Bridge para nos conectarmos ao Microsoft Exchange mas você também pode obter dados do Microsoft SharePoint ou de um CRM como Salesforce ou Dynamics entre muitos outros. E as transferências de dados podem realmente ser bidirecionais. Ou seja, você também pode colocar dados nesses sistemas, embora desta vez estejamos focados na leitura de dados.

Por onde eu começo?

Nosso objetivo é criar um script Python simples que acesse um servidor Exchange e leia e-mails a partir dele. Assumimos que a instância do Exchange já existe. Estes são passos simples que você precisa seguir:

1. Certifique-se de ter as suas credenciais de login Exchange em mãos

2. Solicite um teste gratuito e instale o Connect Bridge

3. Instalar o Python para Windows ver. 3.7+. Você pode usar o editor de sua escolha para escrever o script.

4. Instalar módulo pyodbc 4.0.26+

5. Execute o Connect Bridge Management Studio e:

5.1. Adicionar uma conta para Exchange (Contas - Adicionar conta). Para adicionar a conta, você deve selecionar o conector MGEXPlugin2010 e usar as credenciais mencionadas no ponto 1.

5.2. Abra a opção Nova Consulta e depois o Navegador de Conexão. Encontre o Conector Exchange e expanda-o até ver o DefaultConnection. Clique com o botão direito do mouse na opção DefaultConnection e escolha Get Connection string. Copie a string de conexão ODBC, pois você vai precisar dela para passá-la para o script.

5.3. Use a opção Nova Consulta para testar uma consulta que irá acessar o que você precisa no Exchange.

Vamos fazer uma consulta de exemplo aqui, mas é aqui que deve colocar o que procura no Exchange. Depois de clicar em Nova Consulta, abra o Navegador de Conexão, à esquerda. Encontre o Conector Exchange (MGEXPlugin2010) e abra até que a opção Tabelas esteja visível. Podemos ver que o esquema contém uma "tabela" chamada Mensagem para que possamos construir nossa consulta como SELECT * FROM Message WHERE CreationDate >= '2019-01-01 00:00:00' LIMIT 10; para selecionar 10 entradas da lista de mensagens de e-mail do Exchange que foram criadas depois de 1 de janeiro de 2019. Novamente, note que embora pareça que estamos usando uma base de dados diretamente, esse não é o caso. O Connect Bridge está acessando a API e depois apresentando-a como se fosse uma base de dados. Uma vez que você tenha sua consulta, copie-a, pois você precisará passá-la para o script.

Finalmente o script de Python!

A nossa solução só tem um ficheiro: CBExchange.py. O código fonte completo está abaixo. Por favor, concentre-se nas linhas 70-92 que retratam a solução principal. Uma descrição completa de como este script funciona está abaixo.

#!/usr/local/bin/python3.7 

# encoding: utf-8 

''' 

CBExchange -- query data from, write data to Exchange 

  

CBExchange is a script that allows to read Exchange mail using SQL queries via Connect Bridge's ODBC driver 

  

@author:    Ana Neto  

  

@copyright:  2019 

  

@contact:    ana@connecting-software.com 

@deffield    updated: 22.07.2019 

''' 

  

import sys 

import os 

import pyodbc 

  

from argparse import ArgumentParser 

from argparse import RawDescriptionHelpFormatter 

  

__all__ = [] 

__version__ = 0.2 

__date__ = '2019-07-22' 

__updated__ = '2019-07-22' 

  

DEBUG = 1 

TESTRUN = 0 

PROFILE = 0 

  

class CLIError(Exception): 

    '''Generic exception to raise and log different fatal errors.''' 

    def __init__(self, msg): 

        super(CLIError).__init__(type(self)) 

        self.msg = "E: %s" % msg 

    def __str__(self): 

        return self.msg 

    def __unicode__(self): 

        return self.msg 

  

def main(argv=None): # IGNORE:C0111 

    '''Command line options.''' 

  

    if argv is None: 

        argv = sys.argv 

    else: 

        sys.argv.extend(argv) 

  

    program_name = os.path.basename(sys.argv[0]) 

    program_version = "v%s" % __version__ 

    program_build_date = str(__updated__) 

    program_version_message = '%%(prog)s %s (%s)' % (program_version, program_build_date) 

    program_shortdesc = __import__('__main__').__doc__.split("n")[1] 

    program_license = '''%s 

  

  Created by Ana Neto on %s. 

  

  Licensed under the Apache License 2.0 

  http://www.apache.org/licenses/LICENSE-2.0 

  

  Distributed on an "AS IS" basis without warranties 

  or conditions of any kind, either express or implied. 

  

USAGE 

''' % (program_shortdesc, str(__date__)) 

  

    try: 

        # Setup argument parser 

        parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter) 

        parser.add_argument('connstr')         

        parser.add_argument('query') 

         

        # Process arguments 

        args = parser.parse_args() 

  

        query = args.query 

        connstr = args.connstr 

  

        conn = pyodbc.connect(connstr) 

        cursor = conn.cursor() 

        cursor.execute(query) 

        while 1: 

            row = None 

            try: 

                row = cursor.fetchone() 

            except:  

                print(sys.exc_info()[1]) 

                break 

            if not row: 

                break                     

            print(row) 

                         

             

    except KeyboardInterrupt: 

        ### handle keyboard interrupt ### 

        return 0 

    except: 

        print(sys.exc_info()[1]) 

        #indent = len(program_name) * " "         

        #sys.stderr.write(program_name + ": " + repr(e) + "n") 

        #sys.stderr.write(indent + "  for help use --help") 

        return 2 

  

if __name__ == "__main__": 

          

    if TESTRUN: 

        import doctest 

        doctest.testmod() 

    if PROFILE: 

        import cProfile 

        import pstats 

        profile_filename = 'CBExchange_profile.txt' 

        cProfile.run('main()', profile_filename) 

        statsfile = open("profile_stats.txt", "wb") 

        p = pstats.Stats(profile_filename, stream=statsfile) 

        stats = p.strip_dirs().sort_stats('cumulative') 

        stats.print_stats() 

        statsfile.close() 

        sys.exit(0) 

    sys.exit(main()) 

Aqui está um pouco sobre as variáveis que estamos a usar:

- O parser é usado para analisar os argumentos que obtemos da linha de comando

- args sustenta esses argumentos

- A consulta contém a consulta que queremos executar e que entra como argumento

- connstr detém a string de conexão ODBC que entra como argumento e que passamos para o módulo pyodbc para criar uma conexão ODBC

- conn é a ligação ODBC

E aqui está o que o nosso guião está a fazer.

- Nas linhas 70 a 78, o objetivo é obter as variáveis connstr e query a partir da entrada de argumentos da linha de comando. O modelo de script argparse do pydev foi usado para simplificar

- Na linha 80, abrimos um cursor de banco de dados usando o conn

- Na linha 82, nós executamos a consulta SQL que obtivemos da linha de comando

- Nas linhas 83 a 92, fazemos um laço através dos resultados e os lemos linha a linha a partir do cursor.

-Quando cursor.fetchone retorna Nenhum, nós quebramos o laço

- Se ocorrer uma exceção durante o fetch ODBC, também quebramos o ciclo e mostramos um erro no output

- Se o método fetchone tiver sucesso e retornar uma linha de dados, nós imprimimos a linha de dados brutos como ela é para a saída. Isto é feito porque é suficiente para fins de demonstração, mas naturalmente numa situação real você poderia formatar como xml, json, csv... ou qualquer outro tipo de formato de troca de dados. Ou você também poderia simplesmente usar o objeto de linha de dados brutos para realizar tarefas personalizadas em código subseqüente.

Como eu executo o script CBExchange.py?

O script CBExchange.py aceita dois argumentos de linha de comando posicionais: connstr e query.

Precisamos copiá-los do Connect Bridge Management Studio como explicado acima (ponto 5.2). Quando os tiver em mãos, abra uma linha de comando, cd para a pasta onde guardou o script e executar o seu script Python passando-lhe os 2 parâmetros.

O que mais posso fazer? Explorar mais...

Como mencionado anteriormente, consultas mais sofisticadas podem ser construídas para que você esteja recebendo os e-mails que deseja. Por exemplo, se você quiser receber os e-mails apenas com anexos e com uma data de criação específica, a consulta seria

SELECCIONAR * DA MENSAGEM

ONDE [HasAttachment] = true e [CreationDate] >= '2019-07-01 00:00:00:00';

Você também pode explorar os "Procedimentos Armazenados" disponíveis. Encontre o conector Exchange (MGEXPlugin2010) e expanda até que você possa ver a opção "Stored Procedures". Mais uma vez, estes Procedimentos Armazenados são a integração API do Connect Bridge, não procedimentos reais armazenados na base de dados. Mas a forma de trabalhar com eles é a mesma como se fossem.

Alguns dos Procedimentos Armazenados disponíveis são visíveis nesta captura de tela:

Você pode dar uma olhada no SP_SELECT_DEFAULT_FOLDER_INBOX para um procedimento simples de armazenamento (sem parâmetro obrigatório) ou SP_SEND_MESSAGE para um procedimento um pouco mais complicado.

Restrições

A ferramenta Connect Bridge só está disponível para sistemas operacionais Windows, porque não há uma biblioteca cliente ODBC Linux disponível. Portanto, para que isto funcione, você precisará de uma máquina Windows.

Conclusão

Vimos como acessar dados do Exchange em Python pode ser facilmente feito usando a plataforma de integração do Connect Bridge. Agora imagine que o que você viu neste artigo é possível também com Microsoft Dynamics CRM e Microsoft Exchange! Sim, com o Connect Bridge isto é possível e a forma de o fazer é semelhante... só precisa de escolher o conector para o software específico que pretende e ir com ele.

Se você quiser explorar os conectores atualmente disponíveis no Connect Bridge, o lugar para ir é https://www.connecting-software.com/connect-bridge-connectors/

Se você está curioso sobre quais são os novos conectores deste grande conjunto, dê uma olhada no Connect Bridge's Dynamics 365 Finanças e Operações e Dynamics 365 Central de Negócios conectores, ambos construídos sobre o Protocolo OData. Ou dê uma olhada no conector OPC UA. Sim, eu sei que isso parece ser um caso de uso totalmente diferente.... Mas a verdade é que você pode acessar os servidores OPC UA usando a mesma ferramenta. Só para lhe dar uma ideia do que pode resultar deste tipo de integração, dê uma olhada no Connect Bridge's mostruário do IIoT.

Esperamos que este artigo tenha sido útil para você! Aqui estão mais alguns posts que temos no nosso blog discutindo outras possibilidades de integração:

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *