如何实现 AppCenter Push API?

tea*_*eng 2 c# asp.net push-notification xamarin visual-studio-app-center

重要-微软很快就会停用 AppCenter Push,您仍然可以按照我在下面的回答来实现它。或者,您可以关注我在如何使用 Firebase 和 Apple 推送通知在 Xamarin 中使用 Firebase 和 Apple 推送通知与 C# 后端有关使用 Firebase 和 Apple 推送通知的新帖子。谢谢你。

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

我阅读并实施了这个 https://www.andrewhoefling.com/Blog/Post/push-notifications-with-app-center-api-integration。他的解决方案提供了很好的开始,但不完整。

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

tea*_*eng 5

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

 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);
Run Code Online (Sandbox Code Playgroud)