如何实现AppCenter Push API?

时间:2019-07-11 06:13:51

标签: c# asp.net xamarin push-notification visual-studio-app-center

我一直在阅读https://docs.microsoft.com/en-us/appcenter/push/rest-api并在Internet上查看如何轻松实现此功能的示例,但没有发现有用的信息。

我阅读并实现了 https://www.andrewhoefling.com/Blog/Post/push-notifications-with-app-center-api-integration。他的解决方案提供了一个很好的起点,但还不完善。

因此,我从上面将Andrew Hoefling的解决方案增强到了完整的工作版本,并认为在下面的答案中与Xamarin成员分享是很好的。

3 个答案:

答案 0 :(得分:1)

public class AppCenterPush
{
    User receiver = new User();

    public AppCenterPush(Dictionary<Guid, string> dicInstallIdPlatform)
    {
        //Simply get all the Install IDs for the receipient with the platform name as the value
        foreach(Guid key in dicInstallIdPlatform.Keys)
        {
            switch(dicInstallIdPlatform[key])
            {
                case "Android":
                    receiver.AndroidDevices.Add(key.ToString());

                    break;

                case "iOS":
                    receiver.IOSDevices.Add(key.ToString());

                    break;
            }
        }
    }

    public class Constants
    {
        public const string Url = "https://api.appcenter.ms/v0.1/apps";
        public const string ApiKeyName = "X-API-Token";     

        //Push required to use this. Go to https://docs.microsoft.com/en-us/appcenter/api-docs/index for instruction
        public const string FullAccessToken = "{FULL ACCESS TOKEN}";   

        public const string DeviceTarget = "devices_target";
        public class Apis { public const string Notification = "push/notifications"; }

        //You can find your AppName and Organization/User name at your AppCenter URL as such https://appcenter.ms/users/{owner-name}/apps/{app-name}
        public const string AppNameAndroid = "{APPNAME_ANDROID}";
        public const string AppNameIOS = "{APPNAME_IOS}";

        public const string Organization = "{ORG_OR_USER}";
    }

    [JsonObject]
    public class Push
    {
        [JsonProperty("notification_target")]
        public Target Target { get; set; }

        [JsonProperty("notification_content")]
        public Content Content { get; set; }
    }

    [JsonObject]
    public class Content
    {
        public Content()
        {
            Name = "default";   //By default cannot be empty, must have at least 3 characters
        }

        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("title")]
        public string Title { get; set; }

        [JsonProperty("body")]
        public string Body { get; set; }

        [JsonProperty("custom_data")]
        public IDictionary<string, string> CustomData { get; set; }
    }

    [JsonObject]
    public class Target
    {
        [JsonProperty("type")]
        public string Type { get; set; }

        [JsonProperty("devices")]
        public IEnumerable Devices { get; set; }
    }

    public class User
    {
        public User()
        {
            IOSDevices = new List<string>();
            AndroidDevices = new List<string>();
        }

        public List<string> IOSDevices { get; set; }
        public List<string> AndroidDevices { get; set; }
    }

    public async Task<bool> Notify(string title, string message, Dictionary<string, string> customData = default(Dictionary<string, string>))
    {
        try
        {
            if (!receiver.IOSDevices.Any() && !receiver.AndroidDevices.Any())
                return false; //No devices to send

            //To make sure in Android, title and message is retain when click from notification. Else it's lost when app is in background
            if (customData == null)
                customData = new Dictionary<string, string>();

            if (!customData.ContainsKey("Title"))
                customData.Add("Title", title);

            if (!customData.ContainsKey("Message"))
                customData.Add("Message", message);

            var push = new Push
            {
                Content = new Content
                {
                    Title = title,
                    Body = message,
                    CustomData = customData
                },
                Target = new Target
                {
                    Type = Constants.DeviceTarget
                }
            };

            HttpClient httpClient = new HttpClient();

            //Set the content header to json and inject the token
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            httpClient.DefaultRequestHeaders.Add(Constants.ApiKeyName, Constants.FullAccessToken);

            //Needed to solve SSL/TLS issue when 
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

            if (receiver.IOSDevices.Any())
            {
                push.Target.Devices = receiver.IOSDevices;

                string content = JsonConvert.SerializeObject(push);

                HttpContent httpContent = new StringContent(content, Encoding.UTF8, "application/json");

                string URL = $"{Constants.Url}/{Constants.Organization}/Constants.AppNameiOS}/{Constants.Apis.Notification}";

                var result = await httpClient.PostAsync(URL, httpContent);
            }

            if (receiver.AndroidDevices.Any())
            {
                push.Target.Devices = receiver.AndroidDevices;

                string content = JsonConvert.SerializeObject(push);

                HttpContent httpContent = new StringContent(content, Encoding.UTF8, "application/json");

                string URL = $"{Constants.Url}/{Constants.Organization}/{Constants.AppNameAndroid}/{Constants.Apis.Notification}";

                var result = await httpClient.PostAsync(URL, httpContent);
            }

            return true;
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.ToString());

            return false;
        }
    }
}

要使用此功能,只需在程序中执行以下操作

 var receiptInstallID = new Dictionary<string, string>
    {
        { "XXX-XXX-XXX-XXX", "Android" },
        { "YYY-YYY-YYY-YYY", "iOS" }
    };

AppCenterPush appCenterPush = new AppCenterPush(receiptInstallID);

await appCenterPush.Notify("{YOUR_TITLE}", "{YOUR_MESSAGE}", null);

答案 1 :(得分:1)

还不能添加评论,但上面的答案中有错字

string URL = $"{Constants.Url}/{Constants.Organization}/Constants.AppNameiOS}/{Constants.Apis.Notification}";

应该是

string URL = $"{Constants.Url}/{Constants.Organization}/{Constants.AppNameIOS}/{Constants.Apis.Notification}";

缺少{,且IOS常数为大写。

在您的示例中也应将其构造为

var receiptInstallID = new Dictionary<Guid, string>

也仅需参考:

using Newtonsoft.Json;  
using System;  
using System.Collections;  
using System.Collections.Generic;  
using System.Linq;  
using System.Net;  
using System.Net.Http;  
using System.Net.Http.Headers;  
using System.Text;  
using System.Threading.Tasks;  

答案 2 :(得分:1)

如果您要向目标用户(user_ids_target)发送通知,

 public class AppCenterPush
{
    User receiver = new User();

    public AppCenterPush(Dictionary<string, string> dicInstallIdPlatform)
    {
        //Simply get all the Install IDs for the receipient with the platform name as the value
        foreach (string key in dicInstallIdPlatform.Keys)
        {
            switch (dicInstallIdPlatform[key])
            {
                case "Android":
                    receiver.AndroidDevices.Add(key.ToString());

                    break;

                case "iOS":
                    receiver.IOSDevices.Add(key.ToString());

                    break;
            }
        }
    }

    public class Constants
    {
        public const string Url = "https://api.appcenter.ms/v0.1/apps";
        public const string ApiKeyName = "X-API-Token";

        //Push required to use this. Go to https://docs.microsoft.com/en-us/appcenter/api-docs/index for instruction
        public const string FullAccessToken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

        public const string DeviceTarget = "devices_target";
        public const string UserTarget = "user_ids_target";
        public class Apis { public const string Notification = "push/notifications"; }

        //You can find your AppName and Organization/User name at your AppCenter URL as such https://appcenter.ms/users/{owner-name}/apps/{app-name}
        public const string AppNameAndroid = "XXXXXX";
        public const string AppNameIOS = "XXXXXX";

        public const string Organization = "XXXXXXX";
    }

    [JsonObject]
    public class Push
    {
        [JsonProperty("notification_target")]
        public Target Target { get; set; }

        [JsonProperty("notification_content")]
        public Content Content { get; set; }
    }

    [JsonObject]
    public class Content
    {
        public Content()
        {
            Name = "default";   //By default cannot be empty, must have at least 3 characters
        }

        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("title")]
        public string Title { get; set; }

        [JsonProperty("body")]
        public string Body { get; set; }

        [JsonProperty("custom_data")]
        public IDictionary<string, string> CustomData { get; set; }
    }

    [JsonObject]
    public class Target
    {
        [JsonProperty("type")]
        public string Type { get; set; }

        [JsonProperty("user_ids")]
        public IEnumerable Users { get; set; }
    }

    public class User
    {
        public User()
        {
            IOSDevices = new List<string>();
            AndroidDevices = new List<string>();
        }

        public List<string> IOSDevices { get; set; }
        public List<string> AndroidDevices { get; set; }
    }

    public async Task<bool> Notify(string title, string message, Dictionary<string, string> customData = default(Dictionary<string, string>))
    {
        try
        {
            //title, message length cannot exceed 100 char
            if (title.Length > 100)
                title = title.Substring(0, 95) + "...";

            if (message.Length > 100)
                message = message.Substring(0, 95) + "...";

            if (!receiver.IOSDevices.Any() && !receiver.AndroidDevices.Any())
                return false; //No devices to send

            //To make sure in Android, title and message is retain when click from notification. Else it's lost when app is in background
            if (customData == null)
                customData = new Dictionary<string, string>();

            if (!customData.ContainsKey("Title"))
                customData.Add("Title", title);

            if (!customData.ContainsKey("Message"))
                customData.Add("Message", message);

            //custom data cannot exceed 100 char 
            foreach (string key in customData.Keys)
            {
                if (customData[key].Length > 100)
                {
                    customData[key] = customData[key].Substring(0, 95) + "...";
                }
            }

            var push = new Push
            {
                Content = new Content
                {
                    Title = title,
                    Body = message,
                    CustomData = customData
                },
                Target = new Target
                {
                    Type = Constants.UserTarget
                }
            };

            HttpClient httpClient = new HttpClient();

            //Set the content header to json and inject the token
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            httpClient.DefaultRequestHeaders.Add(Constants.ApiKeyName, Constants.FullAccessToken);

            //Needed to solve SSL/TLS issue when 
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

            if (receiver.IOSDevices.Any())
            {
                push.Target.Users = receiver.IOSDevices;

                string content = JsonConvert.SerializeObject(push);

                HttpContent httpContent = new StringContent(content, Encoding.UTF8, "application/json");

                string URL = $"{Constants.Url}/{Constants.Organization}/{Constants.AppNameIOS}/{Constants.Apis.Notification}";

                var result = await httpClient.PostAsync(URL, httpContent);
            }

            if (receiver.AndroidDevices.Any())
            {
                push.Target.Users = receiver.AndroidDevices;

                string content = JsonConvert.SerializeObject(push);

                HttpContent httpContent = new StringContent(content, Encoding.UTF8, "application/json");

                string URL = $"{Constants.Url}/{Constants.Organization}/{Constants.AppNameAndroid}/{Constants.Apis.Notification}";

                var result = await httpClient.PostAsync(URL, httpContent);
            }

            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());

            return false;
        }
    }
}

在创建一个用于调用它的函数之后;

public async void PushNotification()
    {
        var receiptInstallID = new Dictionary<string, string>
                {
                    {"17593989838", "Android" }
                };

        var customData = new Dictionary<string, string>
                {
                    {"taskId", "1234" }
                };

        AppCenterPush appCenterPush = new AppCenterPush(receiptInstallID);

        await appCenterPush.Notify("Hello", "How are you?", customData);

    }