Skip to main content Link Search Menu Expand Document (external link)

Activities window

Table Of Contents

Overview

An Activity Window (window) is a group of properties that describe a range of Activities to retrieve from Reddit and how to filter them.

The main components of an Activity Window:

  • Range – How many Activities (count) or what time period (duration) of Activities to fetch
  • Type of Activities – When fetching from an Author’s history, should it return overview (any Activities), just Submissions, or just Comments?
  • Filters – How the retrieved Activities should be filtered before returning them to a Rule

As an example, if you want to run a Recent Activity Rule to check if a user has had activity in /r/mealtimevideos you also need to define what range of activities you want to look at from that user’s history.

Lifecycle

Understanding the lifecycle for how CM uses the Activity Window to retrieve Activities is important to effectively using it.

graph TD
    RangReq["Determine Range requirements (Parse `count` and `duration` values)"] --> EmptyList>Create empty Activities List]
    EmptyList --> Fetch>"Fetch Activities chunk (1 API Call)"]
    Fetch --> PreFilter>Invoke `pre` filter on Activities from chunk]
    PreFilter --> Add[Add filtered chunk to Activities list] 
    Add --> CheckRange>Check Range Satisfaction]
    CheckRange -->|`count` Range| CountReq[Are there `count` # of Activities?]
    CheckRange -->|`duration` Range| DurationReq[Is the oldest Activity `duration` old?]
    CheckRange -->|`count` and `duration` Range| CountDurReq[Is either `count` and/or `duration` satisfied?]


    CountReq -->|No| Fetch
    DurationReq -->|No| Fetch
    CountDurReq -->|No| Fetch

    CountReq -->|Yes| FetchDone
    DurationReq -->|Yes| FetchDone
    CountDurReq -->|Yes| FetchDone

    FetchDone[Fetch Complete] --> PostFilter>Invoke `post` filter on all Activities]
    PostFilter --> Return>Return Activities to Rule]

    click PreFilter href "#pre-filter"
    click PostFilter href "#post-filter"
    click CountReq href "#count"
    click DurationReq href "#duration"
    click CountDurReq href "#specifying-range"

Range

There are two types of values that can be used when defining a range:

Count

This is the number of activities you want to retrieve. It’s straightforward – if you want to look at the last 100 activities for a user you can use 100 as the value.

Shorthand

If count is the only property you want to define (leaving everything else as default) then window can be defined with just this value:

window: 70 # retrieve 70 activities

Otherwise, use the count property on a full window object:

window:
  count: 70 # retrieve 70 activities
  ...

Duration

A duration of time between which all activities will be retrieved. This is a relative value that calculates the actual range based on the duration of time subtracted from when the rule is run.

For example:

  • Today is July 15th
  • You define a duration of 10 days

Then the range of activities to be retrieved will be between July 5th and July 15th (10 days).

Shorthand

If a Duration string is the only property you want to define (leaving everything else as default) then window can be defined with just this value:

window: '9 days' # retrieve last 9 days of activities

Otherwise, use the duration property on a full window object:

window:
  duration: '9 days'
  ...

Duration Types

The value used to define the duration can be one of these two types:

A string consisting of

Examples:

  • 9 days
  • 14 hours
  • 80 seconds

You can ensure your string is valid by testing it here.

As ISO 8601 duration string

If you’re a real nerd you can also use a standard duration string.

Examples

  • PT15M (15 minutes)

Ensure your string is valid by testing it here.

Duration Object

If you need to specify multiple units of time for your duration you can instead provide a Dayjs duration object consisting of Dayjs unit-values.

window:
  duration:
    days: 4
    hours: 6
    minutes: 20

Specifying Range

You may use one or both range properties.

If both range properties are specified then the value satisfyOn determines how the final range is determined

Using satisfyOn: any (default)

If any then Activities will be retrieved until one of the range properties is met, whichever occurs first.

window:
  count: 80
  duration: 90 days
  satisfyOn: any

