Microsoft Office

Explorando a API JavaScript para Office: aplicativos de email

Angela Chu-Hatoun

Baixar o código de exemplo

Este artigo é a quarta parte de uma visão detalhada da API JavaScript para Office, com enfoque na parte da API disponível para aplicativos de email com suporte do Outlook e Outlook Web App. Presumo que você tenha uma compreensão geral de aplicativos do Office. Em caso de dúvida, ler a página de documentação do Centro de Desenvolvimento “Visão geral dos Aplicativos para Office” (bit.ly/12nBWHG) irá colocá-lo no caminho certo. A parte 1 desta série, “Explorando a nova API JavaScript para Office” (msdn.microsoft.com/magazine/jj891051), fornece uma visão geral de alto nível do modelo de objeto, que tem o objeto Office como objeto raiz. O objeto Mailbox, contido no Office.context, oferece um ponto de entrada para a maioria das funcionalidades específicas do aplicativo no modelo de objeto, e é nessa parte que continuarei a discussão.

A mensagem principal deste artigo é o que você, como desenvolvedor, pode fazer com a API JavaScript para Office em aplicativos de email. Também forneci um artigo complementar online no qual analiso um aplicativo de email de exemplo, completo com o código-fonte, em msdn.microsoft.com/magazine/dn205107. Agora, discutirei vários recursos da API JavaScript para Office, passando de técnicas mais básicas e usadas normalmente para conceitos mais avançados.

Recursos fundamentais da API JavaScript para Office

O objeto Mailbox fornece acesso ao perfil de usuário, ao item selecionado atualmente pelo usuário, aos formulários para exibir o item e a um subconjunto de EWS (Serviços Web do Exchange) para manipular itens e pastas na caixa de correio. O objeto Item representa a mensagem selecionada ou o item de compromisso. Por meio desse objeto, você pode obter acesso a outras propriedades internas, propriedades personalizadas e anexos desse item.

Controlando a ativação baseada no tipo de item Você pode definir regras no manifesto para determinar quando ativar um aplicativo de email. O item selecionado atualmente pelo usuário e especificado pelo Mailbox.item pode ser um objeto Message (incluindo solicitações de reunião, respostas à solicitação de reunião e cancelamentos de reunião) ou Appointment. Dependendo de seu cenário, você pode restringir o aplicativo de email para ativar apenas para um tipo específico de item. O exemplo XML a seguir mostra uma regra de ativação ItemIs que restringe o aplicativo de email para ativar apenas para mensagens:

 

<Rule xsi:type="ItemIs" ItemType="Message" />

Usando a API JavaScript para Office, você pode usar a propriedade itemType para verificar o tipo do item selecionado:

 

Office.context.mailbox.item.itemType

Acesso e propriedades do item Uma função básica oferecida por aplicativos de email é acessar o item selecionado atualmente e suas propriedades internas.

O exemplo JavaScript a seguir mostra como acessar o item selecionado e sua propriedade interna, subject:

 

// The initialize function is required for all apps.
Office.initialize = function () {
  // Check for the DOM to load.
  $(document).ready(function () {
    var item = Office.context.mailbox.item;
    var subject = item.subject;
    // Continue processing the subject.
  });
}

Entidades conhecidas O Exchange Server reconhece determinadas entidades que ficam disponíveis independentemente se você tiver usado entidades para ativar o aplicativo de email. O Outlook e o Outlook Web App extraem essas entidades se elas existirem no assunto ou no corpo do item selecionado e as disponibilizam por meios dos métodos da API JavaScript a seguir:

  • método getEntities
  • método getEntitiesByType(entityType)
  • método getFilteredEntitiesByName(name)

As entidades com suporte incluem endereço, contato, endereço de email e muito mais.

Observe que o Outlook e o Outlook Web Apps extraem cadeias de caracteres apenas em inglês, independentemente da localidade padrão que você especificar no manifesto do aplicativo. Eles não podem extrair entidades na pasta Itens Enviados. Além disso, podem extrair sugestões de reunião em mensagens, mas não em compromissos.

