mirror of
https://github.com/HugeFrog24/go-telegram-bot.git
synced 2026-03-02 00:14:34 +00:00
docs
rm unused params fix test test workflow security add ci badge
This commit is contained in:
60
.github/workflows/go-ci.yaml
vendored
60
.github/workflows/go-ci.yaml
vendored
@@ -7,23 +7,15 @@ on:
|
|||||||
branches: [ main ]
|
branches: [ main ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
# Common setup job that other jobs can depend on
|
||||||
|
setup:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
# Checkout the repository
|
- uses: actions/checkout@v4
|
||||||
- name: Checkout code
|
- uses: actions/setup-go@v5
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
# Set up Go environment
|
|
||||||
- name: Set up Go
|
|
||||||
uses: actions/setup-go@v5
|
|
||||||
with:
|
with:
|
||||||
go-version: '1.23' # Specify the Go version you are using
|
go-version: '1.23'
|
||||||
|
- uses: actions/cache@v4
|
||||||
# Cache Go modules
|
|
||||||
- name: Cache Go modules
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cache/go-build
|
~/.cache/go-build
|
||||||
@@ -31,24 +23,36 @@ jobs:
|
|||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-go-
|
${{ runner.os }}-go-
|
||||||
|
- run: go mod tidy
|
||||||
|
|
||||||
# Install Dependencies
|
# Lint job
|
||||||
- name: Install Dependencies
|
lint:
|
||||||
run: go mod tidy
|
needs: setup
|
||||||
|
runs-on: ubuntu-latest
|
||||||
# Run Linters using golangci-lint
|
steps:
|
||||||
- name: Lint Code
|
- uses: actions/checkout@v4
|
||||||
uses: golangci/golangci-lint-action@v6
|
- uses: golangci/golangci-lint-action@v6
|
||||||
with:
|
with:
|
||||||
version: v1.60 # Specify the version of golangci-lint
|
version: v1.60
|
||||||
args: --timeout 5m
|
args: --timeout 5m
|
||||||
|
|
||||||
# Run Tests
|
# Test job
|
||||||
- name: Run Tests
|
test:
|
||||||
run: go test ./... -v
|
needs: setup
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: '1.23'
|
||||||
|
- run: go test ./... -v
|
||||||
|
|
||||||
# Security Analysis using gosec
|
# Security scan job
|
||||||
- name: Security Scan
|
security:
|
||||||
uses: securego/gosec@master
|
needs: setup
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: securego/gosec@master
|
||||||
with:
|
with:
|
||||||
args: ./...
|
args: ./...
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -108,3 +108,14 @@ View errors:
|
|||||||
```bash
|
```bash
|
||||||
journalctl -u telegram-bot -p err
|
journalctl -u telegram-bot -p err
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
The GitHub actions workflow already runs tests on every commit:
|
||||||
|
|
||||||
|
> [](https://github.com/HugeFrog24/go-telegram-bot/actions/workflows/go-ci.yaml)
|
||||||
|
|
||||||
|
However, you can run the tests locally using:
|
||||||
|
```bash
|
||||||
|
go test -race -v ./...
|
||||||
|
```
|
||||||
|
|||||||
6
bot.go
6
bot.go
@@ -279,7 +279,7 @@ func initTelegramBot(token string, handleUpdate func(ctx context.Context, tgBot
|
|||||||
|
|
||||||
func (b *Bot) sendResponse(ctx context.Context, chatID int64, text string, businessConnectionID string) error {
|
func (b *Bot) sendResponse(ctx context.Context, chatID int64, text string, businessConnectionID string) error {
|
||||||
// Pass the outgoing message through the centralized screen for storage
|
// Pass the outgoing message through the centralized screen for storage
|
||||||
_, err := b.screenOutgoingMessage(chatID, text, businessConnectionID)
|
_, err := b.screenOutgoingMessage(chatID, text)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrorLogger.Printf("Error storing assistant message: %v", err)
|
ErrorLogger.Printf("Error storing assistant message: %v", err)
|
||||||
return err
|
return err
|
||||||
@@ -306,7 +306,7 @@ func (b *Bot) sendResponse(ctx context.Context, chatID int64, text string, busin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sendStats sends the bot statistics to the specified chat.
|
// sendStats sends the bot statistics to the specified chat.
|
||||||
func (b *Bot) sendStats(ctx context.Context, chatID int64, userID int64, username string, businessConnectionID string) {
|
func (b *Bot) sendStats(ctx context.Context, chatID int64, businessConnectionID string) {
|
||||||
totalUsers, totalMessages, err := b.getStats()
|
totalUsers, totalMessages, err := b.getStats()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrorLogger.Printf("Error fetching stats: %v\n", err)
|
ErrorLogger.Printf("Error fetching stats: %v\n", err)
|
||||||
@@ -425,7 +425,7 @@ func (b *Bot) screenIncomingMessage(message *models.Message) (Message, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// screenOutgoingMessage handles storing of outgoing messages.
|
// screenOutgoingMessage handles storing of outgoing messages.
|
||||||
func (b *Bot) screenOutgoingMessage(chatID int64, response string, businessConnectionID string) (Message, error) {
|
func (b *Bot) screenOutgoingMessage(chatID int64, response string) (Message, error) {
|
||||||
assistantMessage := b.createMessage(chatID, 0, "", string(anthropic.RoleAssistant), response, false)
|
assistantMessage := b.createMessage(chatID, 0, "", string(anthropic.RoleAssistant), response, false)
|
||||||
|
|
||||||
// Store the message.
|
// Store the message.
|
||||||
|
|||||||
12
config.go
12
config.go
@@ -143,9 +143,11 @@ func validateConfig(config *BotConfig, ids, tokens map[string]bool) error {
|
|||||||
|
|
||||||
func loadConfig(filename string) (BotConfig, error) {
|
func loadConfig(filename string) (BotConfig, error) {
|
||||||
var config BotConfig
|
var config BotConfig
|
||||||
file, err := os.OpenFile(filename, os.O_RDONLY, 0)
|
// Use filepath.Clean before opening the file
|
||||||
|
cleanPath := filepath.Clean(filename)
|
||||||
|
file, err := os.OpenFile(cleanPath, os.O_RDONLY, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return config, fmt.Errorf("failed to open config file %s: %w", filename, err)
|
return config, fmt.Errorf("failed to open config file %s: %w", cleanPath, err)
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
@@ -165,9 +167,11 @@ func (c *BotConfig) Reload(configDir, filename string) error {
|
|||||||
return fmt.Errorf("invalid config path: %w", err)
|
return fmt.Errorf("invalid config path: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.OpenFile(validPath, os.O_RDONLY, 0)
|
// Use filepath.Clean before opening the file
|
||||||
|
cleanPath := filepath.Clean(validPath)
|
||||||
|
file, err := os.OpenFile(cleanPath, os.O_RDONLY, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to open config file %s: %w", validPath, err)
|
return fmt.Errorf("failed to open config file %s: %w", cleanPath, err)
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
|
|||||||
@@ -477,8 +477,12 @@ func TestLoadAllConfigs(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
// Clear the tempDir before each test
|
// Clear the tempDir before each test
|
||||||
os.RemoveAll(tempDir)
|
if err := os.RemoveAll(tempDir); err != nil {
|
||||||
os.MkdirAll(tempDir, 0755)
|
t.Fatalf("Failed to remove temp dir: %v", err)
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(tempDir, 0755); err != nil {
|
||||||
|
t.Fatalf("Failed to create temp dir: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Write the test files directly
|
// Write the test files directly
|
||||||
for filename, content := range tt.setupFiles {
|
for filename, content := range tt.setupFiles {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ func (b *Bot) handleUpdate(ctx context.Context, tgBot *bot.Bot, update *models.U
|
|||||||
command := strings.TrimSpace(message.Text[entity.Offset : entity.Offset+entity.Length])
|
command := strings.TrimSpace(message.Text[entity.Offset : entity.Offset+entity.Length])
|
||||||
switch command {
|
switch command {
|
||||||
case "/stats":
|
case "/stats":
|
||||||
b.sendStats(ctx, chatID, userID, username, businessConnectionID)
|
b.sendStats(ctx, chatID, businessConnectionID)
|
||||||
return
|
return
|
||||||
case "/whoami":
|
case "/whoami":
|
||||||
b.sendWhoAmI(ctx, chatID, userID, username, businessConnectionID)
|
b.sendWhoAmI(ctx, chatID, userID, username, businessConnectionID)
|
||||||
|
|||||||
Reference in New Issue
Block a user