Activities are retrieved in chunks of 100 (or count, whichever is smaller)

  • If 90 days of activities returns only 40 activities => returns 40 activities
  • If 80 activities is only 20 days of range => 80 activities

Using satisfyOn: all

If all then both ranges must be satisfied. Effectively, whichever range produces the most Activities will be the one that is used.

window:
  count: 100
  duration: 90 days
  satisfyOn: all

Activities are retrieved in chunks of 100 (or count, whichever is smaller)

  • If at 90 days of activities => 40 activities retrieved
    • continue retrieving results until 100 activities
    • so range is >90 days of activities
  • If at 100 activities => 20 days of activities retrieved
    • continue retrieving results until 90 days of range
    • so results in >100 activities

Types of Activities

When retrieving an Author’s history the window can specify if it should return all Activities (overview), just Comments, or just Submissions, using the fetch property:

window:
  # defaults to 'overview'
  fetch: 'submission' # must be one of: overview, comment, submission

Filters

Activity Window can also specify Item and Subreddit Filters to filter the Activities retrieved from Reddit before they are returned to a Rule.

Activities can be filtered during (pre) retrieval or after (post) retrieval. When, during the window lifecycle, the Activities are filtered can change the set of Activities returned to a Rule drastically.

Filter Properties

Regardless of when you are filtering Activities the shape of the filter is the same. Filter properties:

In this example the filter only returns Activities:

  • With a subreddit that
    • Is from the subreddit /r/mealtimevideos OR
    • Has a name that matches the regex /ask.*/i (starts with ask) OR
    • Is marked as NSFW
  • AND if the Activity is a Submission:
    • must be self text
  • AND if the Activity is a Comment (because activityState is defined and commentState is not):
    • Comment is NOT removed
subreddits:
  include:
    - 'mealtimevideos'
    - '/ask.*/i'
    - over18: true
      
submissionState:
  include:
    - is_self: true

activityState:
  exclude:
    - removed: false

Filter Lifecycle

Filters can be independently specified for two different “locations” during the window lifecycle using the filterOn property.

pre Filter

pre will filter Activities from each API call, before they are added to the full list of retrieved Activities and, most importantly, before CM checks if Range conditions have been satisfied. See the Lifecycle Diagram.

This is useful when you want the Range conditions to be applied to an “already filtered” list of Activities – as opposed to afterwards (like post).

max restriction

However, pre introduces the possibility of near impossible range conditions.

For example, if you want 200 activities from a subreddit a user has never created activities in then CM would fetch the user’s entire history before finishing since each chunk of Activities would be filtered to 0.

To prevent this scenario all pre filters must also specify a max range that tell CM:

if X range of non-filtered Activities is reached stop immediately

pre Example

Let’s follow an example scenario where you want the last 200 activities a user has in /r/mealtimevideos

window:
  count: 200
  filterOn:
    pre:
      subreddits:
        include:
          - mealtimevideos
      max: 400
  • CM fetches the first chunk of 100 Activities (100 total unfiltered)
    • pre Filter finds 70 of those 100 are from /r/mealtimevideos => Total Filtered Activities 70
    • CM Checks range condition => 70 is less than 200
    • CM Checks max condition => 100 unfiltered is less than 400
  • CM fetches second chunk of 100 Activities (200 total unfiltered)
    • pre Filter finds another 70 of those 100 are from /r/mealtimevideos => Total Filtered Activities 140
    • CM Checks range condition => 140 is less than 200
    • CM Checks max condition => 200 unfiltered is less than 400
  • CM fetches third chunk of 100 activities (300 total unfiltered)
    • pre Filter finds 90 of those 100 are from /r/mealtimevideos => Total Filtered Activities 230
    • CM checks range condition => 230 is more than 200
    • CM Checks max condition => 300 unfiltered is less than 400

CM is done fetching activities with 230 Filtered Activities

