# Fetcher Job Scheduler

This project demonstrates a lightweight job runner where each job defines its own execution interval directly in its source file.

## Structure

- `main.go` wires signal handling and starts the scheduler.
- `internal/scheduler` contains the runner implementation that executes jobs on their declared cadence.
- `jobs` hosts job definitions; each job registers itself during package initialization.

## Running

```bash
go run .
```

You should see the example job print a timestamp about every five seconds.

The scheduler will also start the clan monitor job once all required environment variables are present.

## Creating a Job

1. Add a new file under `jobs`, for example `jobs/fetch_users.go`.
2. Declare any interval value in that file (e.g., `const fetchInterval = 10 * time.Second`).
3. Implement the `jobs.Job` interface and call `Register` in an `init` function.

```go
package jobs

import (
    "context"
    "time"
)

const fetchInterval = 10 * time.Second

func init() {
    Register(&FetchUsersJob{})
}

type FetchUsersJob struct{}

func (FetchUsersJob) Name() string { return "fetch_users" }
func (FetchUsersJob) Interval() time.Duration { return fetchInterval }

func (FetchUsersJob) Run(ctx context.Context) error {
    // Perform work here.
    return nil
}
```

The scheduler automatically discovers and runs the new job without additional wiring.

## Clan Monitor Job

The `clan_monitor` job checks your Clash of Clans clan members and sends a Discord DM when someone has been offline for at least two days. The job runs every 30 minutes and requires the following environment variables:

- `COC_API_TOKEN`: Clash of Clans developer API token.
- `COC_CLAN_TAG`: Clan tag (include the leading `#`, e.g. `#123ABC`).
- `DISCORD_BOT_TOKEN`: Discord bot token with permission to create DMs.
- `DISCORD_RECIPIENT_ID`: Your Discord user ID to receive notifications.

Example invocation:

```bash
export COC_API_TOKEN="..."
export COC_CLAN_TAG="#123ABC"
export DISCORD_BOT_TOKEN="..."
export DISCORD_RECIPIENT_ID="1234567890"
go run .
```

If any value is missing, the job logs `clan monitor job disabled: <reason>` during startup and will not register.

## Docker Image

Build the container image:

```bash
docker build -t fetcher .
```

Run with the required environment variables:

```bash
docker run --rm \
  -e COC_API_TOKEN="..." \
  -e COC_CLAN_TAG="#123ABC" \
  -e DISCORD_BOT_TOKEN="..." \
  -e DISCORD_RECIPIENT_ID="1234567890" \
  fetcher
```
