Compare commits
No commits in common. "899ac49336e958d98500ad8c65f45d0bc602883f" and "3a4ba376e75503caab4da111c4941969f9793c0e" have entirely different histories.
899ac49336
...
3a4ba376e7
9 changed files with 31 additions and 99 deletions
|
@ -10,11 +10,6 @@ When creating, modifying, or removing plugins:
|
||||||
- Brief description of functionality
|
- Brief description of functionality
|
||||||
- Usage instructions with examples
|
- Usage instructions with examples
|
||||||
- Any configuration requirements
|
- Any configuration requirements
|
||||||
3. **For plugins with configuration options:**
|
|
||||||
- Set `ConfigRequired: true` in the plugin's BasePlugin struct
|
|
||||||
- Add corresponding HTML form fields in `internal/admin/templates/channel_plugin_config.html`
|
|
||||||
- Use conditional template logic: `{{else if eq .ChannelPlugin.PluginID "plugin.id"}}`
|
|
||||||
- Include proper form labels, help text, and value binding
|
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
|
|
|
@ -23,5 +23,5 @@
|
||||||
|
|
||||||
### Social Media
|
### Social Media
|
||||||
|
|
||||||
- Twitter Link Expander: Automatically converts twitter.com and x.com links to alternative domain links and removes tracking parameters. This allows for better media embedding in chat platforms. Configure with `domain` option to set replacement domain (default: fxtwitter.com).
|
- Twitter Link Expander: Automatically converts twitter.com and x.com links to fxtwitter.com links and removes tracking parameters. This allows for better media embedding in chat platforms.
|
||||||
- Instagram Link Expander: Automatically converts instagram.com links to alternative domain links and removes tracking parameters. This allows for better media embedding in chat platforms. Configure with `domain` option to set replacement domain (default: ddinstagram.com).
|
- Instagram Link Expander: Automatically converts instagram.com links to ddinstagram.com links and removes tracking parameters. This allows for better media embedding in chat platforms.
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
"github.com/gorilla/sessions"
|
"github.com/gorilla/sessions"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed templates/*.html templates/plugins/*.html
|
//go:embed templates/*.html
|
||||||
var templateFS embed.FS
|
var templateFS embed.FS
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -90,7 +90,7 @@ func New(cfg *config.Config, database *db.Database, version string) *Admin {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse and register all templates
|
// Parse and register all templates
|
||||||
mainTemplateFiles := []string{
|
templateFiles := []string{
|
||||||
"index.html",
|
"index.html",
|
||||||
"login.html",
|
"login.html",
|
||||||
"change_password.html",
|
"change_password.html",
|
||||||
|
@ -101,13 +101,7 @@ func New(cfg *config.Config, database *db.Database, version string) *Admin {
|
||||||
"channel_plugin_config.html",
|
"channel_plugin_config.html",
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginTemplateFiles := []string{
|
for _, tf := range templateFiles {
|
||||||
"plugins/security.domainblock.html",
|
|
||||||
"plugins/social.instagram.html",
|
|
||||||
"plugins/social.twitter.html",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tf := range mainTemplateFiles {
|
|
||||||
// Read template content from embedded filesystem
|
// Read template content from embedded filesystem
|
||||||
content, err := templateFS.ReadFile("templates/" + tf)
|
content, err := templateFS.ReadFile("templates/" + tf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -126,20 +120,6 @@ func New(cfg *config.Config, database *db.Database, version string) *Admin {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is the channel_plugin_config template, also parse plugin templates
|
|
||||||
if tf == "channel_plugin_config.html" {
|
|
||||||
for _, pluginTf := range pluginTemplateFiles {
|
|
||||||
pluginContent, err := templateFS.ReadFile("templates/" + pluginTf)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
t, err = t.Parse(string(pluginContent))
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
templates[tf] = t
|
templates[tf] = t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,16 @@
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<!-- Plugin configuration fields -->
|
<!-- Plugin configuration fields -->
|
||||||
{{if eq .ChannelPlugin.PluginID "security.domainblock"}}
|
{{if eq .ChannelPlugin.PluginID "security.domainblock"}}
|
||||||
{{template "plugins/security.domainblock.html" .}}
|
<div class="mb-3">
|
||||||
{{else if eq .ChannelPlugin.PluginID "social.instagram"}}
|
<label class="form-label">Blocked Domains</label>
|
||||||
{{template "plugins/social.instagram.html" .}}
|
<input type="text" class="form-control" name="blocked_domains"
|
||||||
{{else if eq .ChannelPlugin.PluginID "social.twitter"}}
|
value="{{with .ChannelPlugin.Config}}{{index . "blocked_domains"}}{{end}}"
|
||||||
{{template "plugins/social.twitter.html" .}}
|
placeholder="example.com, evil.org, ads.com">
|
||||||
|
<div class="form-text text-muted">
|
||||||
|
Enter comma-separated list of domains to block (e.g., example.com, evil.org).
|
||||||
|
Messages containing links to these domains will be blocked.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
This plugin doesn't have specific configuration fields implemented yet.
|
This plugin doesn't have specific configuration fields implemented yet.
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
{{define "plugins/security.domainblock.html"}}
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label">Blocked Domains</label>
|
|
||||||
<input type="text" class="form-control" name="blocked_domains"
|
|
||||||
value="{{with .ChannelPlugin.Config}}{{index . "blocked_domains"}}{{end}}"
|
|
||||||
placeholder="example.com, evil.org, ads.com">
|
|
||||||
<div class="form-text text-muted">
|
|
||||||
Enter comma-separated list of domains to block (e.g., example.com, evil.org).
|
|
||||||
Messages containing links to these domains will be blocked.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
|
@ -1,11 +0,0 @@
|
||||||
{{define "plugins/social.instagram.html"}}
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label">Replacement Domain</label>
|
|
||||||
<input type="text" class="form-control" name="domain"
|
|
||||||
value="{{with .ChannelPlugin.Config}}{{index . "domain"}}{{end}}"
|
|
||||||
placeholder="ddinstagram.com">
|
|
||||||
<div class="form-text text-muted">
|
|
||||||
Enter the domain to replace instagram.com links with. Default is ddinstagram.com if left empty.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
|
@ -1,11 +0,0 @@
|
||||||
{{define "plugins/social.twitter.html"}}
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label">Replacement Domain</label>
|
|
||||||
<input type="text" class="form-control" name="domain"
|
|
||||||
value="{{with .ChannelPlugin.Config}}{{index . "domain"}}{{end}}"
|
|
||||||
placeholder="fxtwitter.com">
|
|
||||||
<div class="form-text text-muted">
|
|
||||||
Enter the domain to replace twitter.com and x.com links with. Default is fxtwitter.com if left empty.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
|
@ -20,8 +20,7 @@ func NewInstagramExpander() *InstagramExpander {
|
||||||
BasePlugin: plugin.BasePlugin{
|
BasePlugin: plugin.BasePlugin{
|
||||||
ID: "social.instagram",
|
ID: "social.instagram",
|
||||||
Name: "Instagram Link Expander",
|
Name: "Instagram Link Expander",
|
||||||
Help: "Automatically converts instagram.com links to alternative domain links and removes tracking parameters. Configure 'domain' option to set replacement domain (default: ddinstagram.com)",
|
Help: "Automatically converts instagram.com links to ddinstagram.com links and removes tracking parameters",
|
||||||
ConfigRequired: true,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,12 +32,6 @@ func (p *InstagramExpander) OnMessage(msg *model.Message, config map[string]inte
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get replacement domain from config, default to ddinstagram.com
|
|
||||||
replacementDomain := "ddinstagram.com"
|
|
||||||
if domain, ok := config["domain"].(string); ok && domain != "" {
|
|
||||||
replacementDomain = domain
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regex to match instagram.com links
|
// Regex to match instagram.com links
|
||||||
// Match both http://instagram.com and https://instagram.com formats
|
// Match both http://instagram.com and https://instagram.com formats
|
||||||
// Also match www.instagram.com
|
// Also match www.instagram.com
|
||||||
|
@ -49,7 +42,7 @@ func (p *InstagramExpander) OnMessage(msg *model.Message, config map[string]inte
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace instagram.com with configured domain in the message and clean query parameters
|
// Replace instagram.com with ddinstagram.com in the message and clean query parameters
|
||||||
transformed := instagramRegex.ReplaceAllStringFunc(msg.Text, func(link string) string {
|
transformed := instagramRegex.ReplaceAllStringFunc(msg.Text, func(link string) string {
|
||||||
// Parse the URL
|
// Parse the URL
|
||||||
parsedURL, err := url.Parse(link)
|
parsedURL, err := url.Parse(link)
|
||||||
|
@ -58,13 +51,13 @@ func (p *InstagramExpander) OnMessage(msg *model.Message, config map[string]inte
|
||||||
return link
|
return link
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure we don't change links that already come from the replacement domain
|
// Ensure we don't change links that already come from ddinstagram.com
|
||||||
if parsedURL.Host != "instagram.com" && parsedURL.Host != "www.instagram.com" {
|
if parsedURL.Host != "instagram.com" && parsedURL.Host != "www.instagram.com" {
|
||||||
return link
|
return link
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change the host to the configured domain
|
// Change the host
|
||||||
parsedURL.Host = replacementDomain
|
parsedURL.Host = "d.ddinstagram.com"
|
||||||
|
|
||||||
// Remove query parameters
|
// Remove query parameters
|
||||||
parsedURL.RawQuery = ""
|
parsedURL.RawQuery = ""
|
||||||
|
|
|
@ -20,8 +20,7 @@ func NewTwitterExpander() *TwitterExpander {
|
||||||
BasePlugin: plugin.BasePlugin{
|
BasePlugin: plugin.BasePlugin{
|
||||||
ID: "social.twitter",
|
ID: "social.twitter",
|
||||||
Name: "Twitter Link Expander",
|
Name: "Twitter Link Expander",
|
||||||
Help: "Automatically converts twitter.com and x.com links to alternative domain links and removes tracking parameters. Configure 'domain' option to set replacement domain (default: fxtwitter.com)",
|
Help: "Automatically converts twitter.com links to fxtwitter.com links and removes tracking parameters",
|
||||||
ConfigRequired: true,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,12 +32,6 @@ func (p *TwitterExpander) OnMessage(msg *model.Message, config map[string]interf
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get replacement domain from config, default to fxtwitter.com
|
|
||||||
replacementDomain := "fxtwitter.com"
|
|
||||||
if domain, ok := config["domain"].(string); ok && domain != "" {
|
|
||||||
replacementDomain = domain
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regex to match twitter.com links
|
// Regex to match twitter.com links
|
||||||
// Match both http://twitter.com and https://twitter.com formats
|
// Match both http://twitter.com and https://twitter.com formats
|
||||||
// Also match www.twitter.com
|
// Also match www.twitter.com
|
||||||
|
@ -49,22 +42,22 @@ func (p *TwitterExpander) OnMessage(msg *model.Message, config map[string]interf
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace twitter.com/x.com with configured domain in the message and clean query parameters
|
// Replace twitter.com with fxtwitter.com in the message and clean query parameters
|
||||||
transformed := twitterRegex.ReplaceAllStringFunc(msg.Text, func(link string) string {
|
transformed := twitterRegex.ReplaceAllStringFunc(msg.Text, func(link string) string {
|
||||||
// Parse the URL
|
// Parse the URL
|
||||||
parsedURL, err := url.Parse(link)
|
parsedURL, err := url.Parse(link)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If parsing fails, just do the simple replacement
|
// If parsing fails, just do the simple replacement
|
||||||
link = strings.Replace(link, "twitter.com", replacementDomain, 1)
|
link = strings.Replace(link, "twitter.com", "fxtwitter.com", 1)
|
||||||
link = strings.Replace(link, "x.com", replacementDomain, 1)
|
link = strings.Replace(link, "x.com", "fxtwitter.com", 1)
|
||||||
return link
|
return link
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change the host to the configured domain
|
// Change the host
|
||||||
if strings.Contains(parsedURL.Host, "twitter.com") {
|
if strings.Contains(parsedURL.Host, "twitter.com") {
|
||||||
parsedURL.Host = strings.Replace(parsedURL.Host, "twitter.com", replacementDomain, 1)
|
parsedURL.Host = strings.Replace(parsedURL.Host, "twitter.com", "fxtwitter.com", 1)
|
||||||
} else if strings.Contains(parsedURL.Host, "x.com") {
|
} else if strings.Contains(parsedURL.Host, "x.com") {
|
||||||
parsedURL.Host = strings.Replace(parsedURL.Host, "x.com", replacementDomain, 1)
|
parsedURL.Host = strings.Replace(parsedURL.Host, "x.com", "fxtwitter.com", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove query parameters
|
// Remove query parameters
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue