stoiveyp / Alexa.NET.Reminders

Small helper library for Alexa.NET based skills to access the reminders API
MIT License
4 stars 1 forks source link

INVALID_TRIGGER_SCHEDULED_TIME_FORMAT #6

Open bauchschuss opened 5 years ago

bauchschuss commented 5 years ago

Hi, when i was trying to add reminders to my skill i maybe found a bug in your code. It concens the JsonConvert method in the RemindersClient. When dates (ScheduledTime or RequestTime) are serialized your code produces something like 2019-02-21T06:50:56.614029Z which leads to an INVALID_TRIGGER_SCHEDULED_TIME_FORMAT

Amazon documentation says that date times need to be in a format like 2019-02-21T06:50:56.614. As a result of this i extended your ReminderClient class like this:

public class RemindersClientExt : RemindersClient
    {
        private ICustomLogger Logger { get; set; }
        public RemindersClientExt(SkillRequest request, ICustomLogger logger) : this(
            request.Context.System.ApiEndpoint,
            request.Context.System.ApiAccessToken,
            logger)
        { }

        public RemindersClientExt(string endpointUrl, string accessToken, ICustomLogger logger)
            :base(endpointUrl, accessToken)
        {
            Logger = logger;
        }

        public RemindersClientExt(HttpClient client, ICustomLogger logger)
            :base(client)
        {
            Logger = logger;
        }

        public new async Task<ReminderChangedResponse> Create(Reminder reminder)
        {
            var message = await Client.PostAsync(
                new Uri("/v1/alerts/reminders", UriKind.Relative),
                new StringContent(SerializeReminder(reminder), Encoding.UTF8, "application/json"));

            if (message.StatusCode != HttpStatusCode.Created)
            {
                var body = await message.Content.ReadAsStringAsync();
                throw new InvalidOperationException($"Unexpected result: Status {message.StatusCode}, body: {body}");
            }

            return JsonConvert.DeserializeObject<ReminderChangedResponse>(await message.Content.ReadAsStringAsync());
        }

        public new async Task<ReminderChangedResponse> Update(string alertToken, Reminder reminder)
        {
            var message = await Client.PutAsync(
                new Uri("/v1/alerts/reminders/" + System.Net.WebUtility.UrlEncode(alertToken), UriKind.Relative),
                new StringContent(SerializeReminder(reminder), Encoding.UTF8, "application/json"));

            if (message.StatusCode != HttpStatusCode.OK)
            {
                var body = await message.Content.ReadAsStringAsync();
                throw new InvalidOperationException($"Unexpected result: Status {message.StatusCode}, body:{body}");
            }

            return JsonConvert.DeserializeObject<ReminderChangedResponse>(await message.Content.ReadAsStringAsync());
        }

        private string SerializeReminder(Reminder reminder)
        {
            var serializerSettings = new JsonSerializerSettings { DateFormatString = "yyyy-MM-ddTH:mm:ss.fff" };

            //var serializedReminder = JsonConvert.SerializeObject(reminder, serializerSettings);
            var serializedReminder = JsonConvert.SerializeObject(reminder);
            Logger.DebugFormat("SERIALIZATION of REMINDER object: {0}", serializedReminder);

            return serializedReminder;
        }
    }

With the JsonSerializerSettings used in the above code the creation of reminders works like expected. Maybe you can reproduce this issue by using DateTime.UtcNow in your code instead of parsing the DateTime from a correct DateString.

best regards bauchschuss