# =============================================
# !tell script for Eggdrop
# Usage: !tell <nick> <message>
# Admin: /msg <bot> !cleartell (bot owners only)
# =============================================
namespace eval tell {
variable tellfile "scripts/tell.db" ;# storage file (relative to the eggdrop dir)
variable maxpending 10 ;# max queued messages per nick (0 = unlimited)
variable messages
array set messages {}
# Load queued messages from disk
proc load {} {
variable messages
variable tellfile
array unset messages
array set messages {}
if {![file exists $tellfile]} { return }
if {[catch {open $tellfile r} fd]} {
putlog "tell.tcl: cannot read $tellfile: $fd"
return
}
fconfigure $fd -encoding utf-8
while {[gets $fd line] >= 0} {
if {[string trim $line] eq ""} { continue }
# each line is a clean Tcl list: target sender time message
if {[catch {lassign $line target sender time message}]} { continue }
if {$target eq ""} { continue }
lappend messages([string tolower $target]) [list $sender $time $message]
}
close $fd
}
# Persist queued messages to disk
proc save {} {
variable messages
variable tellfile
if {[catch {open $tellfile w} fd]} {
putlog "tell.tcl: cannot write $tellfile: $fd"
return
}
fconfigure $fd -encoding utf-8
foreach target [array names messages] {
foreach m $messages($target) {
lassign $m sender time message
puts $fd [list $target $sender $time $message]
}
}
close $fd
}
# !tell <nick> <message>
proc do_tell {nick uhost hand chan text} {
variable messages
variable maxpending
if {![regexp {^\s*(\S+)\s+(.+)$} $text -> target message]} {
puthelp "PRIVMSG $chan :Usage: !tell <nick> <message>"
return
}
set message [string trim $message]
set ltarget [string tolower $target]
if {$maxpending > 0 && [info exists messages($ltarget)] \
&& [llength $messages($ltarget)] >= $maxpending} {
puthelp "PRIVMSG $chan :$nick: $target already has $maxpending messages waiting - try again later."
return
}
set timestamp [clock format [clock seconds] -gmt 1 -format "%d/%m %H:%M GMT"]
lappend messages($ltarget) [list $nick $timestamp $message]
save
puthelp "PRIVMSG $chan :$nick: noted. $target will be told the next time they're around."
}
# Deliver queued messages (on join or when the user speaks)
proc deliver {nick uhost hand chan {text ""}} {
variable messages
set lnick [string tolower $nick]
if {![info exists messages($lnick)] || [llength $messages($lnick)] == 0} {
return
}
foreach m $messages($lnick) {
lassign $m sender time message
puthelp "PRIVMSG $chan :$nick: $sender left you a message on $time - $message"
}
unset messages($lnick)
save
}
# !cleartell (owner only via private message)
proc clear_tells {nick uhost hand text} {
variable messages
set n 0
foreach t [array names messages] { incr n [llength $messages($t)] }
array unset messages
array set messages {}
save
puthelp "PRIVMSG $nick :Cleared $n pending message(s)."
}
bind pub - "!tell" ::tell::do_tell
bind join - * ::tell::deliver
bind pubm - * ::tell::deliver ;# deliver when the user next speaks
bind msg o "!cleartell" ::tell::clear_tells
load
putlog "tell.tcl loaded - !tell system active"
}