A Google Apps Script application that fetches top Hacker News articles, generates AI summaries, and posts them to Slack.
- 🔥 Hacker News Integration: Fetches top stories from Hacker News API
- 🤖 AI Summarization: Uses Gemini AI to generate concise Japanese summaries
- 💬 Slack Integration: Posts formatted summaries with article titles and discussion links
- Node.js (managed via Nix)
- TypeScript (included in dev dependencies)
- Google Apps Script CLI (clasp)
- Google Cloud Project with Gemini API access
- Slack workspace with bot permissions
# Using Nix (recommended)
nix develop
# Install dependencies
npm install
# Setup Google Apps Script CLI (first time only)
npx clasp login
npx clasp create --type standalone --title "Hacker News Summarizer"
# Clone existing project (optional)
npx clasp clone <PROJECT_ID>
npx clasp pull
Note: clasp.json
is excluded from git as it contains project-specific settings.
After setting up your Google Apps Script project, create a clasp.json
file in the project root:
{
"scriptId": "your-google-apps-script-project-id",
"rootDir": "./dist"
}
How to find your Script ID:
- Open your Google Apps Script project in the web editor
- Click ⚙️ Project Settings in the left sidebar
- Copy the Script ID from the IDs section
- Paste it into your
clasp.json
file
Alternative: Use npx clasp create
or npx clasp clone <PROJECT_ID>
to automatically generate this file.
Configure the following properties in Google Apps Script:
Property | Description | Required | Default |
---|---|---|---|
GEMINI_API_KEY | Gemini AI API authentication key | ✅ | - |
SLACK_BOT_TOKEN | Slack Bot User OAuth Token | ✅ | - |
SLACK_CHANNEL_ID | Target Slack channel ID | ✅ | - |
ARTICLE_COUNT | Number of articles to process | ❌ | 3 |
Set up automated execution:
- Function to run:
main
(for both time-driven and manual execution) - Deployment: Head
- Event source: Time-driven
- Trigger type:
- Hour timer (recommended for production)
- Minute timer (for testing only)
- Interval: Every 6 hours (recommended)
- Failure notifications: Daily
Required OAuth scopes (automatically configured):
https://www.googleapis.com/auth/script.external_request
https://www.googleapis.com/auth/script.scriptapp
# Build the project (type check + compile + bundle for Google Apps Script)
npm run build
# Deploy to Google Apps Script
npx clasp push
# Create a new deployment (optional)
npx clasp deploy --description "Hacker News Summarizer v1.0"
// In Google Apps Script editor
main() // Returns: "X summaries posted."
Set up time-driven triggers in the Google Apps Script editor:
- Go to Triggers (⏰) in the left sidebar
- Click + Add Trigger
- Choose function:
main
- Choose event source: Time-driven
- Choose type: Hour timer or Day timer
- Choose interval as needed (e.g., Every 6 hours)
main()
: Main processing function (synchronous)- Returns: String with number of summaries posted
- Usage: Direct execution in GAS editor or via triggers
- Gemini API: 1000ms delay between requests
- Slack API: 2000ms delay between posts
- Configurable via
withRateLimit()
higher-order function
- Default count: 3 articles (configurable via
ARTICLE_COUNT
) - Source: Top 30 Hacker News stories
- Filtering: Auto-filters deleted/dead articles
- Comments: Up to 10 comments per article
Prompts are externalized in src/prompts.yaml
:
- Japanese output format
- Structured summary format
- Configurable without code changes
- YAML Processing: Converts
prompts.yaml
to TypeScript with strict type definitions - TypeScript Type Checking: Validates all code with strict compiler settings
- esbuild Bundling: Single file output for Google Apps Script
- Manifest Copy: Copies Apps Script manifest to dist
Generated files:
src/loadedPrompts.ts
: Auto-generated from YAML with typed interfaces
- Endpoint:
https://hacker-news.firebaseio.com/v0/
- Rate Limit: No official limit (built-in delays for safety)
- Data: Top stories, article details, comments
- Model:
gemini-1.5-pro
- Rate Limit: ~15 RPM (Free tier)
- Input: Article content + comments
- Output: Japanese summary
- Method:
chat.postMessage
- Format: Rich attachments with titles and links
- Rate Limit: ~1 message per second