【问题标题】:How to implement AppCenter Push API?如何实现 AppCenter 推送 API?
【发布时间】:2019-07-11 06:13:51
【问题描述】:

重要 - Microsoft 即将停用 AppCenter Push,您仍然可以按照我在下面的回答来实施它。或者,您可以在 How to implement Push Notification in Xamarin with Firebase and Apple Push Notification with C# backend 关注我关于使用 Firebase 和 Apple 推送通知的新帖子。谢谢。

我一直在阅读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 成员分享是件好事。

【问题讨论】:

  • Microsoft 将停用 Push 服务 (docs.microsoft.com/en-us/appcenter/migration/push/) :( 建议您不要再使用它了。

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


【解决方案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
        {
            //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;
        }
    }
}

要使用它,只需在您的程序中执行以下操作

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

【讨论】:

  • 两天后不要忘记标记自己的答案,它会帮助有类似问题的其他人。
【解决方案2】:

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

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;  

【讨论】:

  • 这么久终于找到我的错字并更正了,谢谢。
【解决方案3】:

如果您想为目标用户(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);

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-01
    • 2020-07-10
    • 1970-01-01
    • 2020-04-07
    • 2018-11-01
    • 2013-12-05
    • 1970-01-01
    相关资源
    最近更新 更多