简体   繁体   English

如何实现 AppCenter Push API?

[英]How to implement AppCenter Push API?

IMPORTANT - Microsoft is retiring AppCenter Push pretty soon, you can still follow my answer below to implement it.重要-微软很快就会停用 AppCenter Push,您仍然可以按照我在下面的回答来实现它。 Or you can follow my new post at How to implement Push Notification in Xamarin with Firebase and Apple Push Notification with C# backend on using Firebase & Apple Push Notification.或者,您可以关注我在如何使用 Firebase 和 Apple 推送通知在 Xamarin 中使用 Firebase 和 Apple 推送通知与 C# 后端有关使用 Firebase 和 Apple 推送通知的新帖子。 Thank you.谢谢你。

I have been reading https://docs.microsoft.com/en-us/appcenter/push/rest-api and looking over the Internet for example of how to implement this easily but found nothing useful.我一直在阅读https://docs.microsoft.com/en-us/appcenter/push/rest-api并在互联网上查看如何轻松实现这一点的示例,但没有发现任何有用的信息。

I read and implemented this https://www.andrewhoefling.com/Blog/Post/push-notifications-with-app-center-api-integration .我阅读并实施了这个https://www.andrewhoefling.com/Blog/Post/push-notifications-with-app-center-api-integration His solution offers very good start, but incomplete.他的解决方案提供了很好的开始,但不完整。

So I enhanced Andrew Hoefling's solution from above to a full working version and thought it's good to share with fellows Xamarin members in the answer below.因此,我将 Andrew Hoefling 的解决方案从上面增强为完整的工作版本,并认为最好在下面的答案中与 Xamarin 成员分享。

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
        {
            //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.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;
        }
    }
}

To use this, simply do the following from your program要使用它,只需从您的程序中执行以下操作

 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);

Can't add comment yet, but theres a typo in the above answer还不能添加评论,但上面的答案有一个错字

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

Should be应该

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

Missing { and IOS constant is capitalized.缺少 { 和 IOS 常量是大写的。

Also, in your example to call it, Should be constructed as < guid, string >另外,在您调用它的示例中,应该构造为 < guid, string >

var receiptInstallID = new Dictionary<Guid, string>

also needed as just FYI:也需要仅供参考:

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;  

If you want to send notification for target user (user_ids_target),如果您想为目标用户(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;
        }
    }
}

After create a function for call it;创建一个调用它的函数后;

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);

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM