A localhost Streamlit chatbot with Google sign-in, Telegram approval, conversation memory, file upload, and a web-search toggle.
- Python 3.11 or newer
- An Auth0 Regular Web Application with the Google connection enabled
- An Ollama Cloud API key and a Hugging Face token
- A Telegram bot token and the admin chat id
The app reads secrets from .env only. .env.example lists the same keys with blank values. Do not commit .env.
Auth0 application settings:
- Allowed Callback URLs:
http://localhost:8501 - Allowed Logout URLs:
http://localhost:8501 - Allowed Web Origins:
http://localhost:8501 - Google social connection:
google-oauth2
Create a post-login Action named Approve sign-in, deploy it, and add it to the post-login trigger. It lets a first Google login finish so the app can send Telegram. It denies a login only when that account is already marked denied.
exports.onExecutePostLogin = async (event, api) => {
const email = (event.user.email || "").toLowerCase();
if (email === "dominic.ci.yu@gmail.com") return;
if (event.user.app_metadata && event.user.app_metadata.approved === false) {
api.access.deny("Dominic denied this Google account.");
}
};AUTH0_CLIENT_SECRET must be the Auth0 application secret.
dominic.ci.yu@gmail.com can always sign in. Everyone else stays on the front page until the Telegram decision. Approval is stored in approved_users.json, which the app creates at runtime.
Leave SMTP_USER, SMTP_PASSWORD, and SMTP_FROM blank until you want approval emails. Decisions are still saved. For Gmail, use an app password and set SMTP_FROM to the same address as SMTP_USER.
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# fill .env, then
streamlit run app.pypy -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
copy .env.example .env
REM fill .env, then
streamlit run app.pyOpen http://localhost:8501. Use localhost, not 127.0.0.1, so the Auth0 callback matches.
- Sign in with Google opens the chat when the account is already approved.
- Apply for access sends Dominic a Telegram message with the name, email, location, timezone, and time, plus Approve and Deny buttons.
- Reply
APPROVE email@example.comorDENY email@example.comif you prefer text. - List users sits under the Telegram message box. Each guest has a red ❌. No Changes closes the list.
- The paperclip under the message box opens the file picker. Red means no file is attached. Green means a file is attached and will be used.
- The globe turns web search on (green) or off (red) for the current conversation. Search is not called while it is red.
- New conversation starts a fresh chat. Older chats stay in the sidebar.
- Refresh keeps an approved user signed in.
Uploaded files can be txt, md, pdf, csv, xlsx, xls, json, or log. Embeddings are requested from the Hugging Face Inference API (sentence-transformers/all-MiniLM-L6-v2). Nothing is embedded on this machine.
Replies follow the latest message: mostly English stays English, mostly Traditional or Simplified Chinese is answered in Traditional Chinese, and any other language is answered in English.