Erpnext Chatbot
Floating question-and-answer chatbot for the ERPNext desk. Rule-based intents over your own ERP data - no AI service, no API key.
- Author: kamal-star
- Repository: https://github.com/kamal-star/erpnext-chatbot
- GitHub stars: 0
- Forks: 0
- License: MIT
- Category: HR & Payroll
- Maintenance: Actively Maintained
Install Erpnext Chatbot
bench get-app https://github.com/kamal-star/erpnext-chatbot
Tags
- chatbot
- erp
- erpnext
- frappe
- frappe-app
Add the Frappe Gems badge to your README
Maintain Erpnext Chatbot? Paste this into your README:
[](https://frappegems.com/gems/apps/kamal-star/erpnext-chatbot)
About Erpnext Chatbot
# ERPNext Chatbot
A floating question-and-answer widget for the ERPNext desk. It sits in the
bottom-right corner of every desk page; users type a question in plain English
and get the answer back from their own ERP data.
**No AI service, no API key, no data leaves your server.** Answers come from
matching the question against *intents* you configure, and each intent runs an
ordinary Frappe query.
---
## What it does
| Ask | You get |
| --- | --- |
| "How many open sales orders are there?" | `There are 17 open Sales Orders.` + a link to the filtered list |
| "What are the total sales this month?" | The summed amount for the current month |
| "Which invoices are overdue?" | A small table of invoices, each row linking to the document |
| "Show me the recent purchase orders" | The 5 most recent, with supplier, date and amount |
| "Open the stock balance report" | A link straight to the report |
Two things make this useful without any language model:
- **Period phrases are understood.** `today`, `yesterday`, `this week`,
`last month`, `this quarter`, `last year`, `last 7 days`, `past three months`
are detected in the question and applied to the intent's date field.
- **Plurals and word order do not matter.** "sales invoice" matches
"sales invoices", and "how many customers do we have" matches the
"how many customers" keyword.
## Permissions
Every query runs as the logged-in user through `frappe.get_list` **without**
`ignore_permissions`. The bot can never show someone a record they could not
open themselves — a Sales user asking about salaries gets nothing back. Users
also only see their own rows in Chatbot Log.
---
## Installation
```bash
cd /path/to/frappe-bench
bench get-app https://github.com/kamal-star/erpnext-chatbot
bench --site yoursite.com install-app erpnext_chatbot
bench --site yoursite.com migrate
bench build --app erpnext_chatbot
bench restart
```
Full notes, including production and Docker, are in [INSTALL.md](INSTALL.md).
Installing seeds **Chatbot Settings** and about twenty standard intents. Any
intent whose DocType is not on the site (HR intents on a site without HRMS, for
example) is skipped.
---
## Configuration
### Chatbot Settings
Search for **Chatbot Settings** in the awesome bar.
| Field | Meaning |
| --- | --- |
| Enabled | Turns the widget off site-wide |
| Bot Name / Launcher Label | Text in the header and on the floating button |
| Position | Bottom Right or Bottom Left |
| Accent Colour | Any CSS colour; drives the button, header and links |
| Greeting / Fallback Message | First message, and the reply when nothing matches |
| Max Suggestions | How many starter chips to show |
| Search Documents As Fallback | If nothing matches, look for a DocType named in the question and show its most recent records |
| Log Conversations | Store questions in Chatbot Log |
| Match Threshold | Minimum score (0–1) before an intent is used. Lower = more answers but more wrong ones. Default `0.4` |
### Chatbot Intent
One record per question the bot can answer.
**Matching**
- **Keywords** — one phrase per line (commas also split). A question that
*contains* a phrase is a certain match; otherwise the score is the share of
the phrase's words present in the question.
- **Regex Pattern** — optional. A match here always wins.
- **Priority** — only breaks ties between equally-scoring intents.
**Response Type**
| Type | What it does | Fields used |
| --- | --- | --- |
| `Answer` | Replies with fixed text | Answer Text |
| `Count` | Counts matching documents | DocType, Filters, Date Field |
| `List` | Shows a table of documents | DocType, Filters, Columns, Order By, Row Limit |
| `Aggregate` | `sum` / `avg` / `min` / `max` of a field | DocType, Function, Field, Filters |
| `Link` | Replies with a link to a desk page | Route |
**Answer Text placeholders:** `{count}`, `{value}`, `{doctype}`, `{period}`.
**Filters (JSON)** accepts either form:
```json
{"docstatus": 1, "status": ["in", ["Unpaid", "Overdue"]]}
```
```json
[["posting_date", ">", "2026-01-01"], ["company", "=", "Great North"]]
```
Placeholders inside filter values: `{user}`, `{today}`, `{period_start}`,
`{period_end}`.
### Example: "how much did we sell this month"
| Field | Value |
| --- | --- |
| Keywords | `total sales`
`how much did we sell`
`revenue`
`turnover` | | Response Type | `Aggregate` | | DocType | `Sales Invoice` | | Function / Field | `sum` / `base_grand_total` | | Filters (JSON) | `{"docstatus": 1}` | | Date Field | `posting_date` | | Answer Text | `Total sales for {period}: {value}.` | Because **Date Field** is set, "this month", "last week" and "last 30 days" all work on the same intent without extra configuration. --- ## Improving the bot over time Open the **Chatbot Log** list and filter on `Answered = No`. Every question the bot could not handle is there — turn the common ones into new intents. That loop is the whole maintenance story. To restore a standard intent you deleted: ```bash bench --site yoursite.com execute erpnext_chatbot.install.reinstall_standard_intents ``` --- ## How matching works 1. The question is lowercased, stripped of punctuation and split into words. Stopwords are dropped and the common English plurals are folded (`invoices` → `invoice`). 2. Each enabled intent is scored: - regex match → `1.0` - keyword phrase found in the question → `1.0` - otherwise `0.85 × (shared words ÷ words in the phrase)` 3. The highest score wins if it clears **Match Threshold**. 4. If nothing clears it, the question is checked for a DocType name (when *Search Documents As Fallback* is on); failing that, the near-miss intents are offered as chips. There is no training step and no state — the same question always produces the same match. --- ## Project layout ``` erpnext_chatbot/ api.py whitelisted endpoints (get_widget_config, ask) engine.py intent matching, filters, query execution nlp.py normalisation, stemming, scoring, period phrases standard_intents.py the intents shipped with the app install.py seeding + re-seeding public/js/chatbot.js the widget public/css/chatbot.css widget styling (light + dark) erpnext_chatbot/doctype/ chatbot_settings/ single doctype chatbot_intent/ one record per answerable question chatbot_log/ asked questions, for finding gaps ``` ## Tests The matching logic runs without Frappe, so its tests need no bench and no site: ```bash python tests/test_nlp.py ``` ## Compatibility Frappe / ERPNext v14 and v15. No Python dependencies beyond Frappe itself. ## Licence MIT — see [LICENSE](LICENSE).
`how much did we sell`
`revenue`
`turnover` | | Response Type | `Aggregate` | | DocType | `Sales Invoice` | | Function / Field | `sum` / `base_grand_total` | | Filters (JSON) | `{"docstatus": 1}` | | Date Field | `posting_date` | | Answer Text | `Total sales for {period}: {value}.` | Because **Date Field** is set, "this month", "last week" and "last 30 days" all work on the same intent without extra configuration. --- ## Improving the bot over time Open the **Chatbot Log** list and filter on `Answered = No`. Every question the bot could not handle is there — turn the common ones into new intents. That loop is the whole maintenance story. To restore a standard intent you deleted: ```bash bench --site yoursite.com execute erpnext_chatbot.install.reinstall_standard_intents ``` --- ## How matching works 1. The question is lowercased, stripped of punctuation and split into words. Stopwords are dropped and the common English plurals are folded (`invoices` → `invoice`). 2. Each enabled intent is scored: - regex match → `1.0` - keyword phrase found in the question → `1.0` - otherwise `0.85 × (shared words ÷ words in the phrase)` 3. The highest score wins if it clears **Match Threshold**. 4. If nothing clears it, the question is checked for a DocType name (when *Search Documents As Fallback* is on); failing that, the near-miss intents are offered as chips. There is no training step and no state — the same question always produces the same match. --- ## Project layout ``` erpnext_chatbot/ api.py whitelisted endpoints (get_widget_config, ask) engine.py intent matching, filters, query execution nlp.py normalisation, stemming, scoring, period phrases standard_intents.py the intents shipped with the app install.py seeding + re-seeding public/js/chatbot.js the widget public/css/chatbot.css widget styling (light + dark) erpnext_chatbot/doctype/ chatbot_settings/ single doctype chatbot_intent/ one record per answerable question chatbot_log/ asked questions, for finding gaps ``` ## Tests The matching logic runs without Frappe, so its tests need no bench and no site: ```bash python tests/test_nlp.py ``` ## Compatibility Frappe / ERPNext v14 and v15. No Python dependencies beyond Frappe itself. ## Licence MIT — see [LICENSE](LICENSE).
Related HR & Payroll apps for Frappe & ERPNext
- Hrms — Open Source HR and Payroll Software
- Huf — Open-source, self-hosted multi-agent AI infrastructure for teams and apps with support for cloud and local models, tool integrations, workflows, and automation across business systems including Slack, ERPNext, Discord & Gmail.
- Bookings — Hotel Management App for Erpnext
- Employee Self Service — This is the backend component for Nesscale ESS - a mobile app that brings ERPNext to your phone. Employees can manage their HR tasks, sales activities, and projects right from their mobile devices.
- Inventory Tools — A collection of features to streamline and enhance inventory management and manufacturing workflows in ERPNext.
- Check Run — Payables utility for ERPNext
- Next Ai — NextAI is an AI-powered app for Frappe and ERPNext, delivering seamless content generation, automation, and productivity enhancements.
- Projectit — Open Source PWA mobile app to track the Employees out in the field. This mobile app is developed on Frappe Framework and it is integrated with the Project functionalities of ERPNext and integrated tightly with Frappe HR.