Giter Site home page Giter Site logo

Comments (5)

Phanabani avatar Phanabani commented on May 29, 2024

We can make a new database column to track birthday scheduling status. On the daily birthday schedule task, we can set all scheduled birthdays to 1, then when we send the birthday notif, set it to 2, and on the next day we can reset them to 0.

Actually, I don't think we even need two tiers. We can just use a bool to represent "the birthday scheduled this day was already sent". Then, when scheduling the birthdays, if there are any for the day set to true, we can ignore them.

from sandpiper.

Phanabani avatar Phanabani commented on May 29, 2024

After starting to write unit tests, I realized this was not complete. The behavior I want is:

  • When the bot starts, there may be birthdays that should've been sent but were missed
  • These birthdays should only be sent if now is still their birthday in their timezone

Our method using a boolean was_sent can only work if the birthday we missed is still today in UTC. This will not always be the case, like if a Korean user (8 hours ahead of UTC) has a birthday and we start Sandpiper at midnight UTC.

Hang on. Thinking again. What about this algorithm (keeping the boolean was_sent):

  • Get all birthdays yesterday, today, and tomorrow (in UTC), skipping those already sent
  • Still do the 0 <= localized_midnight < 24h
  • Otherwise, if localized_now.date() == birthday and localized_midnight < now, schedule the notification immediately. We can actually use the negative delta to signal Sandpiper to add a little extra blurb like "I'm a little late but ..."

from sandpiper.

Phanabani avatar Phanabani commented on May 29, 2024

I had opened a new branch and changed birthday_notification_sent boolean to birthday_notification_status with an enum ScheduledStatus (unscheduled, scheduled, complete), similar to my first idea commented above before first closing the issue. However, I think I might discard that branch because I think we can still achieve everything just using the boolean. Knowing whether the birthday was scheduled won't provide any useful information. All we need to know is:

  • Was the message sent? If so, do not sent it again.
  • Otherwise, if we've passed their midnight, is it still their birthday in their timezone? If so, we can send it now.

If we were only using the scheduled status to ensure we hit bypassed midnights, we'd actually be at risk of missing birthdays that weren't scheduled by a previous runtime but still occurred today.

from sandpiper.

Phanabani avatar Phanabani commented on May 29, 2024

There is a way with this method though that we can get duplicate birthday notifs.

  • Sandpiper sends a birthday notif and marks it as sent
  • At the end of the 24 hour cycle (which could be a few minutes after the notif), she unmarks it
  • Sandpiper is restarted
  • When she starts back up, she sees this birthday is still today and it "was never sent", so she sends it again

This could be mitigated by storing the datetime the message was sent. I don't think the marking/unmarking logic is feasible because we can never trust whether the notif was sent. We need something persistent.

With the stored "last_notified_datetime" field, we can use the same algorithm as above, but just skip when the last notification was... within the last 24 hours? Same local date?

from sandpiper.

Phanabani avatar Phanabani commented on May 29, 2024

This last_notified_datetime could also be used in a birthday abuse mitigation strategy (#57) if we decide to implement that.

from sandpiper.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.