How itshenrywu/mcut-menu-bot works
1. This repository is a LINE-based menu bot for National Chung Hsing University? Wait, actually 明志科技大學(MCUT)學餐菜單機器人. Its core purpose is to answer menu queries for campus dining, with a public API and a chat bot as the main user-facing entry points.
2. The main runtime entry point is bot.js. That is the interactive layer that likely handles LINE webhook events, user preferences, and menu lookup responses. The README’s LINE add-friend link indicates the bot is exposed through a LINE Official Account rather than a web UI.
3. Menu data is not authored in this repo; it is ingested from the school’s external site http://elder.mcut.edu.tw/website1/. The crawler/ directory contains the domain-specific scrapers:
- menu.js for regular meal menus
- snack.js for snack/light meal menus
- news.js for announcements/news
- working-day.js for workday/calendar logic
4. A key architectural boundary is between “live interaction” and “data collection.” The bot consumes already-prepared menu data, while the crawler scripts periodically refresh that data from the upstream school site and calendar source. This keeps chat responses fast and decouples the bot from scraping latency.
5. The repository also exposes a public menu API, documented in the README as:
https://mcut-menu-api.henrywu.tw/{YYYY}/{MM}/{DD}/{MEAL_ID}.json
That API is a read-only surface for menu retrieval by date and meal type (1 breakfast, 2 lunch, 3 dinner). The response shape is restaurant-based (menu_1, menu_2).
6. The “next/previous day” navigation is business-rule driven, not just date arithmetic. The README says those buttons move to the previous/next working day using ruyut/TaiwanCalendar, which implies the bot must skip weekends and holidays when navigating menus.
7. The public/, public/image/, and public/multi_size_image/ directories suggest generated assets for presenting menus visually, likely for LINE rich messages or shareable images. fonts/ supports that rendering pipeline, indicating the system probably converts scraped text into branded image cards.
8. The .github/workflows/ directory shows this is automation-heavy and likely GitHub Actions–driven:
- get-menu.yml
- get-snack-menu.yml
- get-working-day.yml
- healthcheck.yml
These workflows probably run on schedules to refresh menu/calendar data and verify service availability.
9. healthcheck.js is a separate operational component, used by the workflow to confirm the deployed bot/API is reachable. This suggests the repo includes both application logic and lightweight observability/uptime checking.
10. Configuration appears environment-based. The presence of .env.sample implies secrets and deployment-specific values are injected at runtime, likely for LINE credentials and any hosting/API settings.
11. The overall data flow is:
external MCUT website and calendar source -> crawler scripts -> generated menu/calendar assets and JSON -> bot/API consumers -> LINE users.
In other words, the repo acts as a scraping-and-serving pipeline rather than a traditional database-backed application.
12. There is no obvious database, queue, or separate backend service in the tree. That means the architecture is probably stateless or file-driven, with GitHub Actions and published files/API responses serving as the persistence and distribution mechanism.
13. For an architecture diagram, the important boxes are:
external school website/calendar source, crawler jobs, generated static assets/API, LINE bot runtime, and GitHub Actions automation. The key arrows are “scrape/update,” “render/generate,” and “serve/respond,” with the working-day calendar logic influencing menu navigation.
Main entry points: bot.js Bot runtime · workflows GitHub Actions · menu.js Menu crawler · snack.js Snack crawler
Components 17
User-facing
Chat bot and public menu access
- LINE users · People querying campus menus through LINE
- Bot runtime · Interactive entry point for menu lookup and replies
bot.js - Public API · Static JSON menu surface for external consumers
public
Data collection
Scrapers and calendar logic
- School site · Upstream MCUT website that publishes menu and news content
- Menu crawler · Fetches regular meal menus from the upstream site
crawler/menu.js - Snack crawler · Fetches snack and light meal menus
crawler/snack.js - News crawler · Fetches announcements and related updates
crawler/news.js - Workday logic · Determines working days for menu navigation
crawler/working-day.js
Generated outputs
Static menu assets and API data
- Menu assets · Rendered menu images for presentation and sharing
public/image - Multi-size assets · Alternative image sizes for rich message delivery
public/multi_size_image - Fonts · Typography used when composing menu visuals
fonts - API files · Published menu JSON consumed by the public API
public
Automation
Scheduled workflows and checks
- GitHub Actions · Scheduled refresh and operational automation
.github/workflows - Menu workflow · Runs menu refresh automation
.github/workflows/get-menu.yml - Snack workflow · Runs snack menu refresh automation
.github/workflows/get-snack-menu.yml - Workday workflow · Refreshes calendar and working-day data
.github/workflows/get-working-day.yml - Healthcheck · Verifies the deployed bot or API is reachable
healthcheck.js
Connections 24
- LINE users → Bot runtime: ask menus · Users send menu queries to the bot
- Bot runtime → Public API: read api · Bot can consume published menu JSON
- Bot runtime → Workday logic: nav rules · Bot uses working-day logic for previous/next navigation
- Bot runtime → Menu assets: render reply · Bot replies with generated menu images
- Bot runtime → Multi-size assets: render reply · Bot can use alternate-sized images for rich responses
- Menu crawler → School site: scrape · Regular menu crawler pulls upstream content
- Snack crawler → School site: scrape · Snack crawler pulls upstream content
- News crawler → School site: scrape · News crawler pulls upstream content
- Workday logic → School site: calendar source · Working-day logic depends on external calendar rules/source
- Menu crawler → API files: write json · Menu crawler produces JSON data for serving
- Snack crawler → API files: write json · Snack crawler produces JSON data for serving
- Menu crawler → Menu assets: generate images · Menu crawler feeds visual menu rendering
- Snack crawler → Multi-size assets: generate images · Snack crawler feeds alternative image rendering
- Fonts → Menu assets: style · Fonts support image composition
- Fonts → Multi-size assets: style · Fonts support image composition
- GitHub Actions → Menu workflow: run · Workflow orchestrates menu refresh job
- GitHub Actions → Snack workflow: run · Workflow orchestrates snack refresh job
- GitHub Actions → Workday workflow: run · Workflow orchestrates working-day refresh job
- GitHub Actions → Healthcheck: run · Workflow executes deployment health check
- Menu workflow → Menu crawler: execute · Menu workflow triggers the menu crawler
- Snack workflow → Snack crawler: execute · Snack workflow triggers the snack crawler
- Workday workflow → Workday logic: execute · Workday workflow refreshes calendar logic/data
- Healthcheck → Bot runtime: check · Healthcheck validates bot reachability
- Healthcheck → Public API: check · Healthcheck can validate the public API surface