An intelligent LINE chatbot for cocktail discovery and recommendations
Over Party Lab Chatbot is a production-ready LINE messaging bot built for Over Party Lab, leveraging Google Apps Script and TypeScript to deliver an interactive cocktail discovery experience. The bot intelligently searches cocktail recipes and provides personalized recommendations based on ingredients.
- 🔍 Multilingual Search: Query cocktail recipes in English or Chinese with fuzzy matching
- 🎯 Smart Recommendations: AI-powered ingredient-based suggestions when exact matches aren't found
- 🎨 Rich Interactive UI: Button templates and carousel cards for enhanced user experience
- 📊 Analytics Integration: Comprehensive user interaction logging to Google Sheets
- 🚀 Serverless Architecture: Zero-maintenance deployment with Google Apps Script
- Type-safe development with TypeScript
- Modular service architecture for maintainability
- Automated deployment pipeline with clasp
- Real-time webhook integration with LINE Messaging API
- Scalable data storage with Google Sheets
| Category | Technology |
|---|---|
| Runtime | Google Apps Script |
| Language | TypeScript 5.7+ |
| Messaging Platform | LINE Messaging API |
| Data Storage | Google Sheets |
| Build Tool | clasp (Command Line Apps Script Projects) |
| Type Definitions | @types/google-apps-script |
The bot follows a serverless, event-driven architecture:
┌─────────────────┐
│ LINE User │
│ (Client) │
└────────┬────────┘
│ Message
▼
┌─────────────────────────────────────────┐
│ LINE Messaging API │
│ (Webhook Trigger) │
└────────┬────────────────────────────────┘
│ HTTP POST
▼
┌─────────────────────────────────────────┐
│ Google Apps Script (Server) │
│ ┌─────────────────────────────────┐ │
│ │ doPost() - Webhook Handler │ │
│ └──────────┬──────────────────────┘ │
│ │ │
│ ┌──────────▼──────────┐ │
│ │ Message Processing │ │
│ │ - Parse input │ │
│ │ - Search logic │ │
│ │ - Response builder │ │
│ └──────────┬──────────┘ │
│ │ │
│ ┌──────────▼──────────┐ │
│ │ Service Layer │ │
│ │ - lineService │ │
│ │ - sheetService │ │
│ │ - logService │ │
│ └──────────┬──────────┘ │
└─────────────┼──────────────────────────┘
│
▼
┌──────────────────────────────────────────┐
│ Google Sheets (Database) │
│ ┌────────────┐ ┌──────────────────┐ │
│ │ DRINK_LIST │ │ ELEMENT_MAPPING │ │
│ └────────────┘ └──────────────────┘ │
│ ┌────────────┐ │
│ │USER_ACTION │ (Analytics) │
│ └────────────┘ │
└──────────────────────────────────────────┘
Before you begin, ensure you have the following:
- Node.js: v12.0.0 or later (Download)
- Package Manager: npm (comes with Node.js) or yarn
- Google Account: For Google Apps Script and Sheets access
- LINE Developer Account: Register here
- LINE Messaging API Channel: Create a channel
# Clone the repository
git clone https://github.com/sean1093/over-party-lab-chatbot.git
cd over-party-lab-chatbot
# Install dependencies
npm install
# Install clasp globally
npm install -g @google/clasp
# Login to Google Account
clasp login
# Create config file
cp config.ts.example config.ts
# Edit config.ts with your credentials
# Deploy to Google Apps Script
clasp create --type webapp --title "Over Party Lab Chatbot"
clasp push
clasp deploy# Install clasp globally
npm install -g @google/clasp
# Install project dependencies
npm install# Login to Google Account
clasp login
# Create a new Apps Script project (or clone existing one)
clasp create --type webapp --title "Over Party Lab Chatbot"
# Or clone existing project
clasp clone <SCRIPT_ID>Create a config.ts file in the root directory with your credentials:
const CONFIG = {
LINE: {
// Get this from LINE Developers Console > Your Channel > Messaging API
CHANNEL_ACCESS_TOKEN: 'YOUR_LINE_CHANNEL_ACCESS_TOKEN',
URL_LINE: 'https://api.line.me/v2/bot/message/'
},
GOOGLE_SHEET: {
// Your Google Sheet ID (from the spreadsheet URL)
// https://docs.google.com/spreadsheets/d/{SHEET_ID}/edit
API_KEY: 'YOUR_GOOGLE_SHEET_ID'
},
COLUMN_KEY_MAPPING: {
name: 1, // Chinese name column
nameen: 2, // English name column
link: 3, // Recipe link column
detail: 4, // Cocktail details column
recommendation: 5 // Recommendation column
},
OVERPARTYLAB: {
IG: 'https://www.instagram.com/over.party.lab/'
},
CONFIG_DEBUG: {
// Your LINE User ID for testing (optional)
// Get it by sending a message to the bot and checking webhook logs
USERID: 'YOUR_LINE_USER_ID_FOR_TESTING'
}
};
export default CONFIG;Note: Never commit
config.tsto version control. It's already in.gitignore.
- Create a new Google Sheet
- Create three tabs with the following structure:
Stores cocktail recipes and information.
| Column | Type | Description | Example |
|---|---|---|---|
| name | Text | Chinese cocktail name | 瑪格麗特 |
| nameen | Text | English cocktail name | Margarita |
| link | URL | Recipe link | https://... |
| detail | Text | Cocktail description | 經典龍舌蘭調酒... |
Maps ingredients to recommended cocktails.
| Column | Type | Description | Example |
|---|---|---|---|
| name | Text | Chinese ingredient name | 龍舌蘭 |
| nameen | Text | English ingredient name | Tequila |
| recommendation | Text | Recommended cocktail names (comma-separated) | 瑪格麗特,龍舌蘭日出 |
Automatically logs user interactions (no manual setup needed).
| Column | Type | Description |
|---|---|---|
| index | Number | Auto-increment ID |
| search | Text | User search query |
| user | Text | LINE User ID |
| time | Datetime | Timestamp |
- Copy the Google Sheet ID from the URL and add it to your
config.ts
# Push code to Google Apps Script
clasp push
# Deploy as web app
clasp deploy-
After deployment, get your web app URL:
clasp deploy # Copy the Web app URL from the output -
Configure LINE Messaging API:
- Go to LINE Developers Console
- Select your Messaging API channel
- Navigate to Messaging API tab
- Set Webhook URL to your Google Apps Script web app URL
- Enable Use webhook
- Disable Auto-reply messages (optional, recommended)
-
Verify webhook:
- Click Verify button in LINE Console
- Should return success message
# Push code to Google Apps Script
npm run push
# Pull code from Google Apps Script
npm run pull
# Deploy new version
npm run deploy
# Watch mode - auto-push on file changes
npm run watch- Make local changes to TypeScript files
- Push to Google Apps Script:
npm run push
- Test in LINE: Send messages to your bot
- View logs: Check Google Apps Script editor > Executions
The project includes testing utilities in debug.ts:
// Test webhook POST endpoint
function test_post() {
// Simulates a LINE webhook message
// Useful for testing message parsing and response logic
}
// Test sending messages
function test_send() {
// Tests LINE API message delivery
// Requires CONFIG_DEBUG.USERID to be set
}Run tests:
- Open Google Apps Script editor
- Select the test function
- Click Run
- Check Execution log for results
- Type checking: Run
tsc --noEmitto check for TypeScript errors before pushing - Auto-formatting: Use Prettier or similar formatter for consistent code style
- Watch mode: Use
npm run watchduring active development for automatic deployment
over-party-lab-chatbot/
│
├── 📄 Core Application Files
│ ├── app.ts # Main webhook handler and message processing logic
│ ├── config.ts # Configuration file (not in repo, see config.ts.example)
│ └── appsscript.json # Google Apps Script manifest
│
├── 🔧 Service Layer
│ ├── lineService.ts # LINE Messaging API integration
│ ├── sheetService.ts # Google Sheets data operations
│ ├── logService.ts # User activity logging
│ └── timeService.ts # Timestamp formatting utilities
│
├── 📝 Resources
│ ├── wording.ts # Message templates and response texts
│ └── debug.ts # Testing and debugging utilities
│
├── ⚙️ Configuration
│ ├── package.json # Node.js dependencies and scripts
│ ├── tsconfig.json # TypeScript compiler configuration
│ ├── .claspignore # Files to exclude from clasp push
│ └── .gitignore # Git ignore rules
│
└── 📁 Other
└── image/ # Project assets (logo, screenshots)
| File | Purpose |
|---|---|
app.ts |
Entry point with doPost() webhook handler |
lineService.ts |
Handles LINE API calls (push messages, buttons, carousels) |
sheetService.ts |
CRUD operations for Google Sheets data |
wording.ts |
Centralized message templates for consistency |
debug.ts |
Testing functions for local development |
1. User sends message (e.g., "Margarita")
↓
2. LINE Platform receives message
↓
3. Webhook POST → doPost(e) in app.ts
↓
4. Parse message and extract search query
↓
5. Search DRINK_LIST sheet for exact match
↓
6a. ✅ Match found 6b. ❌ No match found
→ Return cocktail details → Search ELEMENT_MAPPING
→ Include recipe link → Find ingredient recommendations
→ Send text message → Send button template with options
↓
7. Log user action to USER_ACTION sheet
↓
8. Response delivered to user
The bot implements a two-tier search strategy:
-
Exact Match Search (Primary):
- Searches both
name(Chinese) andnameen(English) columns - Case-insensitive matching
- Returns full cocktail details with recipe link
- Searches both
-
Ingredient-Based Recommendations (Fallback):
- Searches ELEMENT_MAPPING for partial matches
- Returns up to 5 recommended cocktails
- Presented as interactive buttons for easy selection
Webhook handler that processes incoming LINE messages.
function doPost(e: GoogleAppsScript.Events.DoPost): GoogleAppsScript.Content.TextOutputParameters:
e: Event object containing the POST request data from LINE
Returns: TextOutput with status 200
Sends messages to LINE users via Messaging API.
interface PushMessageConfig {
to: string; // LINE User ID
messages: Message[]; // Array of message objects
}Queries Google Sheets for cocktail or ingredient data.
interface QueryParams {
sheetName: string; // Sheet tab name (e.g., 'DRINK_LIST')
searchValue: string; // Search query
searchColumn?: number; // Column index to search
}Logs user actions to the USER_ACTION sheet.
interface SaveParams {
search: string; // User's search query
user: string; // LINE User ID
timestamp: string; // Formatted timestamp
}Configuration for Google Apps Script deployment:
{
"timeZone": "Asia/Hong_Kong",
"webapp": {
"access": "ANYONE_ANONYMOUS", // Allow public webhook access
"executeAs": "USER_DEPLOYING" // Run as deploying user
},
"exceptionLogging": "STACKDRIVER" // Enable Google Cloud logging
}Key Settings:
timeZone: Adjust for your region (affects timestamp logging)access: Must beANYONE_ANONYMOUSfor LINE webhookexecuteAs:USER_DEPLOYINGensures proper permissions
- ✅ Verify webhook URL is correct in LINE Console
- ✅ Ensure web app is deployed (not just saved)
- ✅ Check
accessis set toANYONE_ANONYMOUSin appsscript.json - ✅ Test webhook using LINE Console's verification tool
- ✅ Ensure
config.tsexists in root directory - ✅ Copy from
config.ts.exampleif missing - ✅ Verify
config.tsis not in.claspignore
- ✅ Check Google Apps Script execution logs for errors
- ✅ Verify LINE Channel Access Token is valid
- ✅ Confirm Google Sheet ID is correct
- ✅ Ensure sheet tab names match exactly (case-sensitive)
# Check for errors before pushing
npx tsc --noEmit
# Common fix: Reinstall dependencies
rm -rf node_modules package-lock.json
npm install-
View Execution Logs:
- Open Google Apps Script editor
- Click View > Executions
- Check recent execution logs for errors
-
Test Locally:
- Use
debug.tsfunctions to test without LINE - Run
test_post()to simulate webhook - Run
test_send()to test message sending
- Use
-
Enable Verbose Logging:
- Add
console.log()statements in your code - View output in Apps Script Executions panel
- Add
Contributions are welcome! Here's how you can help:
-
Fork the repository
git clone https://github.com/YOUR_USERNAME/over-party-lab-chatbot.git
-
Create a feature branch
git checkout -b feature/amazing-feature
-
Make your changes
- Follow existing code style
- Add comments for complex logic
- Update documentation if needed
-
Test your changes
- Test locally using debug functions
- Ensure no TypeScript errors:
npx tsc --noEmit
-
Commit with clear messages
git commit -m "feat: add amazing feature"Follow Conventional Commits
-
Push and create Pull Request
git push origin feature/amazing-feature
- Write clean, readable code
- Maintain type safety (avoid
anytypes) - Add JSDoc comments for public functions
- Keep dependencies minimal
- Test thoroughly before submitting PR
- 🌐 Add more language support
- 🎨 Improve message templates and UI
- 📊 Enhanced analytics and reporting
- 🧪 Add unit tests
- 📝 Improve documentation
- 🐛 Bug fixes and performance improvements
This project is licensed under the MIT License - see the LICENSE file for details.
Yes! The architecture is generic. Simply modify:
- Google Sheets structure for your data
- Search logic in app.ts
- Message templates in wording.ts
$0 - Both Google Apps Script and LINE Messaging API offer free tiers sufficient for most small to medium bots.
Yes! LINE Messaging API supports rich media. See LINE Message Types for implementation details.
Google Apps Script has daily quotas. For high-traffic bots, consider:
- Using Google Cloud Functions
- Implementing caching
- Optimizing Sheets queries
- Migrating to a database (Firebase, MongoDB)
Yes! Clone the project, use different:
- LINE channels
- Google Sheets
- Apps Script deployments
- 📝 How to create a LINE chatbot using Google Apps Script (Chinese)
- 📝 Using clasp and TypeScript to develop Google Apps Script (Chinese)
- 📚 LINE Messaging API Documentation
- 📚 Google Apps Script Documentation
- 📚 clasp - Command Line Apps Script Projects
- 📚 TypeScript Handbook
- LINE Bot SDK - Node.js SDK for LINE
- Google Apps Script Samples
Sean Chou
- 🍸 Over Party Lab - Cocktail community and inspiration
- 💚 LINE Corporation - LINE Messaging API
- ☁️ Google - Apps Script platform and infrastructure
- 💙 TypeScript Team - Type-safe development tools
- 🙏 All contributors and users of this project
Made with ❤️ for cocktail enthusiasts
