Share via


Início Rápido: notificações por push no SDK do Aplicativo Windows

Neste início rápido, você criará um aplicativo do Windows para área de trabalho que envia e recebe notificações de aplicativo local, também conhecidas como notificações do sistema, usando o SDK do Aplicativo Windows.

Pré-requisitos

Aplicativo de exemplo

Este guia de início rápido mostra como adicionar suporte a notificações por push ao seu aplicativo. Confira o código de exemplo deste início rápido no contexto nos aplicativos de exemplo encontrados no GitHub.

Referência da API

Para obter a documentação da referência de API das notificações por push, confira o Namespace Microsoft.Windows.PushNotifications.

Configurar a identidade do seu aplicativo no Azure Active Directory (AAD)

As notificações por push no SDK do Aplicativo Windows usam identidades do Azure Active Directory (AAD). As credenciais do Azure são necessárias ao solicitar um URI de Canal WNS e ao solicitar tokens de acesso para enviar notificações por push. Observação: NÃO oferecemos suporte ao uso de notificações por push do SDK do Aplicativo Windows com o Microsoft Central de Parceiros.

Etapa 1: criar um registro de aplicativo AAD

Faça logon em sua conta do Azure e crie um recurso de Registro de Aplicativo do AAD. Selecione Novo registro.

Etapa 2: Forneça um nome e selecione uma opção multilocatário

  1. Forneça um nome do aplicativo.

  2. As notificações por push exigem a opção multilocatário, portanto, selecione-a.

    1. Para obter mais informações sobre locatários, confira Quem pode iniciar sessão em seu aplicativo?.
  3. Escolha Registrar

  4. Anote sua ID de Aplicativo (cliente), pois essa é sua AppId do Azure que você usará durante o registro de ativação e a solicitação de token de acesso.

  5. Anote sua ID de Diretório (locatário), pois essa é sua ID de Locatário do Azure que você usará ao solicitar um token de acesso.

    Importante

    Locatário de registro de aplicativo ADDAnote sua ID de aplicativo (cliente) e a ID de diretório (locatário).

  6. Anote sua ID de objeto, pois essa é a ID de objeto do Azure que você usará ao fazer uma solicitação de canal. Observe que essa NÃO é a ID de objeto listada na página Essentials. Em vez disso, para procurar a ID de objeto correta, clique no nome do aplicativo no campo Aplicativo gerenciado no diretório local na página Essentials:

    Captura de tela mostrando a opção Aplicativo gerenciado no diretório local na página Essentials

    Captura de tela mostrando o campo ID do Objeto.

    Observação

    Uma entidade de serviço é necessária para obter uma ID de objeto, se não houver uma associada ao seu aplicativo, siga as etapas em um dos seguintes artigos para criar uma no portal do Azure ou usando a linha de comando:

    Usar o portal para criar um aplicativo e uma entidade de serviço do Azure Active Directory que possa acessar recursos

    Usar o Azure PowerShell para criar uma entidade de serviço com um certificado

Etapa 3: criar um segredo para o registro do seu aplicativo

Seu segredo será usado junto com seu AppId/ClientId do Azure ao solicitar um token de acesso para enviar notificações por push.

Segredo do aplicativo AAD

Navegue até Certificados e segredos e selecione Novo segredo do cliente.

Importante

Certifique-se de copiar seu segredo depois de criado e armazená-lo em uma localização segura, como o Azure Key Vault. Ele só poderá ser visto uma vez logo após a criação.

Etapa 4: mapear o Nome da Família de Pacotes do seu aplicativo para seu AppId do Azure

Caso seu aplicativo seja um aplicativo Win32 empacotado, crie uma solicitação de mapeamento de Nome da Família de Pacotes (PFN) enviando um email para Win_App_SDK_Push@microsoft.com com a linha de assunto "Solicitação de Notificações por Push do SDK de Aplicativo do Windows" e o corpo "PFN: [seu PFN]", AppId: [seu APPId], ObjectId: [seu ObjectId]. As solicitações de mapeamento são concluídas semanalmente. Você será notificado assim que sua solicitação de mapeamento for concluída.

Configure seu aplicativo para receber notificações por push

Etapa 1: adicionar declarações de namespace

Adicione o namespace para notificações por push do SDK do Aplicativo Windows Microsoft.Windows.PushNotifications.

#include <winrt/Microsoft.Windows.PushNotifications.h>

using namespace winrt::Microsoft::Windows::PushNotifications;

Etapa 2: adicionar o ativador COM ao manifesto do aplicativo

Importante

Se o aplicativo estiver desempacotado (ou seja, se ele não tiver um identificador de pacote no runtime), vá para a Etapa 3: Registre-se para responder a notificações por push na inicialização do aplicativo.

