-
Create a package under
hunts/yourhunt/ -
Implement the required
Huntinterface (6 methods):Name() stringInit(ctx, lookup) errorSources() []core.SourceDedupeKey(raw RawItem) stringEvaluator() core.EvaluatorDefaultSchedule() core.Schedule
-
Optionally implement any of the 6 optional interfaces:
Grouper— batch opportunities before evaluation (e.g., weekly grouping)ReEvaluator— re-evaluate previously scored opportunities (e.g., weather changes)Briefer— group evaluations for notification and synthesize briefingsExpirer— custom expiration logic (default: expire when StartTime is past)WebHunt— custom card rendering and feedback optionsNotifyHunt— custom Discord notification formatting
-
Register your hunt in
cmd/opportunity-hunter/main.go:func registeredHunts() []core.Hunt { return []core.Hunt{ &yourhunt.YourHunt{}, // ... } }
-
Add environment variables to
.env.example
Sources implement core.Source:
type Source interface {
Name() string
Scan(ctx context.Context, region ScanRegion) ([]RawItem, error)
}Map external API responses to core.RawItem. Store the original response in RawJSON.
- Use
testutil.NewTestDB(t)for in-memory SQLite - Use
testutil.FakeEvaluatorfor configurable evaluation results - Use
testutil.FakeNotifierto capture notification actions - Use
hunts/fake.FakeHuntfor pipeline integration tests - Run all tests:
make test
- Standard Go conventions
go vetfor linting- No external test frameworks — stdlib
testingonly