Obtendo correspondências que resultam em ativação contextual Você pode especificar regras de ativação que dependem de correspondências de expressões regulares (regras ItemHasRegularExpressionMatch) ou de correspondências de entidades (regras ItemHasKnownEntity) no item selecionado. É possível usar os métodos a seguir para obter correspondências de expressões regulares. Estes métodos estão disponíveis no objeto pai Item, que pode ser uma mensagem ou um compromisso:

  • método getRegExMatches
  • método getRegExMatchesByName(name)

Você pode usar os métodos listados na seção Entidades conhecidas para obter correspondências de entidades específicas. Observe que você sempre pode usar esses métodos para obter quaisquer correspondências de entidades, independentemente do tipo de regra de ativação que usar para o aplicativo de email.

Exemplos A seguir, há um exemplo de uma regra ItemHasRegularExpressionMatch, nomeada VideoURL, que ativa o aplicativo de email se o item selecionado for uma mensagem e o corpo da mensagem contiver uma URL para um vídeo no YouTube:

 

<Rule xsi:type="RuleCollection" Mode="And">
  <Rule xsi:type="ItemIs" ItemType="Message"/>
  <Rule xsi:type="ItemHasRegularExpressionMatch"
    RegExName="VideoURL"
    RegExValue="http://www\.youtube\.com/watch\?v=[a-zA-Z0-9_-]{11}"
    PropertyName="Body"/>
</Rule>

O exemplo de código JavaScript a seguir mostra como usar o método Item.getRegExMatches para obter as correspondências da expressão regular VideoURL anterior:

 

Office.initialize = function () {
  // Check for the DOM to load.
  $(document).ready(function () {
    // Get an array of string matches for the regular expression VideoURL,
    // as specified in the manifest.
    var matches = Office.context.mailbox.item.getRegExMatches().VideoURL;
    // Continue processing the matches for the regular expression.
    });
}

A seguir, há um exemplo de uma regra ItemHasKnownEntity que ativa o aplicativo de email se um endereço estiver presente no assunto ou no corpo de uma mensagem:

<Rule xsi:type="RuleCollection" Mode="And">
  <Rule xsi:type="ItemIs" ItemType="Message"/>
  <Rule xsi:type="ItemHasKnownEntity" EntityType="Address" />
</Rule>

O exemplo de código JavaScript a seguir mostra como usar o método getEntitiesByType para obter uma matriz de cadeias de caracteres que são endereços postais no assunto ou no corpo da mensagem selecionada atualmente:

Office.initialize = function () {
  // Check for the DOM to load.
  $(document).ready(function () {
    var item = Office.context.mailbox.item;
    // Get an array of strings that represent postal
    // addresses in the current item.
    var addresses = item.getEntitiesByType(
      Office.MailboxEnums.EntityType.Address);
    // Continue processing the array of addresses.
  });
}

A ativação de um aplicativo de email baseada em contextos — principalmente correspondências de expressões regulares ou a existência de entidades conhecidas — é potente e pode ser complicada de depurar. Consulte o artigo da Biblioteca MSDN “Solucionando problemas de ativação de aplicativos de email”, em bit.ly/11C0H30 para encontrar dicas de como depurar problemas de ativação.

Armazenamento de dados por item e por aplicativo O objeto CustomProperties permite armazenar dados específicos de item que apenas seu aplicativo de email pode acessar como uma propriedade personalizada no item em uma sessão subsequente. Esses dados são representados como pares chave-valor. Se o aplicativo tiver sido criado para ser executado em vários clientes Outlook e fatores forma, as propriedades personalizadas serão carregadas com o cliente Outlook e fator forma com suporte.

As propriedades personalizadas de um item ficam disponíveis pelo método Item.loadCustomPropertiesAysnc. Esse é um método assíncrono que usa um método de retorno de chamada com parâmetro. Quando as propriedades personalizadas são carregadas, ficam disponíveis pela propriedade asyncResult.value, que é transmitida para o método de retorno de chamada como um parâmetro de entrada. A Figura 1 mostra como carregar, obter, definir e salvar propriedades personalizadas para o item atual.

Figura 1 Trabalhando com propriedades personalizadas para o item atual

