@@ -15,6 +15,7 @@ import (
1515 "os/signal"
1616 "path/filepath"
1717 "regexp"
18+ "sort"
1819 "strings"
1920 "sync"
2021 "syscall"
@@ -95,6 +96,7 @@ type Config struct {
9596 LinkstashURL string `json:"LINKSTASH_URL,omitempty"`
9697 SyncTimeoutMS int `json:"SYNC_TIMEOUT_MS"`
9798 Debug bool `json:"DEBUG"`
99+ DryRun bool `json:"DRY_RUN"`
98100 DeviceName string `json:"MATRIX_DEVICE_NAME"`
99101 OptOutTag string `json:"OPT_OUT_TAG"`
100102}
@@ -114,6 +116,21 @@ func LoadConfig() (*Config, error) {
114116 return & cfg , nil
115117}
116118
119+ // generateHelpMessage creates a help message listing available commands
120+ func generateHelpMessage (botCfg * BotConfig , allowedCommands []string ) string {
121+ var cmds []string
122+ if len (allowedCommands ) > 0 {
123+ cmds = make ([]string , len (allowedCommands ))
124+ copy (cmds , allowedCommands )
125+ } else {
126+ for cmd := range botCfg .Commands {
127+ cmds = append (cmds , cmd )
128+ }
129+ }
130+ sort .Strings (cmds )
131+ return "Available commands: " + strings .Join (cmds , ", " )
132+ }
133+
117134func OpenMeta (ctx context.Context , path string ) (* sql.DB , error ) {
118135 return openWithSchema (ctx , path , "db/schema_meta.sql" )
119136}
@@ -433,32 +450,6 @@ func resolveURL(url string) string {
433450 return resp .Request .URL .String ()
434451}
435452
436- // fetchRandomJoke fetches a random dad joke from icanhazdadjoke.com
437- func fetchRandomJoke (ctx context.Context ) (string , error ) {
438- req , err := http .NewRequestWithContext (ctx , "GET" , "https://icanhazdadjoke.com/" , nil )
439- if err != nil {
440- return "" , err
441- }
442- req .Header .Set ("Accept" , "application/json" )
443- req .Header .Set ("User-Agent" , "ash-bot (https://github.com/polarhive/ash)" )
444- client := & http.Client {Timeout : 5 * time .Second }
445- resp , err := client .Do (req )
446- if err != nil {
447- return "" , err
448- }
449- defer resp .Body .Close ()
450- if resp .StatusCode != http .StatusOK {
451- return "" , fmt .Errorf ("unexpected status: %d" , resp .StatusCode )
452- }
453- var payload struct {
454- Joke string `json:"joke"`
455- }
456- if err := json .NewDecoder (resp .Body ).Decode (& payload ); err != nil {
457- return "" , err
458- }
459- return payload .Joke , nil
460- }
461-
462453type LinkRow struct {
463454 MessageID string `json:"message_id"`
464455 URL string `json:"url"`
@@ -670,6 +661,10 @@ func run(ctx context.Context, metaDB *sql.DB, messagesDB *sql.DB, cfg *Config) e
670661 return
671662 }
672663 log .Info ().Str ("sender" , string (ev .Sender )).Str ("room" , currentRoom .Comment ).Msg (truncate (msgData .Msg .Body , 100 ))
664+ if cfg .DryRun {
665+ log .Info ().Msg ("dry run mode: skipping bot commands and hooks" )
666+ return
667+ }
673668 if cfg .BotReplyLabel != "" && strings .Contains (msgData .Msg .Body , cfg .BotReplyLabel ) {
674669 log .Debug ().Str ("label" , cfg .BotReplyLabel ).Msg ("skipped bot processing due to bot reply label" )
675670 return
@@ -692,38 +687,21 @@ func run(ctx context.Context, metaDB *sql.DB, messagesDB *sql.DB, cfg *Config) e
692687 body = "command not allowed in this room"
693688 } else {
694689 if botCfg != nil {
695- if cmdCfg , ok := botCfg .Commands [cmd ]; ok {
696- resp , err := FetchBotCommand (evCtx , & cmdCfg , cfg .LinkstashURL )
690+ if cmd == "help" {
691+ body = generateHelpMessage (botCfg , currentRoom .AllowedCommands )
692+ } else if cmdCfg , ok := botCfg .Commands [cmd ]; ok {
693+ resp , err := FetchBotCommand (evCtx , & cmdCfg , cfg .LinkstashURL , ev , client )
697694 if err != nil {
698- log .Error ().Err (err ).Str ("cmd" , cmd ).Msg ("failed to fetch bot command" )
699- body = fmt .Sprintf ("sorry, couldn't fetch %s right now" , cmd )
695+ log .Error ().Err (err ).Str ("cmd" , cmd ).Msg ("failed to execute bot command" )
696+ body = fmt .Sprintf ("sorry, couldn't execute %s right now" , cmd )
700697 } else {
701698 body = resp
702699 }
703- } else if cmd == "joke" {
704- joke , err := fetchRandomJoke (evCtx )
705- if err != nil {
706- log .Error ().Err (err ).Msg ("failed to fetch joke" )
707- body = "sorry, couldn't fetch a joke right now"
708- } else {
709- body = joke
710- }
711700 } else {
712- body = "unknown command"
701+ body = "Unknown command. " + generateHelpMessage ( botCfg , currentRoom . AllowedCommands )
713702 }
714703 } else {
715- // No bot config loaded; fall back to built-in joke
716- if cmd == "joke" {
717- joke , err := fetchRandomJoke (evCtx )
718- if err != nil {
719- log .Error ().Err (err ).Msg ("failed to fetch joke" )
720- body = "sorry, couldn't fetch a joke right now"
721- } else {
722- body = joke
723- }
724- } else {
725- body = "unknown command"
726- }
704+ body = "no bot configuration loaded"
727705 }
728706 }
729707 label := "> "
0 commit comments