Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<a href="#features">Features</a> •
<a href="#requirements">Requirements</a> •
<a href="#installation">Installation</a> •
<a href="#Configuration">Configuration</a> •
<a href="#configuration">Configuration</a> •
<a href="#contributing">Contributing</a> •
<a href="#license">License</a>
</p>
Expand All @@ -22,12 +22,13 @@

- 📄 Add **text** and **URL bookmarks** into your Karakeep instance (tested on [v0.25.0](https://github.com/karakeep-app/karakeep/releases/tag/v0.25.0)).
- 🤖 Obtain **AI-generated tags** in **hashtag format** for easy searching on Telegram.
- 🔒 Support **chat ID and thread ID allowlists**.
- 🔒 **Mandatory chat ID allowlist** to prevent abuse (**thread ID allowlist** is also supported).
- 🐳 **Production-ready Docker image** for easy **deployment**.

## Requirements

- A [Telegram bot token](https://core.telegram.org/bots/features#botfather) (you can get one by talking to [@BotFather](https://t.me/BotFather) on Telegram)
- Your Telegram Chat ID (see [How to Find Your Chat ID](#how-to-find-your-chat-id)).
- A valid API key from [Karakeep](https://docs.karakeep.app/screenshots#settings).

## Installation
Expand All @@ -41,6 +42,7 @@ Use the `docker run` command to start `Karakeepbot`. Make sure to set the requir
```sh
docker run --name karakeepbot \
-e KARAKEEPBOT_TELEGRAM_TOKEN=your-telegram-bot-token \
-e KARAKEEPBOT_TELEGRAM_ALLOWLIST=your-telegram-chat-id \
-e KARAKEEPBOT_KARAKEEP_TOKEN=your-karakeep-api-key \
-e KARAKEEPBOT_KARAKEEP_URL=https://your-karakeep-instance.tld \
ghcr.io/madh93/karakeepbot:latest
Expand All @@ -59,6 +61,7 @@ services:
# - ./custom.config.toml:/var/run/ko/config.default.toml # Optional: specify a custom configuration file instead of the default one
environment:
- KARAKEEPBOT_TELEGRAM_TOKEN=your-telegram-bot-token
- KARAKEEPBOT_TELEGRAM_ALLOWLIST=your-telegram-chat-id
- KARAKEEPBOT_KARAKEEP_TOKEN=your-karakeep-api-key
- KARAKEEPBOT_KARAKEEP_URL=https://your-karakeep-instance.tld
```
Expand Down Expand Up @@ -95,7 +98,7 @@ go install github.com/Madh93/karakeepbot@latest
You can load a different configuration file by using the `-config path/to/config/file` flag when starting the application:

```sh
karakeepbot -config custom.config.tml
karakeepbot -config custom.config.toml
```

### Overriding with environment variables
Expand All @@ -106,6 +109,21 @@ Additionally, you can override the configuration values using environment variab
KARAKEEPBOT_LOGGING_LEVEL=debug KARAKEEPBOT_TELEGRAM_ALLOWLIST=chat_id_1,chat_id_2 karakeepbot
```

### Security Concerns

To protect your bot from abuse and spam from unauthorized users, `Karakeepbot` implements a **mandatory Chat ID allowlist**.

By default, the bot is configured with a placeholder value and **it will not start** until you explicitly configure the `telegram.allowlist` parameter. You have two options:

1. **Recommended:** Provide a list of one or more specific Chat IDs. This ensures only you and other authorized users can interact with the bot.
2. **Not Recommended:** Provide an empty list (`[]`). This will allow any Telegram user to interact with your bot, exposing it to potential abuse.

#### How to Find Your Chat ID

1. Open your Telegram client.
2. Search for the bot `@userinfobot` and start a chat with it.
3. The bot will immediately reply with your user information, including your **Id**. This is your Chat ID.

## Contributing

Contributions are welcome! Please open an issue or submit a pull request for any bug fixes or enhancements.
Expand Down
8 changes: 5 additions & 3 deletions config.default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
# Telegram bot token
token = "<YOUR_BOT_TOKEN_FROM_BOTFATHER>"

# Allowed chat IDs for the bot to interact with. If empty (default), the bot
# will interact with all chats.
allowlist = []
# Allowed chat IDs for the bot to interact with. It is strongly recommended to
# set this to your personal chat ID to prevent abuse. The bot will not start
# with the default value. You can get your chat ID by talking to @userinfobot on
# Telegram. If empty, the bot will interact with all chats.
allowlist = [-1]

# Allowed thread IDs (a.k.a topics) for the bot to interact with. If empty
# (default), the bot will interact with all threads.
Expand Down
5 changes: 2 additions & 3 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ var DefaultPath = filepath.Join(os.Getenv("KO_DATA_PATH"), DefaultConfigFile)
// DefaultConfig is the default configuration for the bot.
var DefaultConfig = Config{
Telegram: TelegramConfig{
Allowlist: []int64(nil),
Allowlist: []int64{-1}, // Enforce allowlist by default.
Threads: []int(nil),
},
Karakeep: KarakeepConfig{
Expand Down Expand Up @@ -159,8 +159,7 @@ func parseCommandLineFlags(config *Config) {
// validateConfig checks the validity of the configuration.
func validateConfig(config *Config) error {
if err := config.Telegram.Validate(); err != nil {
log.Printf("WRN: %v", err) // Telegram Bot Token validation couldn't be be 100% reliable.
return nil
return err
}
if err := config.Karakeep.Validate(); err != nil {
return err
Expand Down
6 changes: 6 additions & 0 deletions internal/config/telegram.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package config

import (
"fmt"

"github.com/Madh93/karakeepbot/internal/secret"
"github.com/Madh93/karakeepbot/internal/validation"
)
Expand All @@ -18,5 +20,9 @@ func (c TelegramConfig) Validate() error {
return err
}

if len(c.Allowlist) == 1 && c.Allowlist[0] == -1 {
return fmt.Errorf("invalid Telegram Allowlist (-1). Please configure it with your actual chat ID or an empty list to allow all users (not recommended)")
}

return nil
}