A few updates, cleanup updated weather module.
This commit is contained in:
132
bot.sh
132
bot.sh
@@ -5,6 +5,19 @@ if [ "$(whoami)" = "root" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if bot.cfg exists, if not create it from example
|
||||
if [[ ! -f "bot.cfg" ]]; then
|
||||
if [[ -f "bot.cfg.example" ]]; then
|
||||
echo "bot.cfg not found. Creating from bot.cfg.example..."
|
||||
cp "bot.cfg.example" "bot.cfg"
|
||||
echo "Please edit bot.cfg to configure your bot (server, channel, nick, etc.)."
|
||||
exit 0
|
||||
else
|
||||
echo "Neither bot.cfg nor bot.cfg.example found."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Load required files.
|
||||
for i in "bot.cfg" "functions.sh" ; do
|
||||
if [[ -f "$i" ]]; then
|
||||
@@ -23,6 +36,21 @@ export ignoreList
|
||||
export nick
|
||||
export quitMessage
|
||||
|
||||
# Check for critical dependencies needed by the bot core
|
||||
coreDependencies=("socat" "tail" "shuf" "grep" "sed" "tr" "cut" "date")
|
||||
missingCore=()
|
||||
for dep in "${coreDependencies[@]}"; do
|
||||
if ! command -v "$dep" &> /dev/null; then
|
||||
missingCore+=("$dep")
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#missingCore[@]} -gt 0 ]]; then
|
||||
echo "ERROR: Missing critical dependencies: ${missingCore[*]}"
|
||||
echo "Please install these packages before running the bot."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function called on exit to remove the temporary input file.
|
||||
rm_input() {
|
||||
if [[ -f "$input" ]]; then
|
||||
@@ -30,19 +58,66 @@ rm_input() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to trim log file to prevent unbounded growth
|
||||
# Keeps log between 800-1000 lines by trimming oldest entries when limit reached
|
||||
trim_log() {
|
||||
local logFile="$1"
|
||||
local maxLines=1000
|
||||
local trimTo=800
|
||||
|
||||
# Only check if log file exists and is readable
|
||||
if [[ ! -f "$logFile" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Count lines efficiently
|
||||
local lineCount
|
||||
lineCount=$(wc -l < "$logFile" 2>/dev/null || echo 0)
|
||||
|
||||
# If over limit, trim to keep most recent entries
|
||||
if [[ $lineCount -gt $maxLines ]]; then
|
||||
tail -n "$trimTo" "$logFile" > "${logFile}.tmp" && mv "${logFile}.tmp" "$logFile"
|
||||
fi
|
||||
}
|
||||
|
||||
# Trap exiting ffrom the program to remove the temporary input file.
|
||||
trap rm_input EXIT
|
||||
|
||||
# Set up the connection.
|
||||
echo -e "Session started $(date "+%I:%M%p%n %A, %B %d, %Y").\n\nTo gracefully exit, make sure you are in the allow list and send the command exit to the bot.\n\n" | tee "$log"
|
||||
echo "NICK $nick" > "$input"
|
||||
echo "USER $user" >> "$input"
|
||||
echo "JOIN #$channel" >> "$input"
|
||||
# Reconnection loop - keeps bot connected even if connection drops
|
||||
reconnectDelay=10
|
||||
while true; do
|
||||
# Set up the connection.
|
||||
echo -e "Session started $(date "+%I:%M%p%n %A, %B %d, %Y").\n\nTo gracefully exit, make sure you are in the allow list and send the command exit to the bot.\n\n" | tee -a "$log"
|
||||
echo "NICK $nick" > "$input"
|
||||
echo "USER $user" >> "$input"
|
||||
echo "JOIN #$channel" >> "$input"
|
||||
|
||||
# The main loop of the program where we watch for output from irc.
|
||||
tail -f "$input" | telnet "$server" "$port" | while read -r result ; do
|
||||
# The main loop of the program where we watch for output from irc.
|
||||
# Use SSL if enabled, otherwise plain TCP
|
||||
if [[ "${useSSL,,}" == "true" ]]; then
|
||||
socatAddress="SSL:${server}:${port},verify=0"
|
||||
else
|
||||
socatAddress="TCP:${server}:${port}"
|
||||
fi
|
||||
|
||||
# Counter for log trimming (check every 50 messages)
|
||||
logTrimCounter=0
|
||||
|
||||
tail -f "$input" | socat -,ignoreeof "$socatAddress" | while read -r result ; do
|
||||
# Strip carriage return from IRC protocol (CRLF line endings)
|
||||
result="${result%$'\r'}"
|
||||
# Sanitize control characters for logging (prevent log injection)
|
||||
logSanitized="${result//[$'\001'-$'\037'$'\177']/}"
|
||||
# log the session
|
||||
echo "$(date "+[$dateFormat]") $result" >> "$log"
|
||||
echo "$logSanitized [$(date "+$dateFormat")]" >> "$log"
|
||||
|
||||
# Periodically trim log to prevent unbounded growth
|
||||
((logTrimCounter++))
|
||||
if [[ $logTrimCounter -ge 50 ]]; then
|
||||
trim_log "$log"
|
||||
logTrimCounter=0
|
||||
fi
|
||||
|
||||
# do things when you see output
|
||||
case "$result" in
|
||||
# Handle nick changes
|
||||
@@ -51,7 +126,7 @@ tail -f "$input" | telnet "$server" "$port" | while read -r result ; do
|
||||
originalNick="${result#:}"
|
||||
originalNick="${originalNick%%!*}"
|
||||
# If the old nick was in the ignore list, update it.
|
||||
if [[ "${originalNick}" =~ [${ignoreList}] ]]; then
|
||||
if [[ "${originalNick}" =~ ^($ignoreList)$ ]]; then
|
||||
export ignoreList="${ignoreList/${originalNick}/${result#:*:}}"
|
||||
fi
|
||||
;;
|
||||
@@ -83,11 +158,10 @@ tail -f "$input" | telnet "$server" "$port" | while read -r result ; do
|
||||
from="${result#*#}"
|
||||
from="#$from"
|
||||
if [ "$who" = "$nick" ]; then
|
||||
continue
|
||||
continue
|
||||
fi
|
||||
echo "MODE #$channel +o $who" | tee -a "$input"
|
||||
if [ "${greet^^}" = "TRUE" ]; then
|
||||
set -f
|
||||
set -f
|
||||
./triggers/greet/greet.sh "$who" "$from"
|
||||
set +f
|
||||
fi
|
||||
@@ -109,7 +183,7 @@ tail -f "$input" | telnet "$server" "$port" | while read -r result ; do
|
||||
;;
|
||||
# run when a private message is seen
|
||||
*"PRIVMSG "[[:alnum:]-_]*)
|
||||
echo "$result" >> "$log"
|
||||
echo "$logSanitized" >> "$log"
|
||||
who="${result%%!*}"
|
||||
who="${who:1}"
|
||||
from="${who%!*}"
|
||||
@@ -117,12 +191,13 @@ tail -f "$input" | telnet "$server" "$port" | while read -r result ; do
|
||||
command="${command//# /}"
|
||||
will="${command#* }"
|
||||
command="${command%% *}"
|
||||
if [[ "$from" =~ $allowList ]]; then
|
||||
if [[ "$from" =~ ^($allowList)$ ]]; then
|
||||
if command -v "./modules/${command% *}/${command% *}.sh" ; then
|
||||
echo "Calling module ./modules/${command% *}/${command% *}/${command% *}.sh \"$who\" \"$from\" $will" >> "$log"
|
||||
willSanitized="${will//[$'\001'-$'\037'$'\177']/}"
|
||||
echo "Calling module ./modules/${command% *}/${command% *}/${command% *}.sh \"$who\" \"$from\" $willSanitized" >> "$log"
|
||||
# Disable wildcards
|
||||
set -f
|
||||
./modules/${command% *}/${command% *}.sh "$who" "#$channel" $will
|
||||
set -f
|
||||
"./modules/${command% *}/${command% *}.sh" "$who" "#$channel" "$will"
|
||||
# Enable wildcards
|
||||
set +f
|
||||
else
|
||||
@@ -134,7 +209,6 @@ tail -f "$input" | telnet "$server" "$port" | while read -r result ; do
|
||||
;;
|
||||
# run when a message is seen
|
||||
*PRIVMSG*)
|
||||
echo "$result" >> "$log"
|
||||
who="${result%%!*}"
|
||||
who="${who:1}"
|
||||
from="${result#*#}"
|
||||
@@ -144,28 +218,31 @@ tail -f "$input" | telnet "$server" "$port" | while read -r result ; do
|
||||
# Call link trigger if msg contains a link:
|
||||
if [[ "$result" =~ .*http://|https://|www\..* ]]; then
|
||||
set -f
|
||||
echo "Calling link.sh with \"$who\" \"$from\" \"$result\"" >> "$log"
|
||||
echo "Calling link.sh with \"$who\" \"$from\" \"$logSanitized\"" >> "$log"
|
||||
./triggers/link/link.sh "$who" "$from" "$result"
|
||||
set -f
|
||||
# Although this calls modules, it triggers on text other than the bot's nick
|
||||
# To make sure that modules are only called when they are supposed to be, had to combine string monipulation with regexp.
|
||||
elif [[ "${result#:*PRIVMSG*:}" =~ ^[${botCaller}][a-zA-Z0-9_].* ]]; then
|
||||
echo "DEBUG: Matched bot caller pattern" >> "$log"
|
||||
command="${result#*:[[:punct:]]}"
|
||||
command="${command//# /}"
|
||||
will="${command#* }"
|
||||
command="${command%% *}"
|
||||
if command -v "./modules/${command% *}/${command% *}.sh" ; then
|
||||
echo "Calling module ./modules/${command% *}/${command% *}/${command% *}.sh \"$who\" \"$from\" $will" >> "$log"
|
||||
willSanitized="${will//[$'\001'-$'\037'$'\177']/}"
|
||||
echo "DEBUG: command='$command' will='$willSanitized'" >> "$log"
|
||||
if command -v "./modules/${command% *}/${command% *}.sh" &>/dev/null ; then
|
||||
echo "Calling module ./modules/${command% *}/${command% *}.sh \"$who\" \"$from\" $willSanitized" >> "$log"
|
||||
# Disable wildcards
|
||||
set -f
|
||||
./modules/${command% *}/${command% *}.sh "$who" "$from" $will
|
||||
set -f
|
||||
"./modules/${command% *}/${command% *}.sh" "$who" "$from" "$will"
|
||||
# Enable wildcards
|
||||
set +f
|
||||
else
|
||||
./modules/say/say.sh "$who" "$from" "$who: $(shuf -n1 "response/error.txt")"
|
||||
fi
|
||||
else
|
||||
if ! [[ "$who" =~ $ignoreList ]]; then
|
||||
if ! [[ "$who" =~ ^($ignoreList)$ ]]; then
|
||||
set -f
|
||||
./triggers/keywords/keywords.sh "$who" "$from" "$result"
|
||||
set +f
|
||||
@@ -173,9 +250,14 @@ tail -f "$input" | telnet "$server" "$port" | while read -r result ; do
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "$result" >> "$log"
|
||||
echo "$logSanitized" >> "$log"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# If we reach here, the connection was dropped
|
||||
echo "Connection lost. Reconnecting in $reconnectDelay seconds... [$(date "+$dateFormat")]" | tee -a "$log"
|
||||
sleep "$reconnectDelay"
|
||||
done
|
||||
|
||||
rm_input
|
||||
|
||||
Reference in New Issue
Block a user