Центры уведомлений Azure: как отправлять локализованные, независимые от платформы push-уведомления отдельным пользователям из серверной части .net?

Сценарий

Я разрабатываю бэкэнд для локализованного кроссплатформенного мобильного приложения и хочу отправлять пользователю push-уведомления, когда в бэкэнде происходят какие-то события.

Приложения разработаны для iOS и android с использованием xamarin, а серверной частью является web-api 2, использующий < strong> Центры уведомлений Azure.

Что работает до сих пор

В настоящее время мобильные приложения регистрируются для получения уведомлений через веб-API с помощью Установки. Регистрация через веб-API необходима, потому что сервер создает уникальный пользовательский тег, который будет использоваться для идентификации пользователя при отправке сообщений. В настоящее время я могу отправлять тестовые уведомления на зарегистрированное устройство iOS из раздела «Отладка» серверной части Azure. Вот код, который обрабатывает регистрацию:

[HttpPut]
[Route("")]
public async Task<IHttpActionResult> CreateOrUpdateDeviceInstallation(DeviceInstallationModel deviceInstallationModel)
{
    var installation = new Installation
    {
        InstallationId = deviceInstallationModel.InstallationId,
        PushChannel = deviceInstallationModel.Handle
    };

    switch (deviceInstallationModel.Platform)
    {
        case "apns":
            installation.Platform = NotificationPlatform.Apns;
            break;
        case "gcm":
            installation.Platform = NotificationPlatform.Gcm;
            break;
        default:

            return BadRequest("The given platform is not supported");
    }

    installation.Tags = new List<string>{ OwnerId }; 
    //OwnerId is the server generated unique user tag

    await _notificationHubClient.CreateOrUpdateInstallationAsync(installation);

    return Ok();
}


public class DeviceInstallationModel
{
    public string InstallationId { get; set; }
    public string Platform { get; set; }
    public string Handle { get; set; }
}

Моя проблема

Теперь мне нужно отправлять локализованные push-уведомления, когда в серверной части происходят определенные события. Я пытаюсь достичь этого без ведома серверной части ни о локали, ни о платформе приложений. Насколько я понял из документации (Межплатформенные уведомления и localized-notifications), шаблоны позволят мне добиться этого.

Мои вопросы

  1. Как происходит регистрация шаблона с помощью Установок?
  2. Как должен выглядеть шаблон, чтобы его можно было локализовать на клиенте, и что должен сделать клиент, чтобы добиться локализации? (Или есть шаблон для каждой локали?)
  3. Что должна делать серверная часть, чтобы отправлять уведомления, не зная платформу или локаль клиента?
  4. Мне нужно отправить разные сообщения (текст). Нужен ли мне один (или несколько) шаблонов для каждого сообщения?

person ChrisM    schedule 27.04.2016    source источник


Ответы (3)


Чтобы ответить на вопрос 1-3, вам нужно взглянуть на Шаблон. (Q1) Поскольку вы используете мобильные приложения, пакеты SDK для мобильных приложений Xamarin фактически позволяют зарегистрируйтесь напрямую с помощью шаблонов в Установках. (Q2) Чтобы увидеть, как выглядит шаблон в объекте установки, тело здесь хорошее место. (Q3) Для отправки учебные пособия, на которые вы ссылаетесь, на самом деле содержат отличные примеры. Для четвертого квартала это действительно зависит. Вы можете использовать один и тот же шаблон для передачи разных сообщений, учитывая, что все пользователи, зарегистрированные с помощью этого шаблона, получат эти сообщения (например, в cross-plat tutorial, вы можете легко переключиться на" Hello "+ user с другим сообщением). Но если вам нужно локализовать эти сообщения и т. Д., Вам понадобится несколько шаблонов.

Дайте мне знать, если у вас возникнут дополнительные вопросы.

person Mimi Xu    schedule 27.04.2016

  1. Как происходит регистрация шаблона с помощью Установок?

Как вы уже использовали в своем собственном ответе, используя _ 1_ свойства _ 2_ класс.

  1. Как должен выглядеть шаблон, чтобы его можно было локализовать на клиенте, и что должен сделать клиент, чтобы добиться локализации? (Или есть шаблон для каждой локали?)

Используйте параметры шаблона для текстов, которые необходимо локализовать, и добавьте суффикс языка к именам параметров. Точнее, клиенты должны регистрироваться с использованием шаблонов с параметрами, имеющими суффикс языка.

Пример iOS с английской локалью:

{"aps":{"alert":"$(message_en)"}}

Пример Android с немецким языком:

{"data":{"message":"$(message_de)"}}
  1. Что должна делать серверная часть, чтобы отправлять уведомления, не зная платформу или локаль клиента?

Просто отправьте шаблон уведомления со всеми параметрами на всех возможных языках.

Пример, предполагающий, что приложение поддерживает только английский и немецкий языки:

public void SendMessageA(int recipientUserId)
{
    var tagExpression = $"{recipientUserId}";
    var parameters = new Dictionary<string, string>()
    {
        { "message_en", "This is message A!" },
        { "message_de", "Dies ist Nachricht A!" }
    };

    _notificationHubClient.SendTemplateNotificationAsync(parameters, tagExpression);
}

public void SendMessageB(int recipientUserId)
{
    var tagExpression = $"{recipientUserId}";
    var parameters = new Dictionary<string, string>()
    {
        { "message_en", "This is message B!" },
        { "message_de", "Dies ist Nachricht B!" }
    };

    _notificationHubClient.SendTemplateNotificationAsync(parameters, tagExpression);
}
  1. Мне нужно отправить разные сообщения (текст). Нужен ли мне один (или несколько) шаблонов для каждого сообщения?

Как видите, при таком подходе у вас может быть одна регистрация шаблона для каждого экземпляра приложения и возможность отправлять разные локализованные сообщения из вашего бэкэнда.

Конечно, подход в вашем ответе также работает, но вам следует по возможности избегать использования тегов, поскольку выражения тегов ограничены (например, до 6 тегов, если выражение содержит другие операторы, кроме OR), и вы будете более гибкими, если не жестко закодируете текст для уведомление в ваше приложение.

person Baris Akar    schedule 02.05.2016
comment
Спасибо за подробный пример. Я еще не знал об ограничении тегов. У меня все еще вопрос: можно ли использовать параметры внутри других параметров? I.E. {message_en, Здравствуйте, $ (userName)! Это сообщение B! }. - person ChrisM; 02.05.2016
comment
@ChrisM, это невозможно. Вы можете попробовать использовать выражения шаблона, но они довольно limited, поэтому я предлагаю вам создать строки, содержащие имя отправителя, в вашем бэкэнде, прежде чем предоставлять их в качестве параметров шаблона для метода отправки. Если вы хотите использовать выражения шаблона, шаблон iOS может выглядеть так: {"aps":{"alert":"{$(messageBeforeUserName_en)+$(userName)+$(messageAfterUserName_en)}"}} - person Baris Akar; 02.05.2016
comment
Ах да, вот что я подумал. Спасибо за разъяснения. - person ChrisM; 02.05.2016

Я нашел решение для достижения желаемого поведения.

В демонстрационных целях предположим, что клиенты могут зарегистрироваться для получения двух разных уведомлений, MessageA и MessageB. MessageA помечается от клиента как "tagForMessageA", а MessageB помечается от клиента как "taggedForMessageB". Когда клиентское приложение запускается или пользователь меняет язык, оно вызывает веб-API и указывает один шаблон для каждого сообщения, которое он хочет получить (messageA и messageB в этом примере). Body содержит локализованное тело, зависящее от платформы, например:

MessageA, iOS на английском языке

{"aps":{"alert":"This is message A!"}}

или MessageB, немецкий android

{"data":{"message":"Dies ist NachrichtB für Android!"}}

