Oregon Liquor Search Notification Service using the OLCC Liquor Search website, Go, and the nikoksr/notify library.
- Search Oregon Liquor Search for specific liquor items
- Search by product name or item code
- Multi-user support: Configure multiple users with individual preferences
- Notification condensing: Combine multiple findings into single notifications
- Configurable search radius based on zip code
- Automatic age verification handling
- Random user agent rotation to avoid detection
- Random delays between searches to simulate human behavior
- Multiple notification methods:
- Gotify (direct API integration)
- Slack
- Telegram
- Discord
- Pushover
- Pushbullet
- Configurable search interval
- One-time or continuous search mode
- Backward compatibility with existing single-user configurations
Dockerized GFL uses a final image based on Distroless Debian static since it includes minimal dependencies but most crucially ca-certificates (which are needed to POST notifications to HTTPS endpoints).
cp config.example.yaml config.yaml
# edit config.yaml
make build runcp config.example.yaml config.yaml
# edit config.yaml
make up# Clone the repository
git clone https://github.com/toozej/go-find-liquor.git
cd go-find-liquor
# Build the application
make local-buildGFL supports multiple users with individual search preferences. This is useful for:
- Shared installations: Multiple people using the same GFL instance
- Different search areas: Users in different zip codes
- Varied notification preferences: Some users want individual notifications, others prefer condensed
- Different liquor interests: Each user can search for their preferred items
-
Copy the example configuration:
cp config.example.yaml config.yaml
-
Edit the configuration to add your users:
# Global settings (shared by all users) interval: 6h verbose: true # Individual user configurations users: - name: "alice" items: ["Blanton's", "Eagle Rare"] zipcode: "97201" distance: 15 notifications: - type: gotify condense: false credential: token: "ALICE_TOKEN" - name: "bob" items: ["Buffalo Trace", "Weller"] zipcode: "97210" distance: 10 notifications: - type: slack condense: true credential: token: "BOB_TOKEN" channel_id: "BOB_CHANNEL"
-
Run GFL: The application will automatically manage searches for all configured users
If you have an existing single-user configuration, GFL will automatically migrate it:
- Your existing settings become a user named "default"
- All functionality is preserved
- You can add additional users to the same config file
- No manual migration required
GFL supports both single-user and multi-user configurations. You can configure it using a YAML configuration file, environment variables, or command-line flags.
GFL now supports multiple users with individual search preferences while sharing global settings like search intervals and logging configuration.
- Global Settings: Apply to all users (interval, verbose logging, user agent)
- User-Specific Settings: Each user has their own items, location, and notification preferences
- Notification Condensing: Each notification method can be configured to send individual notifications or condense multiple findings into a single message
Create a config.yaml file in the same directory as the executable:
cp config.example.yaml config.yaml
# Edit config.yaml to add your users and notification settings# Global settings
interval: 6h
verbose: true
# Multiple users with different preferences
users:
- name: "alice"
items:
- "Blanton's"
- "W.L. Weller Special Reserve"
zipcode: "97201"
distance: 15
notifications:
- type: gotify
endpoint: "https://gotify.example.com"
condense: false # Individual notifications
credential:
token: "ALICE_GOTIFY_TOKEN"
- name: "bob"
items:
- "Eagle Rare"
- "Buffalo Trace"
zipcode: "97210"
distance: 10
notifications:
- type: slack
condense: true # Condensed notifications
credential:
token: "BOB_SLACK_TOKEN"
channel_id: "BOB_SLACK_CHANNEL"GFL maintains backward compatibility with existing single-user configurations. If you have an existing config, it will be automatically migrated to the multi-user format with a user named "default".
Environment variables are supported for backward compatibility with the GFL_ prefix:
export GFL_ITEMS="Blanton's,Eagle Rare,Buffalo Trace"
export GFL_ZIPCODE="97201"
export GFL_DISTANCE="15"
export GFL_INTERVAL="6h"Note: Environment variables will create a single user configuration and are primarily for backward compatibility.
Basic options can be set using command-line flags:
# Run in debug mode
./out/go-find-liquor -d
# Use a specific config file (overrides default config.yaml)
./out/go-find-liquor -c /path/to/config.yaml
# Run search once and exit
./out/go-find-liquor -oEach notification method supports a condense option:
condense: false(default): Send separate notifications for each liquor item foundcondense: true: Combine all liquor findings from a single search run into one notification
Example condensed notification:
🥃 Liquor Found (3 items):
• Blanton's - Store A (5 miles)
• Eagle Rare - Store B (8 miles)
• Buffalo Trace - Store C (12 miles)
When upgrading from a single-user configuration, GFL will automatically:
- Detect the legacy format
- Create a new user named "default" with your existing settings
- Preserve all functionality while enabling multi-user capabilities
- Log the migration process for your awareness
You can then manually edit your config to add additional users or rename the default user.
make local-run
# or alternatively without using the provided Makefile
./out/go-find-liquor --once./out/go-find-liquor./out/go-find-liquor --config /path/to/config.yaml./out/go-find-liquor version./out/go-find-liquor man --dir /usr/local/share/man/man1GFL supports multiple notification methods. Each notification method supports the condense option to control whether multiple findings are combined into a single message.
notifications:
- type: gotify
endpoint: "https://gotify.example.com"
condense: false # Send individual notifications (default)
credential:
token: "YOUR_GOTIFY_TOKEN"notifications:
- type: slack
condense: true # Combine multiple findings into one message
credential:
token: "YOUR_SLACK_TOKEN"
channel_id: "https://exampleorg.slack.com/archives/XXXXXXXXXXXXXXXXXXXXXXXX"notifications:
- type: telegram
condense: false
credential:
token: "YOUR_TELEGRAM_BOT_TOKEN"
chat_id: "YOUR_CHAT_ID"notifications:
- type: discord
condense: true
credential:
webhook_url: "https://discord.com/api/webhooks/000000000000000000/XXXXXXXXXXXXXXXXXXXXX"notifications:
- type: pushover
condense: false
credential:
token: "YOUR_PUSHOVER_TOKEN"
receipient_id: "XXXXXXXXXXXXX"notifications:
- type: pushbullet
condense: true
credential:
token: "YOUR_PUSHBULLET_TOKEN"
device_nickname: "XXXXXXXXXXXXX"- Individual Notifications (
condense: false): Each liquor item found generates a separate notification - Condensed Notifications (
condense: true): All liquor items found in a single search run are combined into one notification with a list of all items
go-find-liquor, or GFL for short, was built since it is increasingly difficult to find some liquors at Oregon liquor stores due to short supply, mis-management, antiquated technology, etc. GFL was born to make it easier to find just the right bottle. Also, fun fact, GFL's alternative name is "good-fucking-luck", as in good luck finding those rare bottles ;).
make update-golang-version