Se seu aplicativo estiver empacotado (inclusive empacotado com localização externa): abra seu Package.appxmanifest. Adicione o seguinte dentro do elemento <Application>. Substitua os valores Id,Executable e DisplayName por aqueles específicos para seu aplicativo.

<!--Packaged apps only-->
<!--package.appxmanifest-->

<Package
  ...
  xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
  ...
  <Applications>
    <Application>
      ...
      <Extensions>

        <!--Register COM activator-->    
        <com:Extension Category="windows.comServer">
          <com:ComServer>
              <com:ExeServer Executable="SampleApp\SampleApp.exe" DisplayName="SampleApp" Arguments="----WindowsAppRuntimePushServer:">
                <com:Class Id="[Your app's Azure AppId]" DisplayName="Windows App SDK Push" />
            </com:ExeServer>
          </com:ComServer>
        </com:Extension>
    
      </Extensions>
    </Application>
  </Applications>
 </Package>    

Etapa 3: Registre-se e responda às notificações por push na inicialização do aplicativo

Atualize o método do seu aplicativo main() para adicionar o seguinte:

  1. Registre seu aplicativo para receber notificações por push chamando PushNotificationManager::Default().Register().
  2. Verifique a origem da solicitação de ativação chamando AppInstance::GetCurrent(). GetActivatedEventArgs(). Se a ativação foi acionada a partir de uma notificação por push, responda com base na payload da notificação.

Importante

Você deve chamar PushNotificationManager::Default().Register antes de chamar AppInstance.GetCurrent.GetActivatedEventArgs.

O exemplo a seguir é do aplicativo empacotado de exemplo encontrado no GitHub.

// cpp-console.cpp
#include "pch.h"
#include <iostream>
#include <winrt/Microsoft.Windows.PushNotifications.h>
#include <winrt/Microsoft.Windows.AppLifecycle.h>
#include <winrt/Windows.Foundation.h>
#include <wil/result.h>
#include <wil/cppwinrt.h>


using namespace winrt;
using namespace Windows::Foundation;

using namespace winrt::Microsoft::Windows::PushNotifications;
using namespace winrt::Microsoft::Windows::AppLifecycle;

winrt::guid remoteId{ "7edfab6c-25ae-4678-b406-d1848f97919a" }; // Replace this with your own Azure ObjectId



void SubscribeForegroundEventHandler()
{
    winrt::event_token token{ PushNotificationManager::Default().PushReceived([](auto const&, PushNotificationReceivedEventArgs const& args)
    {
        auto payload{ args.Payload() };

        std::string payloadString(payload.begin(), payload.end());
        std::cout << "\nPush notification content received in the FOREGROUND: " << payloadString << std::endl;
    }) };
}

int main()
{
    // Setup an event handler, so we can receive notifications in the foreground while the app is running.
    SubscribeForegroundEventHandler();

    PushNotificationManager::Default().Register();

    auto args{ AppInstance::GetCurrent().GetActivatedEventArgs() };
    switch (args.Kind())
    {
        // When it is launched normally (by the users, or from the debugger), the sample requests a WNS Channel URI and
        // displays it, then waits for notifications. This user can take a copy of the WNS Channel URI and use it to send
        // notifications to the sample
        case ExtendedActivationKind::Launch:
        {
            // Checks to see if push notifications are supported. Certain self-contained apps may not support push notifications by design
            if (PushNotificationManager::IsSupported())
            {
                // Request a WNS Channel URI which can be passed off to an external app to send notifications to.
                // The WNS Channel URI uniquely identifies this app for this user and device.
                PushNotificationChannel channel{ RequestChannel() };
                if (!channel)
                {
                    std::cout << "\nThere was an error obtaining the WNS Channel URI" << std::endl;
    
                    if (remoteId == winrt::guid { "00000000-0000-0000-0000-000000000000" })
                    {
                        std::cout << "\nThe ObjectID has not been set. Refer to the readme file accompanying this sample\nfor the instructions on how to obtain and setup an ObjectID" << std::endl;
                    }
                }
    
                std::cout << "\nPress 'Enter' at any time to exit App." << std::endl;
                std::cin.ignore();
            }
            else
            {
                // App implements its own custom socket here to receive messages from the cloud since Push APIs are unsupported.
            }
        }
        break;

        // When it is activated from a push notification, the sample only displays the notification.
        // It doesn’t register for foreground activation of perform any other actions
        // because background activation is meant to let app perform only small tasks in order to preserve battery life.
        case ExtendedActivationKind::Push:
        {
            PushNotificationReceivedEventArgs pushArgs{ args.Data().as<PushNotificationReceivedEventArgs>() };

            // Call GetDeferral to ensure that code runs in low power
            auto deferral{ pushArgs.GetDeferral() };

            auto payload{ pushArgs.Payload() } ;

            // Do stuff to process the raw notification payload
            std::string payloadString(payload.begin(), payload.end());
            std::cout << "\nPush notification content received in the BACKGROUND: " << payloadString.c_str() << std::endl;
            std::cout << "\nPress 'Enter' to exit the App." << std::endl;

            // Call Complete on the deferral when finished processing the payload.
            // This removes the override that kept the app running even when the system was in a low power mode.
            deferral.Complete();
            std::cin.ignore();
        }
        break;

        default:
            std::cout << "\nUnexpected activation type" << std::endl;
            std::cout << "\nPress 'Enter' to exit the App." << std::endl;
            std::cin.ignore();
            break;
    }

    // We do not call PushNotificationManager::UnregisterActivator
    // because then we wouldn't be able to receive background activations, once the app has closed.
    // Call UnregisterActivator once you don't want to receive push notifications anymore.
}

