# Meetup Group & Event Monitor - Schedules and Changes (`maydit/meetup-group-event-monitor`) Actor

Track public Meetup events from group pages or event URLs. Export schedules, venue, group member totals and going counts, with saved changes and honest first-page coverage.

- **URL**: https://apify.com/maydit/meetup-group-event-monitor.md
- **Developed by:** [Brandt May](https://apify.com/maydit) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 saved observations

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Meetup Group & Event Monitor

**Follow public community events without repeatedly opening group pages.** Turn Meetup group or event URLs into structured schedules, venues, public group size and aggregate going counts, then compare saved observations to see what changed.

Useful for community teams, event researchers and agencies maintaining a focused local or industry watchlist. Each event has a stable source identity, its original time offset, a source link and an observation timestamp. No attendee identities or member lists are collected.

### Start with a public group

```json
{
  "groupUrls": ["https://www.meetup.com/orlandopython/"],
  "maxResults": 5
}
```

Click **Start**, then open the **Dataset** for event records. Use **Coverage and diagnostics** to see how many events the public page exposed, and **Readable run report** for a concise run summary.

No Meetup login, API key or proxy setup is required. Empty input uses this public sample. Upcoming events naturally change; a group with no active events can correctly return zero rows with successful, empty coverage.

### A practical event change feed

| Question | Fields to use |
| --- | --- |
| Did the schedule move? | `startDate`, `endDate`, `timeZone`, `scheduleChanged` and previous values |
| Is the event in person or online? | Source `eventType` and public venue fields |
| Did interest change? | Aggregate `goingCount`, `goingCountDelta` and observation time |
| Is the community growing? | Public `groupMemberCount` and its delta on each event observation |
| Did the source report cancellation? | Source `eventStatus`; no cancellation inferred from a missing listing |
| Was the check complete? | `SUMMARY.outputComplete`, `selectionTruncated` and unreached sources |

Each saved event is one result. Its group metadata and venue are included in the row. Going counts represent public RSVPs, not verified physical attendance.

### Three ready-to-run recipes

#### 1. Orlando Python events

```json
{"groupUrls":["https://www.meetup.com/orlandopython/"],"maxResults":5}
```

#### 2. Chennai Python events

```json
{"groupUrls":["https://www.meetup.com/chennaipy/"],"maxResults":5}
```

#### 3. A two-community watchlist

```json
{
  "groupUrls": [
    "https://www.meetup.com/orlandopython/",
    "https://www.meetup.com/chennaipy/"
  ],
  "maxResults": 10
}
```

For an event already known to your workflow, place its exact `https://www.meetup.com/group/events/id/` URL in `eventUrls`. If the same event is also discovered from a group, it is deduplicated before output.

### Monitor changes over time

```json
{
  "groupUrls": [
    "https://www.meetup.com/orlandopython/",
    "https://www.meetup.com/chennaipy/"
  ],
  "maxEvents": 10,
  "maxResults": 10,
  "comparePrevious": true,
  "onlyChanges": true,
  "snapshotName": "python-community-watch"
}
```

The first complete run saves a baseline and emits `new` events. Later runs compare stable event fields and include `changedFields` and `previous`. Unchanged events are skipped when `onlyChanges` is true. Use one writer at a time for the same scope and snapshot name.

History is scoped to the normalized group/event selection, `maxEvents` and snapshot name. Failed reads, unvisited details, incomplete group windows, time limits and spending limits preserve the prior baseline. Saved rows from a partial run remain useful observations, but they are not a complete watchlist check.

### Important group-window limit

The Actor reads the **active-event connection embedded in a public group page**, commonly the first four events. It does not paginate, call private APIs or scan every event object in the page cache. Past events and unrelated cached records are not treated as upcoming events.

`totalActiveEvents` and `embeddedEvents` in source coverage make the difference visible. If the group reports more active events than are embedded, `selectionTruncated` is true, the run is partial, and comparison history does not advance. Use explicit event URLs for a known-event watchlist when you need complete comparison coverage for a larger group. Raising `maxEvents` cannot expand the source's embedded window.

### Input reference

| Field | Default | Purpose |
| --- | --- | --- |
| `groupUrls` | Sample group | Up to 5 exact public group URLs |
| `eventUrls` | Empty | Up to 20 exact public event URLs; direct details take priority |
| `maxEvents` | 10 | Maximum selected event detail pages, 1–20 |
| `maxResults` | 10 | Maximum confirmed event rows saved, 1–20 |
| `comparePrevious` | false | Compare with the last complete saved baseline |
| `onlyChanges` | false | Enable comparison and skip unchanged observations |
| `snapshotName` | `default` | Independent history label; letters, numbers, underscores or hyphens |
| `maxRunSeconds` | 120 | Shared 30–120 second collection budget |

Source campaign parameters are removed; authentication and unsupported query parameters are rejected. Only `www.meetup.com` group and event paths are supported. City-wide search, keyword discovery and attendee scraping are outside scope.

### Understand the records

Dates retain the source's explicit UTC offset; the group timezone is recorded separately. A venue may be missing for online events or withheld until registration. Missing venue, fee or going count remains `null`; a missing fee never means that an event is free. Source fees, if supplied in the supported public structure, retain amount and currency and are not a checkout quote.

Member totals are public group aggregates. An event row may show the same group total as another event in that group; do not sum those totals as unique people. A disappearing event or an empty group list never triggers an invented cancellation or deletion row. Explicit event details can still represent a past event.

### Output, API and integrations

Export Dataset rows as JSON or CSV. JSON preserves the nested venue and previous observation. The `SUMMARY` record reports discovery and detail reads separately as `groupPagesSucceeded` and `eventPagesSucceeded`; `sourcesSucceeded` counts both kinds of successful page reads. `requestedSources` counts user-supplied URLs. The `RUN_REPORT` HTML output presents this coverage without adding billed event rows.

Save a task for your watchlist and connect a schedule or integration to a spreadsheet, community dashboard or internal notification workflow. The same JSON input works through the [Apify API](https://docs.apify.com/api/v2) or [Apify MCP server](https://docs.apify.com/platform/integrations/mcp). Include the source URL and observation time when an AI agent summarizes a changed event.

Pricing is **$0.00005 per Actor start plus $0.003 per saved event observation ($3 per 1,000)**. Check the Actor's live Pricing tab for the current offer. Unchanged observations skipped by `onlyChanges` incur no result event; platform usage may still apply under your plan. Set a maximum charge in Run options to bound spending.

### Source boundaries and support

The Actor respects robots directives and reads public page data only. It does not sign in, bypass access restrictions, join groups, RSVP, contact members or collect attendee identities, member profiles or access tokens. Unsupported and blocked pages are reported as failures instead of silently appearing empty.

Upstream content can be stale or change shape. Review coverage before treating a successful platform run as a complete observation. For help, open an Actor issue with the public URL, run ID and expected field, without credentials. Find related tools at [Mayd It Data Tools](https://mayd-it.com/data-tools/).

# Actor input Schema

## `groupUrls` (type: `array`):

Up to 5 public www.meetup.com/group/ URLs. Reads the active-event window embedded on the group page, usually up to 4 events. If the group has more events, SUMMARY is partial and history does not advance.

## `eventUrls` (type: `array`):

Up to 20 exact public www.meetup.com/group/events/id/ URLs. Fetches those details directly. Empty group and event lists use the sample group.

## `maxEvents` (type: `integer`):

Bounds detail requests across the deduplicated watchlist. Explicit event URLs take priority. Unread selected events remain reported as partial coverage.

## `maxResults` (type: `integer`):

Maximum confirmed rows saved. Nested versions, tiers and group metadata are included in the row. If requested observations remain, history is preserved and SUMMARY reports partial coverage.

## `comparePrevious` (type: `boolean`):

Compare with the last complete successful observation under the same input selection and snapshot name. First comparison establishes a baseline.

## `onlyChanges` (type: `boolean`):

Enables comparison. Unchanged observations are skipped and incur no result event; an unchanged run may correctly produce zero rows.

## `snapshotName` (type: `string`):

Use 1-80 letters, numbers, underscores or hyphens. One active writer per watchlist and snapshot; new names create independent history.

## `maxRunSeconds` (type: `integer`):

Shared deadline for all source reads and output. Failed, partial or spending-limited runs do not advance comparison history.

## Actor input object example

```json
{
  "groupUrls": [
    "https://www.meetup.com/orlandopython/"
  ],
  "eventUrls": [],
  "maxEvents": 10,
  "maxResults": 10,
  "comparePrevious": false,
  "onlyChanges": false,
  "snapshotName": "default",
  "maxRunSeconds": 120
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `report` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "groupUrls": [
        "https://www.meetup.com/orlandopython/"
    ],
    "eventUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("maydit/meetup-group-event-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "groupUrls": ["https://www.meetup.com/orlandopython/"],
    "eventUrls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("maydit/meetup-group-event-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "groupUrls": [
    "https://www.meetup.com/orlandopython/"
  ],
  "eventUrls": []
}' |
apify call maydit/meetup-group-event-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maydit/meetup-group-event-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/eD8Kh1fuQwRqXZ4hg/builds/eZDXugCMHRyGJfcCs/openapi.json