Now let’s look at the same scenario but max is hit:

  • CM fetches the first chunk of 100 Activities (100 total unfiltered)
    • pre Filter finds 10 of those 100 are from /r/mealtimevideos => Total Filtered Activities 10
    • CM Checks range condition => 10 is less than 200
    • CM Checks max condition => 100 unfiltered is less than 400
  • CM fetches second chunk of 100 Activities (200 total unfiltered)
    • pre Filter finds another 15 of those 100 are from /r/mealtimevideos => Total Filtered Activities 25
    • CM Checks range condition => 25 is less than 200
    • CM Checks max condition => 200 unfiltered is less than 400
  • CM fetches third chunk of 100 activities (300 total unfiltered)
    • pre Filter finds 5 of those 100 are from /r/mealtimevideos => Total Filtered Activities 30
    • CM checks range condition => 30 is less than 200
    • CM Checks max condition => 300 unfiltered is less than 400
  • CM fetches fourth chunk of 100 activities (400 total unfiltered)
    • pre Filter finds 0 of those 100 are from /r/mealtimevideos => Total Filtered Activities 30
    • CM checks range condition => 30 is less than 200
    • CM Checks max condition => 400 unfiltered is NOT less than 400
      • CM stops fetching due to max condition hit

CM is done fetching activities with 30 Filtered Activities

post Filter

post will filter the full list of Activities after range conditions are satisfied. This also means it receives the list of Activities filtered by the pre filter, if one is defined.

The list returned by post is what the Rule receives.

Example

Let’s follow an example scenario where you want to get the last 200 activities from a User’s history and then return any of those 200 that were made in /r/mealtimevideos – contrast this wording to the pre example

window:
  count: 200
  filterOn:
    post:
      subreddits:
        include:
          - mealtimevideos
  • CM fetches the first chunk of 100 Activities (100 total unfiltered)
    • CM checks range condition => 100 is less than 200
  • CM fetches the second chunk of 100 Activities (200 total unfiltered)
    • CM checks range condition => 200 is equal to 200
  • CM is done fetching activities with 200 unfiltered Activities
    • post filter finds 10 of those 200 are from /r/mealtimevideos
    • CM returns 10 Activities to the Rule

More Examples

Count Examples

Get last 100 activities in a User’s history

window: 100

or

window:
  count: 100

Duration Examples

Get last 2 weeks of a User’s history

window: '2 weeks'

or

window:
  duration: '2 weeks'

Get last 24 hours and 30 minutes of User’s history

window:
  duration:
    hours: 24
    minutes: 30

Count and Duration Examples

Get EITHER last 6 months or last 200 activities of User’s history

Whichever is satisifed first

window:
  count: 200
  duration: '6 months'

Get AT LEAST the last 6 months and last 200 activities of User’s history

Both must be satisifed

window:
  count: 200
  duration: '6 months'
  satisfyOn: 'all'

Activity Type Examples

Get the last 200 submissions from User’s history

window:
  count: 200
  fetch: 'submission'

Get the last 200 comments from User’s history

window:
  count: 200
  fetch: 'comment'

Get the last 200 activities (submissions or comments) from User’s history

window:
  count: 200
  fetch: 'overview' # or do not include 'fetch' at all, this is the default

Filter Examples

Get the all activities from NSFW subreddits in the User’s last 200 activities

window:
  count: 200
  filterOn:
    post:
      subreddits:
        include:
          - over18: true

Get the all comments from NSFW subreddits where user is OP, in the User’s last 200 activities

window:
  count: 200
  fetch: 'comment'
  filterOn:
    post:
      subreddits:
        include:
          - over18: true
      commentState:
        include:
          - op: true

Get the last 200 self-text submissions from a User’s history and return any from ask* subreddits

window:
  count: 200
  fetch: 'submission'
  filterOn:
    pre:
      submissionState:
        include:
          - is_self: true
      max: 500
    post:
      subreddits:
        include:
          - '/ask.*/i'