Это позволяет клиенту решить

  • какие сообщения он хочет получать
  • на каком языке написаны сообщения
  • как он хочет их отображать.

Регистрация через API

Вот код веб-API, который обрабатывает регистрацию:

Контроллер API

[HttpPut]
[Route("")]
public async Task<IHttpActionResult> CreateOrUpdateDeviceInstallation(DeviceInstallationModel deviceInstallationModel)
{
    var installation = new Installation
    {
        InstallationId = deviceInstallationModel.InstallationId,
        PushChannel = deviceInstallationModel.Handle,
        Tags = new List<string>
        {
            //Obtain the users id from the database here
        },
        Templates = new Dictionary<string, InstallationTemplate>()
    };
    switch (deviceInstallationModel.Platform)
    {
        case "apns":
            installation.Platform = NotificationPlatform.Apns;
            break;
        case "gcm":
            installation.Platform = NotificationPlatform.Gcm;
            break;
        default:
            return BadRequest("The given platform is not supported");
    }
    foreach (var templateModel in deviceInstallationModel.Templates)
    {
        if (installation.Templates.ContainsKey(templateModel.MessageIdentifier))
        {
            return BadRequest("Message identifiers must be unique");
        }
        installation.Templates.Add(
            templateModel.MessageIdentifier,
            CreateInstallationTemplateFromModel(templateModel));
    }
    await _notificationHubClient.CreateOrUpdateInstallationAsync(installation);

    return Ok();
}

private static InstallationTemplate CreateInstallationTemplateFromModel(TemplateModel templateModel)
{
    return new InstallationTemplate
    {
        Body = templateModel.Body,
        Tags = new List<string> {templateModel.MessageIdentifier}
    };
}

Модели

public class DeviceInstallationModel
{
    public DeviceInstallationModel()
    {
        Templates= new List<TemplateModel>();
    }

    public string InstallationId { get; set; }
    public string Platform { get; set; }
    public string Handle { get; set; }
    public List<TemplateModel> Templates { get; set; }
}

public class TemplateModel
{
    public string MessageIdentifier { get; set; }

    public string Body { get; set; }
}

MessageIdentifiers

Это соглашение, которому должны следовать и клиенты:

public class MessageIdentifiers
{
    public const string MessageA = "tagForMessageA";
    public const string MessageB = "tagForMessageB";
}

Отправка сообщений из бэкэнда

И этот код обрабатывает отправку уведомлений клиенту.

СообщениеA

public void SendMessageA(int recipientUserId)
{
    var tagExpression = $"{recipientUserId}&&{MessageIdentifiers.MessageA}";
    _notificationHubClient.SendTemplateNotificationAsync(new Dictionary<string, string>(),
            tagExpression);
}

СообщениеB

public void SendMessageB(int recipientUserId)
{
    var tagExpression = $"{recipientUserId}&&{MessageIdentifiers.MessageB}";
    _notificationHubClient.SendTemplateNotificationAsync(new Dictionary<string, string>(),
            tagExpression);
}
person ChrisM    schedule 28.04.2016
comment
Вам действительно стоит использовать для этого шаблоны, он был разработан для этого. См. Ответ Мимиса ... - person Baris Akar; 02.05.2016
comment
@BarisAkar На самом деле, я использую шаблоны. Если вы знаете, как использовать ОДИН шаблон для каждого сообщения, сохраняя при этом внутреннюю независимость от клиентской платформы И языкового стандарта клиента, я все слышу :) - person ChrisM; 02.05.2016
comment
извините, я был недостаточно ясен. Вы должны использовать шаблоны с параметрами шаблона для локализации уведомлений, как показано в связанном руководстве. Я отправлю ответ ... - person Baris Akar; 02.05.2016
comment
@BarisAkar Нет, нет, я тебя понял. Я знаю, как настраивать пользовательские параметры в шаблонах. Я просто не мог понять, как это сделать, не зная локали клиента на стороне сервера. - person ChrisM; 02.05.2016