slackapi / deno-slack-sdk

SDK for building Run on Slack apps using Deno
https://api.slack.com/automation
MIT License
155 stars 27 forks source link

Add time_to_live_attribute to datastore module #278

Closed mniemer closed 6 months ago

mniemer commented 6 months ago

Summary

This PR adds support for the AWS DynamoDB TimeToLive feature on Slack app datastores. This feature allows developers to identify an attribute in their datastore schema which serves as an expiration timestamp. In the background, DynamoDB will check for items which have this attribute populated with an epoch timestamp < now and delete them from the DynamoDB table.

To enable the feature, add time_to_live_attribute in the DefineDatastore function arguments and specify an attribute from the attributes map which has type Schema.slack.types.timestamp.

Example:

const SongDatastore = DefineDatastore({
  name: SONG_DATASTORE,
  primary_key: "id",
  time_to_live_attribute: "song_played_date",
  attributes: {
    id: {
      type: Schema.types.string,
    },
   ...
    song_played_date: {
      type: Schema.slack.types.timestamp,
    },
  },
});

Inclusion of the time_to_live_attribute is optional, and if it is not included, the time to live feature will not be enabled for the datastore.

Testing

Manual tests:

Special notes

Requirements

codecov[bot] commented 6 months ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Comparison is base (dd7985c) 98.15% compared to head (a5d1fc3) 98.15%.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #278 +/- ## ======================================= Coverage 98.15% 98.15% ======================================= Files 58 58 Lines 2280 2282 +2 Branches 147 147 ======================================= + Hits 2238 2240 +2 Misses 42 42 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

mniemer commented 6 months ago

What happens if a user set an attribute as time_to_live_attribute and does not give it a value at runtime... Should the attribute selected as being the time_to_live_attribute be set as a required field in typescript similar to how the primary key made required?

In this case, the item without the TTL attribute will not be eligible for deletion by Dynamo. I think this is a valid usage of the feature - in my own demo I've created a daily song recommender that uses the attribute song_played_date as the TTL attribute:

const SongDatastore = DefineDatastore({
  name: SONG_DATASTORE,
  primary_key: "id",
  time_to_live_attribute: "song_played_date",
  attributes: {
    id: {
      type: Schema.types.string,
    },
...
    song_played_date: {
      type: Schema.slack.types.timestamp,
    },
  },
});

I have two custom functions, one where users of the app submit songs, and another where the app picks a song from the suggestion list to recommend to the users. The song_played_date attribute is only added once the song is recommended by the second function, marking it as ready for expiration:

    // Add song_played_date to song datastore
    const played_date = Math.trunc(Date.now().valueOf() / 1000);
    const songPutResponse = await client.apps.datastore.put({
      datastore: SONG_DATASTORE,
      item: {
        id: song.id,
...
        song_played_date: played_date,
      },
    });
WilliamBergamin commented 6 months ago

Ohh I see, this is a great implementation 💯 if no value is passed to the attribute selected as the time_to_live_attribute then the entry is not eligible for deletion