diff --git a/CLAUDE.md b/CLAUDE.md
index cb4e70a..2191848 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -18,12 +18,10 @@ When creating, modifying, or removing plugins:
## Testing
-**CRITICAL**: After making ANY changes to code files, you MUST run these commands in order:
+Before committing plugin changes:
-1. **Format code**: `make format` - Format all code according to project standards
-2. **Lint code**: `make lint` - Check code style and quality (must show "0 issues")
-3. **Run tests**: `make test` - Run all tests to ensure functionality works
+1. Check files are properly formatted: Run `make format`
+2. Check code style and linting: Run `make lint`
+3. Test the plugin functionality: Run `make test`
4. Verify documentation accuracy
5. Ensure all examples work as described
-
-**These commands are MANDATORY after every code change, no exceptions.**
diff --git a/internal/admin/templates/channel_detail.html b/internal/admin/templates/channel_detail.html
index 7e12d57..9f9a78d 100644
--- a/internal/admin/templates/channel_detail.html
+++ b/internal/admin/templates/channel_detail.html
@@ -32,7 +32,7 @@
Enable All Plugins
-
+
When enabled, all registered plugins will be automatically enabled for this channel. Individual plugin settings will be ignored.
@@ -124,4 +124,4 @@
-{{end}}
+{{end}}
\ No newline at end of file
diff --git a/internal/db/db_test.go b/internal/db/db_test.go
index beb485d..88ab470 100644
--- a/internal/db/db_test.go
+++ b/internal/db/db_test.go
@@ -200,4 +200,4 @@ func TestEnableAllPlugins(t *testing.T) {
t.Errorf("EnableAllPlugins should be true after update")
}
})
-}
+}
\ No newline at end of file
diff --git a/internal/model/message_test.go b/internal/model/message_test.go
index d2dfedc..d94c5ea 100644
--- a/internal/model/message_test.go
+++ b/internal/model/message_test.go
@@ -231,4 +231,4 @@ func TestChannelName(t *testing.T) {
t.Errorf("Expected channel name to fallback to 'fallback-id', got '%s'", result)
}
})
-}
+}
\ No newline at end of file
diff --git a/internal/platform/telegram/telegram.go b/internal/platform/telegram/telegram.go
index b015793..24714f2 100644
--- a/internal/platform/telegram/telegram.go
+++ b/internal/platform/telegram/telegram.go
@@ -233,17 +233,9 @@ func (t *TelegramPlatform) SendMessage(msg *model.Message) error {
// Prepare payload
payload := map[string]interface{}{
- "chat_id": chatID,
- "text": msg.Text,
- }
-
- // Set parse_mode based on plugin preference or default to empty string
- if msg.Raw != nil && msg.Raw["parse_mode"] != nil {
- // Plugin explicitly set parse_mode
- payload["parse_mode"] = msg.Raw["parse_mode"]
- } else {
- // Default to empty string (no formatting)
- payload["parse_mode"] = ""
+ "chat_id": chatID,
+ "text": msg.Text,
+ "parse_mode": "Markdown",
}
// Add reply if needed
diff --git a/internal/plugin/fun/hltb.go b/internal/plugin/fun/hltb.go
index f94f2ba..227d637 100644
--- a/internal/plugin/fun/hltb.go
+++ b/internal/plugin/fun/hltb.go
@@ -131,15 +131,12 @@ func (p *HLTBPlugin) OnMessage(msg *model.Message, config map[string]interface{}
Channel: msg.Channel,
}
- // Set parse mode for markdown formatting
- if responseMsg.Raw == nil {
- responseMsg.Raw = make(map[string]interface{})
- }
- responseMsg.Raw["parse_mode"] = "Markdown"
-
// Add game cover as attachment if available
if game.GameImage != "" {
imageURL := p.getFullImageURL(game.GameImage)
+ if responseMsg.Raw == nil {
+ responseMsg.Raw = make(map[string]interface{})
+ }
responseMsg.Raw["image_url"] = imageURL
}
diff --git a/internal/plugin/help/help.go b/internal/plugin/help/help.go
index 4e6215a..88b25dd 100644
--- a/internal/plugin/help/help.go
+++ b/internal/plugin/help/help.go
@@ -74,7 +74,6 @@ func (p *HelpPlugin) OnMessage(msg *model.Message, config map[string]interface{}
Chat: msg.Chat,
ReplyTo: msg.ID,
Channel: msg.Channel,
- Raw: map[string]interface{}{"parse_mode": "Markdown"},
}
return []*model.MessageAction{
@@ -152,7 +151,6 @@ func (p *HelpPlugin) OnMessage(msg *model.Message, config map[string]interface{}
Chat: msg.Chat,
ReplyTo: msg.ID,
Channel: msg.Channel,
- Raw: map[string]interface{}{"parse_mode": "Markdown"},
}
return []*model.MessageAction{
diff --git a/internal/plugin/plugin_test.go b/internal/plugin/plugin_test.go
index 0bfd207..e0b68d3 100644
--- a/internal/plugin/plugin_test.go
+++ b/internal/plugin/plugin_test.go
@@ -328,4 +328,4 @@ func TestPluginRegistry(t *testing.T) {
t.Errorf("Expected error when getting plugin after clearing registry, got nil")
}
})
-}
+}
\ No newline at end of file
diff --git a/internal/plugin/social/twitter_test.go b/internal/plugin/social/twitter_test.go
deleted file mode 100644
index c0e1681..0000000
--- a/internal/plugin/social/twitter_test.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package social
-
-import (
- "testing"
-
- "git.nakama.town/fmartingr/butterrobot/internal/model"
-)
-
-func TestTwitterExpander_OnMessage(t *testing.T) {
- plugin := NewTwitterExpander()
-
- tests := []struct {
- name string
- input string
- config map[string]interface{}
- expected string
- hasReply bool
- }{
- {
- name: "Twitter URL with default domain",
- input: "https://twitter.com/user/status/123456789",
- config: map[string]interface{}{},
- expected: "https://fxtwitter.com/user/status/123456789",
- hasReply: true,
- },
- {
- name: "X.com URL with custom domain",
- input: "https://x.com/elonmusk/status/987654321",
- config: map[string]interface{}{"domain": "vxtwitter.com"},
- expected: "https://vxtwitter.com/elonmusk/status/987654321",
- hasReply: true,
- },
- {
- name: "Twitter URL with tracking parameters",
- input: "https://twitter.com/openai/status/555?ref_src=twsrc%5Etfw&s=20",
- config: map[string]interface{}{},
- expected: "https://fxtwitter.com/openai/status/555",
- hasReply: true,
- },
- {
- name: "www.twitter.com URL",
- input: "https://www.twitter.com/user/status/789",
- config: map[string]interface{}{"domain": "nitter.net"},
- expected: "https://nitter.net/user/status/789",
- hasReply: true,
- },
- {
- name: "Mixed text with Twitter URL",
- input: "Check this out: https://twitter.com/user/status/123 amazing!",
- config: map[string]interface{}{},
- expected: "Check this out: https://fxtwitter.com/user/status/123 amazing!",
- hasReply: true,
- },
- {
- name: "No Twitter URLs",
- input: "Just some regular text https://youtube.com/watch?v=abc",
- config: map[string]interface{}{},
- expected: "",
- hasReply: false,
- },
- {
- name: "Empty message",
- input: "",
- config: map[string]interface{}{},
- expected: "",
- hasReply: false,
- },
- }
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- msg := &model.Message{
- ID: "test_msg",
- Text: tt.input,
- Chat: "test_chat",
- Channel: &model.Channel{
- ID: 1,
- Platform: "telegram",
- PlatformChannelID: "test_chat",
- },
- }
-
- actions := plugin.OnMessage(msg, tt.config, nil)
-
- if !tt.hasReply {
- if len(actions) != 0 {
- t.Errorf("Expected no actions, got %d", len(actions))
- }
- return
- }
-
- if len(actions) != 1 {
- t.Errorf("Expected 1 action, got %d", len(actions))
- return
- }
-
- action := actions[0]
- if action.Type != model.ActionSendMessage {
- t.Errorf("Expected ActionSendMessage, got %s", action.Type)
- }
-
- if action.Message == nil {
- t.Error("Expected message in action, got nil")
- return
- }
-
- if action.Message.Text != tt.expected {
- t.Errorf("Expected '%s', got '%s'", tt.expected, action.Message.Text)
- }
-
- if action.Message.ReplyTo != msg.ID {
- t.Errorf("Expected ReplyTo '%s', got '%s'", msg.ID, action.Message.ReplyTo)
- }
-
- if action.Message.Raw == nil || action.Message.Raw["parse_mode"] != "" {
- t.Error("Expected parse_mode to be empty string to disable markdown parsing")
- }
- })
- }
-}