Etapa 4: solicitar um URI do Canal WNS e registrá-lo no servidor WNS

Os URIs do Canal WNS são os pontos de extremidade HTTP para o envio de notificações por push. Cada cliente deve solicitar um URI de canal e registrá-lo no servidor WNS para receber notificações por push.

Observação

Os URIs do Canal WNS expiram após 30 dias.

auto channelOperation{ PushNotificationManager::Default().CreateChannelAsync(winrt::guid("[Your app's Azure ObjectID]")) };

O PushNotificationManager tentará criar um URI de canal, realizando uma nova tentativa automaticamente por no máximo 15 minutos. Crie um manipulador de eventos para aguardar a conclusão da chamada. Quando a chamada for concluída, se tiver sido bem-sucedida, registre o URI no servidor WNS.

// cpp-console.cpp

winrt::Windows::Foundation::IAsyncOperation<PushNotificationChannel> RequestChannelAsync()
{
    // To obtain an AAD RemoteIdentifier for your app,
    // follow the instructions on https://learn.microsoft.com/azure/active-directory/develop/quickstart-register-app
    auto channelOperation = PushNotificationManager::Default().CreateChannelAsync(remoteId);

    // Setup the inprogress event handler
    channelOperation.Progress(
        [](auto&& sender, auto&& args)
        {
            if (args.status == PushNotificationChannelStatus::InProgress)
            {
                // This is basically a noop since it isn't really an error state
                std::cout << "Channel request is in progress." << std::endl << std::endl;
            }
            else if (args.status == PushNotificationChannelStatus::InProgressRetry)
            {
                LOG_HR_MSG(
                    args.extendedError,
                    "The channel request is in back-off retry mode because of a retryable error! Expect delays in acquiring it. RetryCount = %d",
                    args.retryCount);
            }
        });

    auto result = co_await channelOperation;

    if (result.Status() == PushNotificationChannelStatus::CompletedSuccess)
    {
        auto channelUri = result.Channel().Uri();

        std::cout << "channelUri: " << winrt::to_string(channelUri.ToString()) << std::endl << std::endl;

        auto channelExpiry = result.Channel().ExpirationTime();

        // Caller's responsibility to keep the channel alive
        co_return result.Channel();
    }
    else if (result.Status() == PushNotificationChannelStatus::CompletedFailure)
    {
        LOG_HR_MSG(result.ExtendedError(), "We hit a critical non-retryable error with channel request!");
        co_return nullptr;
    }
    else
    {
        LOG_HR_MSG(result.ExtendedError(), "Some other failure occurred.");
        co_return nullptr;
    }

};

PushNotificationChannel RequestChannel()
{
    auto task = RequestChannelAsync();
    if (task.wait_for(std::chrono::seconds(300)) != AsyncStatus::Completed)
    {
        task.Cancel();
        return nullptr;
    }

    auto result = task.GetResults();
    return result;
}

Etapa 5: criar e instalar seu aplicativo

Use o Visual Studio Code para criar e instalar seu aplicativo. Clique com o botão direito do mouse no arquivo de solução gerenciador de soluções e selecione Implantar. O Visual Studio criará seu aplicativo e o instalará em seu computador. Você pode executar o aplicativo iniciando-o por meio do Menu Iniciar ou do depurador do Visual Studio.

Envie uma notificação por push para o seu aplicativo

Neste ponto, toda a configuração está concluída e o servidor WNS pode enviar notificações por push para aplicativos cliente. Nas etapas a seguir, confira os cabeçalhos de solicitação e resposta do servidor de notificação por push para obter mais detalhes.

Etapa 1: solicitar um token de acesso

Para enviar uma notificação por push, o servidor WNS primeiro precisa solicitar um token de acesso. Envie uma solicitação HTTP POST com seu Azure TenantId, Azure AppId e segredo. Para obter informações sobre como recuperar o Azure TenantId e o Azure AppId, confira Obter valores de locatário e ID do aplicativo para entrar.

Solicitação HTTP de exemplo:

POST /{tenantID}/oauth2/v2.0/token Http/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 160