Office.initialize = function () {
  var mailbox = Office.context.mailbox;
  mailbox.item.loadCustomPropertiesAsync(customPropsCallback);
}
function customPropsCallback(asyncResult) {
  if (asyncResult.status == Office.AsyncResultStatus.Succeeded) {
    var customProps = asyncResult.value;
    var myProp = customProps.get("myProp");
    customProps.set("otherProp", "value");
    customProps.saveAsync(saveCallback);
  }
  else {
    write (asyncResult.error.message);
  }
}
function saveCallback(asyncResult) {
  // Callback method to save custom properties.
}

Armazenamento de dados por caixa de correio e por aplicativo O objeto RoamingSettings permite armazenar dados personalizados que seu aplicativo de email pode acessar para a mesma caixa de correio, independentemente se o aplicativo de email estiver em execução em um desktop, tablet ou smartphone. O exemplo JavaScript a seguir mostra como obter dados específicos de caixa de correio no manipulador de eventos initialize do aplicativo de email:

var _mailbox;
var _settings;
Office.initialize = function () {
  // Check for the DOM to load using the jQuery ready function.
  $(document).ready(function () {
    // Initialize instance variables to access API objects.
    _mailbox = Office.context.mailbox;
    _settings = Office.context.roamingSettings;
    // Continue with app-specific code.
  });
}

Perfil de usuário Você pode acessar o perfil do usuário usando a propriedade Office.context.mailbox.userProfile. Por meio do objeto UserProfile, você pode obter o nome de exibição, o endereço SMTP e o fuso horário local do usuário conectado. O exemplo de código JavaScript a seguir mostra como acessar a propriedade UserProfile.emailAddress do usuário atual conectado ao Outlook ou ao Outlook Web App:

Office.initialize = function () {
  // Check for the DOM to load.
  $(document).ready(function () {
    var userProfile = Office.context.mailbox.userProfile;
    var SMTPAddress = userProfile.emailAddress;
    // Continue with processing the user's SMTP address. 
  });
}

Exibindo formulários do Outlook No Outlook, um usuário pode especificar formulários para exibir compromissos e mensagens por padrão. Usando os métodos a seguir na API JavaScript para Office, um aplicativo de email pode exibir um compromisso e uma mensagem, respectivamente, usando os mesmos formulários que o Outlook usa:

  • Mailbox.displayAppointmentForm(itemId)
  • Mailbox.displayMessageForm(itemId)

O código na Figura 2 verifica se o usuário selecionou um compromisso e o exibe com o formulário de compromissos padrão do Outlook.

Figura 2 Verificando se o usuário selecionou um compromisso

var myOm;
var myItem;
Office.initialize = function () {
  $(document).ready(function () {
    myOm = Office.context.mailbox;
    // Get the selected item.
    myItem = myOm.item;
    // Display the selected appointment.
    displaySelectedAppointment();
  });
}
function displaySelectedAppointment() {
  // Display selected item only if the item is an appointment.
  if (myitem.itemType == Office.MailboxEnums.ItemType.Appointment)
  {
    myOm.displayAppointmentForm(myItem.itemId);
  }
  else
  {
    // Handle condition as appropriate.
  }
}

O método Mailbox.displayNewAppointmentForm permite atribuir valores a determinados campos em um formulário de compromissos para uma nova reunião e exibir o formulário para que o usuário preencha o compromisso. Ao chamar esse método, especifique esses campos como uma lista de pares cadeia de caracteres-valor, como mostra a Figura 3.

Figura 3 Atribuindo valores a campos específicos em um novo formulário de compromissos

