0

I am making a reminder feature. And triggering it in Azure function with Time trigger set to every minute by calling Get method of notify api. Do i need to code something about timezone? i think azure is using UTC while my timezone is GMT+8

It is working when i put the code outside the if date matches block like this.

 foreach (var reminder in userstate.Reminders)
        {
            await turnContext.SendActivityAsync($"Reminding you to {reminder.Subject}");

            if (reminder.DateAndTime == DateTime.Now)
            {

            }
        }

But when i put it inside it is not triggering.

    namespace SabikoBotV2.Controllers
    {
    [Route("api/notify")]

    public class NotifyController : ControllerBase
    {
        private readonly IBotFrameworkHttpAdapter _adapter;
        private readonly string _appId;
        private readonly ConcurrentDictionary<string, ConversationReference> _conversationReferences;
        private readonly IStatePropertyAccessor<BasicUserState> _userProfileAccessor;

        public NotifyController(UserState userState, IBotFrameworkHttpAdapter adapter, ICredentialProvider credentials, ConcurrentDictionary<string, ConversationReference> conversationReferences)
        {
            _userProfileAccessor = userState.CreateProperty<BasicUserState>("UserProfile");

            _adapter = adapter;
            _conversationReferences = conversationReferences;
            _appId = ((SimpleCredentialProvider)credentials).AppId;

            if (string.IsNullOrEmpty(_appId))
            {
                _appId = Guid.NewGuid().ToString(); //if no AppId, use a random Guid
            }
        }

        public async Task<IActionResult> Get()
        {

            try
            {
                foreach (var conversationReference in _conversationReferences.Values)
                {
                    await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, conversationReference, BotCallback, default(CancellationToken));

                }

                return new ContentResult()
                {
                    Content = "<html><body><h1>Proactive messages have been sent.</h1></body></html>",
                    ContentType = "text/html",
                    StatusCode = (int)HttpStatusCode.OK,
                };
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }

        private async Task BotCallback(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            var userstate = await _userProfileAccessor.GetAsync(turnContext, () => new BasicUserState(), cancellationToken);

            if(userstate.Reminders != null)
            {
                foreach (var reminder in userstate.Reminders)
                {
                    if (reminder.DateAndTime == DateTime.Now)
                    {
                        await turnContext.SendActivityAsync($"Reminding you to {reminder.Subject}");
                    }
                }
            }
        }
    }
}

Azure function

enter image description here

user10860402
  • 912
  • 1
  • 10
  • 34

1 Answers1

0

The main issue here may be your if check: if (reminder.DateAndTime == DateTime.Now)

DateTimes equals only when they are strictly equal, so keep in mind that "2019-10-09 13:28:55.26566" is different from "2019-10-09 13:28:55.11876" for example.

Here your date check must be made based on a granularity that is logical compared to how often reminders can be setup.

If the granularity is by minute, then when your code is triggered, compare your reminder date (year + month + day + hour + minute) and the current date (year + month + day + hour + minute).

You can do this check by several ways, for example:

  • Comparing differences in minutes: reminder.DateAndTime.Subtract(DateTime.Now) <= TimeSpan.FromMinutes(1)
  • Comparing dates in string format
  • ...
Nicolas R
  • 13,812
  • 2
  • 28
  • 57
  • I think your right sir the seconds has something to do with it. But also the DateTime.Now azure function is sending me is 8 hours late which i think is UTC. but my bot saves time in GMT+8. i know i am triggering every minute so that is irrelevant but might need to sync them in the future – user10860402 Oct 09 '19 at 12:42
  • you are right, you have to take the timezone into account. See this post: https://stackoverflow.com/questions/31220481/how-to-compare-datetime-values-taking-into-account-timezone – Nicolas R Oct 09 '19 at 12:44
  • Thank you sir Nicolas can i ask one more thing, is what i am doing about the trigger okay? would it cost so high in cosmosDB if am accessing userstate every minute? and also does azure function cost more if a trigger every minute compared to everyday? – user10860402 Oct 09 '19 at 15:09
  • It will depend on many aspects, for example on the Function it will depend on the pricing that you have chosen (Consumption plan vs app service plan) – Nicolas R Oct 09 '19 at 15:31