grant_type=client_credentials&client_id=<Azure_App_Registration_AppId_Here>&client_secret=<Azure_App_Registration_Secret_Here>&scope=https://wns.windows.com/.default/

Solicitação de exemplo C#:

//Sample C# Access token request
var client = new RestClient("https://login.microsoftonline.com/{tenantID}/oauth2/v2.0");
var request = new RestRequest("/token", Method.Post);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("grant_type", "client_credentials");
request.AddParameter("client_id", "[Your app's Azure AppId]");
request.AddParameter("client_secret", "[Your app's secret]");
request.AddParameter("scope", "https://wns.windows.com/.default");
RestResponse response = await client.ExecutePostAsync(request);
Console.WriteLine(response.Content);

Se sua solicitação for bem-sucedida, você receberá uma resposta que contém seu token no campo access_token.

{
    "token_type":"Bearer",
    "expires_in":"86399",
    "ext_expires_in":"86399",
    "expires_on":"1653771789",
    "not_before":"1653685089",
    "access_token":"[your access token]"
}

Etapa 2. Enviar uma notificação bruta

Crie uma solicitação HTTP POST que contenha o token de acesso obtido na etapa anterior e o conteúdo da notificação por push que você deseja enviar. O conteúdo da notificação por push será entregue ao aplicativo.

POST /?token=[The token query string parameter from your channel URL. E.g. AwYAAABa5cJ3...] HTTP/1.1
Host: dm3p.notify.windows.com
Content-Type: application/octet-stream
X-WNS-Type: wns/raw
Authorization: Bearer [your access token]
Content-Length: 46

{ Sync: "Hello from the Contoso App Service" }
var client = new RestClient("[Your channel URL. E.g. https://wns2-by3p.notify.windows.com/?token=AwYAAABa5cJ3...]");
var request = new RestRequest();
request.Method = Method.Post; 
request.AddHeader("Content-Type", "application/octet-stream");
request.AddHeader("X-WNS-Type", "wns/raw");
request.AddHeader("Authorization", "Bearer [your access token]");
request.AddBody("Notification body");
RestResponse response = await client.ExecutePostAsync(request);");

Etapa 3: enviar uma notificação de aplicativo originada da nuvem

Se você estiver interessado apenas em enviar notificações brutas, desconsidere esta etapa. Para enviar uma notificação de aplicativo originada na nuvem, também conhecida como notificação do sistema por push, primeiro siga o Início Rápido: notificações de aplicativo no SDK do Aplicativo Windows. As notificações de aplicativo podem ser enviadas por push (enviadas da nuvem) ou enviadas localmente. Enviar uma notificação de aplicativo de origem na nuvem é semelhante ao envio de uma notificação bruta na Etapa 2, exceto que o cabeçalho do tipo X-WNS é toast, tipo de conteúdo é text/xml, e o conteúdo contém a payload XML de notificação do aplicativo. Consulte o Esquema XML de notificações para saber mais sobre como construir sua payload XML.

Crie uma solicitação HTTP POST que contenha seu token de acesso e o conteúdo da notificação de aplicativo originada na nuvem que você deseja enviar. O conteúdo da notificação por push será entregue ao aplicativo.

POST /?token=AwYAAAB%2fQAhYEiAESPobjHzQcwGCTjHu%2f%2fP3CCNDcyfyvgbK5xD3kztniW%2bjba1b3aSSun58SA326GMxuzZooJYwtpgzL9AusPDES2alyQ8CHvW94cO5VuxxLDVzrSzdO1ZVgm%2bNSB9BAzOASvHqkMHQhsDy HTTP/1.1
Host: dm3p.notify.windows.com
Content-Type: text/xml
X-WNS-Type: wns/toast
Authorization: Bearer [your access token]
Content-Length: 180

<toast><visual><binding template="ToastGeneric"><text>Example cloud toast notification</text><text>This is an example cloud notification using XML</text></binding></visual></toast>
var client = new RestClient("https://dm3p.notify.windows.com/?token=AwYAAAB%2fQAhYEiAESPobjHzQcwGCTjHu%2f%2fP3CCNDcyfyvgbK5xD3kztniW%2bjba1b3aSSun58SA326GMxuzZooJYwtpgzL9AusPDES2alyQ8CHvW94cO5VuxxLDVzrSzdO1ZVgm%2bNSB9BAzOASvHqkMHQhsDy");
client.Timeout = -1;

var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "text/xml");
request.AddHeader("X-WNS-Type", "wns/toast");
request.AddHeader("Authorization", "Bearer <AccessToken>");
request.AddParameter("text/xml", "<toast><visual><binding template=\"ToastGeneric\"><text>Example cloud toast notification</text><text>This is an example cloud notification using XML</text></binding></visual></toast>",  ParameterType.RequestBody);
Console.WriteLine(response.Content);

Recursos