var myOm;
Office.initialize = function () {
  $(document).ready(function () {
    myOm = Office.context.mailbox;
    // After the DOM is loaded, can display the
    // pre-populated new appointment form.
    displayFormForNewAppointment();
  });
}
function displayFormForNewAppointment(){
  var formParameters =
  {
    "requiredAttendees" : ["wendy@contoso.com", "derek@contoso.com"],
    "optionalAttendees" : ["shane@contoso.com", "michael@contoso.com"],
    "start" : new Date("September 27, 2012 11:15:00"),
    "end" : new Date("("September 27, 2012 12:30:00"),
    "location" : "Conf room 200",
    "resources" : ['sound', 'lighting', 'recording'],
    "subject" : "Next rehearsal",
    "body" : "This is about the next rehearsal."
  }
  // Display a form to create an appointment with
  // the specified fields in the form.
  myOm.displayNewAppointmentForm(formParameters);
}

Os métodos que exibem formulários de resposta para um compromisso ou uma mensagem oferecem a maior possibilidade de personalização:

  • método Appointment.displayReplyAllForm(htmlBody)
  • método Appointment.displayReplyForm(htmlBody)
  • método Message.displayReplyAllForm(htmlBody)
  • método Message.displayReplyForm(htmlBody)

Com cada um desses métodos, você pode fornecer uma cadeia de caracteres HTML que representa o corpo do formulário de resposta. O exemplo na Figura 4 exibe um formulário de responder a todos para uma mensagem.

Figura 4 Especificando o HTML para um formulário de responder a todos para um item de mensagem

var myOm;
var myItem;
Office.initialize = function () {
  // Check for the DOM to load.
  $(document).ready(function () {
    myOm = Office.context.mailbox;
    // Get the selected item.
    myItem = myOm.item;
    // After the DOM is loaded, display
    // the reply form.
    displayReply();
  });
}
function displayReply(){
  // Display a reply form to the sender and recipients only
  // if the selected item is a message.
  if (myitem.itemType == Office.MailboxEnums.ItemType.Message) {
      myItem.displayReplyAllForm
      ("<html><head><head><body>This is the body of " +
       "the email reply.</body></html>");
  }
}

 

Conceitos avançados

Obtendo anexos de item Um aplicativo de email pode usar a API JavaScript para Office e os tokens de retorno de chamada do EWS para acessar os anexos da mensagem ou compromisso selecionado atualmente na caixa de correio do usuário. O uso do token de retorno de chamada permite que o código de back-end e do servidor do aplicativo de email — ou serviços Web de terceiros — chame a operação do EWS, GetAttachment, para realmente obter os anexos específicos.

A seguir, há a descrição de como um aplicativo de email obtém anexos (esse processo também é mostrado na Figura 5):

  1. Um aplicativo de email usa Mailbox.getCallbackTokenAsync para solicitar um token de retorno de chamada, usa Item.attachments para obter os metadados sobre os anexos da mensagem ou compromisso selecionado (incluindo IDs dos anexos) e usa Mailbox.ewsUrl para obter a URL do ponto de extremidade do EWS para a conta de email atual.
  2. O aplicativo de email transmite o token de retorno de chamada, as IDs dos anexos e a URL do ponto de extremidade do EWS para o código do servidor.
  3. O código do servidor chama a operação GetAttachment do EWS para obter os anexos reais desse repositório do Exchange.

Aplicativos de email acessando anexos de um servidor Exchange
Figura 5 Aplicativos de email acessando anexos de um servidor Exchange

Observe que o código do servidor deve acessar o EWS criando diretamente solicitações do EWS. Você não pode usar o método Mailbox.makeEws­RequestAsync para acessar a operação GetAttachment. No momento da elaboração deste artigo, o acesso a anexos tem suporte se o aplicativo de email for executado no Outlook Web App. O recurso não fica disponível se o aplicativo de email estiver em execução no Outlook.

Veja o exemplo de código do MSDN, “Aplicativos de email para Office: obter anexos de um servidor Exchange” (bit.ly/11dG9fS), para encontrar um exemplo de como acessar anexos em um aplicativo de email.

Token do usuário para logon único Seu aplicativo de email pode usar técnicas Web de autenticação comuns para autenticar e autorizar usuários. Caso deseje oferecer suporte à autenticação de logon único para seus usuários no Outlook e no Outlook Web App, você pode usar tokens de identidade do Exchange chamando o método Mailbox.getUserIdentityTokenAsync.

O logon único tem como base um servidor Exchange que atribui um token de identidade do Exchange para a conta de email do usuário nesse servidor Exchange. Um token de identidade do Exchange contém vários campos, entre os quais há uma assinatura para validar o token e um identificador exclusivo que representa a conta de email do Exchange.

Em geral, um aplicativo de email que autentica usuários pode interagir com um serviço Web — que pode ser um código do servidor para o aplicativo de email — ou um serviço Web de terceiros, que usa seu próprio IdP (Provedor de Identidade) para validar a identidade do usuário em um sistema de identidade federada. A chave para o logon único é o mapeamento que o serviço Web mantém entre a ID exclusiva (no token de identidade do Exchange) e a identidade do usuário (que é conhecida para o IdP).

A Figura 6 fornece uma descrição de alto nível do uso de tokens de identidade do Exchange para autenticação.

Os itens abaixo resumem o processo:

  1. O aplicativo de email chama Mailbox.getUserIdentityTokenAsync para solicitar um token de identidade do Exchange para o usuário, especificando um método de retorno de chamada que é executado quando a operação get assíncrona é concluída.
  2. A função de retorno de chamada obtém o token de identidade do Exchange e o transmite para o serviço Web para autenticação.
  3. O serviço Web obtém uma chave pública do servidor Exchange para validar o token.
  4. Se o usuário tiver entrado antes, o serviço Web executa as seguintes ações:
    1. Se for a primeira vez que o usuário entra no aplicativo de email, nenhum mapeamento anterior existe para essa conta, e o serviço Web responde ao aplicativo de email para solicitar as credenciais do usuário. Após receber as credenciais, o aplicativo de email as transmite para o serviço Web.
    2. Em seguida, o serviço cria um mapeamento entre a ID exclusiva fornecida pelo token e a identidade do usuário por meio das credenciais que são conhecidas para o IdP. Usando as credenciais, o serviço pode fazer logon do usuário:
    3. Nas próximas vezes: Quando o usuário abre o aplicativo de email no Outlook ou no Outlook Web App em um computador, tablet ou navegador de um smartphone, as seguintes etapas ocorrem:
      1. O aplicativo de email chama getUserIdentityTokenAsync e obtém a mesma ID exclusiva no token.
      2. O aplicativo de email transmite o token para o serviço Web.
      3. O serviço Web valida o token.
      4. Em seguida, o serviço Web pesquisa a tabela de mapeamento, encontra o usuário e autoriza o acesso.

Authentication Using Exchange Identity TokensFigura 6 Autenticação usando tokens de identidade do Exchange

Depois de validar o token, é possível manter o usuário conectado, mesmo que ele abra o aplicativo de email em outro aplicativo host ou dispositivo.

Os detalhes de autenticação e validação são bastante complexos. Você pode usar uma biblioteca de validação de API gerenciada do EWS para simplificar o processo. Usando essa biblioteca de validação, um serviço Web iria criar um objeto, extrair e colocar o token no objeto, verificar se a assinatura é válida e, em caso positivo, colocar o identificador exclusivo no banco de dados de mapeamento.

Para obter mais informações sobre o uso de tokens de identidade do Exchange para autenticação, veja a seguinte documentação do Centro de Desenvolvimento:

  • “Autenticando um aplicativo de email usando tokens de identidade do Exchange” (bit.ly/ZYaZ9v)
  • “Por dentro do token de identidade do Exchange” (bit.ly/ZxRogq)
  • “Como: Chamar um serviço usando um token de identidade do Exchange” (bit.ly/12jqxcU)
  • “Como: Usar a biblioteca de validação do token do Exchange” (bit.ly/11akmEg)
  • “Como: Validar um token de identidade do Exchange” (bit.ly/15im6SO)
  • “Como: Autenticar um usuário com um token de identidade do Exchange” (bit.ly/13gZ36T)

Para encontrar exemplos de código:

  • Você pode consultar “Aplicativos de email para o Outlook: Usar um token de identidade do cliente” em C# para o Visual Studio 2012 (bit.ly/ZxS85b) para encontrar um exemplo do C# de um aplicativo de email e de um serviço Web que usam tokens de identidade do Exchange para autenticação.
  • Consulte “Aplicativos de email para o Outlook: Validar um token de identidade do cliente usando o .NET Framework” (bit.ly/17j9FSZ) para encontrar um exemplo de uso do .NET Framework para validar tokens de identidade do cliente do Exchange.

Acesso a um subconjunto do EWS Usando o método Mailbox.makeEwsRequestAsync, os aplicativos de email podem acessar um subconjunto de operações do EWS para criar, encontrar, obter, atualizar, mover ou enviar um item ou uma pasta. Por exemplo, você pode usar a operação CreateItem para criar um compromisso, mensagem ou contato. Usar a operação FindItem para pesquisar itens em uma caixa de correio. E usar a operação SendItem para enviar uma mensagem ou um convite para reunião. O subconjunto de operações com suporte se refere apenas à caixa de correio do usuário. Outras operações do EWS que se referem a uma organização inteira — como acessar a Lista de Endereços Global ou interagir com todas as pessoas na organização — estão fora dos limites dos aplicativos de email. Além disso, como o subconjunto de operações com suporte é avançado, os aplicativos de email devem exigir permissão de leitura/gravação de caixa de correio no manifesto do aplicativo, e apenas os administradores podem instalar os aplicativos de email que exigem essa permissão.

Quando você chama o método Mailbox.makeEwsRequestAsync, solicita o EWS no servidor Exchange que hospeda a caixa de correio do usuário. Antes de chamar makeEwsRequestAsync, especifique argumentos de entrada para os seguintes parâmetros:

  • parâmetro data: crie uma solicitação SOAP XML para a operação do EWS que você pretende chamar.
  • parâmetro callback: um método de retorno de chamada que trataria da resposta da operação.
  • parâmetro userContext: quaisquer dados de entrada para o método de retorno de chamada.

Quando a operação é concluída, os aplicativos da estrutura do Office chamam o método de retorno de chamada com um argumento, que é um objeto AsyncResult, semelhante aos outros métodos assíncronos que você viu na primeira parte desta série. O método de retorno de chamada pode acessar a propriedade Async­Result.value para obter a resposta SOAP XML que contém dados relevantes para a operação. O método de retorno de chamada também pode acessar a propriedade AsyncResult.asyncContext para acessar qualquer outro parâmetro de entrada transmitido pelo parâmetro userContext. Em seguida, o método de retorno de chamada analisa o XML na resposta SOAP para obter os dados relevantes para seus propósitos.

Para encontrar uma lista completa das operações do EWS com suporte e mais detalhes, consulte a documentação do Centro de Desenvolvimento, “Chamando serviços Web em um aplicativo de email do Outlook” (bit.ly/12jtH0z).

Para encontrar um exemplo de um aplicativo de email que demonstra a chamada da operação GetItem, consulte “Aplicativos de email para o Outlook: Faça uma solicitação do EWS” em C# para o Visual Studio 2012 (bit.ly/Zv3hEQ).

Conclusão

Isso encerra minha discussão sobre a criação de aplicativos de email, bem como a exploração da API JavaScript para Office com quatro partes. Para encontrar as partes anteriores da série e o artigo complementar online desta parte, consulte:

Angela Chu-Hatoun começou como desenvolvedora de software e mudou para a redação devido ao seu grande interesse em explicar como funcionam os softwares. Ela é redatora de programação na Divisão do Office há 12 anos e escreve para os desenvolvedores sobre a criação de aplicativos para o Office e sobre outras soluções para o Outlook. Gosta de ler sobre assuntos atuais, jardinagem, viagem, gastronomia e moda.

Agradecemos aos seguintes especialistas técnicos pela revisão deste artigo: Andrew Salamatov (Microsoft) e Tim Wan (Microsoft)
Tim Wan formou-se na Caltech em 2003 e possui um diploma de Engenharia e Ciências Aplicadas. Nos últimos nove anos, trabalha como desenvolvedor de software no Outlook. Trabalhou amplamente no recurso de aplicativos de email no Outlook 2013, bem como no modelo de objeto do Outlook nas versões anteriores. Ele está ansioso para lançar novos recursos e melhorias para os clientes no mundo inteiro.