This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.
For more information, see this announcement post . Click the X in the top right-corner of this box to dismiss this message.
General support and discussion of Eggdrop bots.
blake
Master
Posts: 201 Joined: Mon Feb 23, 2009 9:42 am
Contact:
Post
by blake » Wed Nov 23, 2011 6:26 pm
Hey
Im trying to use a twitter script but keep getting the following error can any one help with how i would install this package
[01:22:22] Tcl error in file 'eggdrop.conf':
[01:22:22] can't find package base64
while executing
"package require base64"
(file "scripts/twitter.tcl" line 43)
invoked from within
"source scripts/twitter.tcl"
(file "eggdrop.conf" line 1352)
[01:22:22] * CONFIG FILE NOT LOADED (NOT FOUND, OR ERROR)
many thanks
nml375
Revered One
Posts: 2860 Joined: Fri Aug 04, 2006 2:09 pm
Post
by nml375 » Wed Nov 23, 2011 6:45 pm
Your system is missing the base64 tcl-package (not to be confused with distribution packages such as deb's and rpm's). A good source for this would be the tcllib project (
http://sourceforge.net/projects/tcllib/ ). Just download and follow the installation instructions...
NML_375
blake
Master
Posts: 201 Joined: Mon Feb 23, 2009 9:42 am
Contact:
Post
by blake » Wed Nov 23, 2011 7:03 pm
nml375 wrote: Your system is missing the base64 tcl-package (not to be confused with distribution packages such as deb's and rpm's). A good source for this would be the tcllib project (
http://sourceforge.net/projects/tcllib/ ). Just download and follow the installation instructions...
I have sorted that but i now get the following error
Code: Select all
[22:54] <TwitterBot> [01:54:08] HTTP query failed: 401 (URL: http://twitter.com/statuses/friends.json) (QUERY_LIST: ) (QUERY: ) (METHOD: ) (USED METHOD: GET)
Im assuming that the script may be out dated
Code: Select all
# 0.1 - Feb 6 2010
#
# Created by fedex and cd. www.summercat.com for updates
#
# Requirements: Tcl 8.5+ and tcllib of some version (for base64, json)
#
# Essentially a twitter client for IRC. Follow updates from tweets of all
# those you follow on the given account.
#
# Usage notes:
# - Stores states in variable $idfile file in eggdrop root directory
# - Default time between tweet fetches is 10 minutes. Alter the "bind time"
# option below to change to a different setting. Right now there is only
# options for 1 minute or 10 minutes.
# - Accepts commands issued by anyone right now! Perhaps if you wish to use
# in a channel with untrusted people, have one channel for output and one
# for controlling the script client style (+twitter)
#
# Setup:
# - Place your username and pass in the variables user and pas
# - Set the channel variable as the channel where tweets will be output
# - .chanset #channel +twitter to provide access to !commands in #channel
#
# Commands:
# - !twit - send a tweet
# - !twit_msg
# - !twit_trends
# - !follow
# - !unfollow
# - !twit_updates
# - !twit_msgs
# - !twit_search
# - !followers
# - !following
# - !retweet
#
# TODO:
#
package require http
# tcllib packages
package require base64
package require json
namespace eval twitter {
variable user "xxxxxxx"
variable pass "xxxxxxx"
variable channel "#Tweets"
# Only have one of these uncommented
# Check for tweets every 1 min
#bind time - "* * * * *" twitter::update
# Check for tweets every 10 min
bind time - "?0 * * * *" twitter::update
variable idfile "twitter.last_id"
#variable output_cmd "cd::putnow"
variable output_cmd "putserv"
variable last_id
variable last_update
variable last_msg
variable status_url "http://twitter.com/statuses/update.json"
variable home_url "http://api.twitter.com/1/statuses/home_timeline.json"
variable msg_url "http://twitter.com/direct_messages/new.xml"
variable msgs_url "http://twitter.com/direct_messages.json"
variable trends_curr_url "http://search.twitter.com/trends/current.json"
variable follow_url "http://twitter.com/friendships/create.json"
variable unfollow_url "http://twitter.com/friendships/destroy.json"
variable search_url "http://search.twitter.com/search.json"
variable followers_url "http://twitter.com/statuses/followers.json"
variable following_url "http://twitter.com/statuses/friends.json"
variable retweet_url "http://api.twitter.com/1/statuses/retweet/"
bind pub -|- "!twit" twitter::tweet
bind pub -|- "!twit_msg" twitter::msg
bind pub -|- "!twit_trends" twitter::trends
bind pub -|- "!follow" twitter::follow
bind pub -|- "!unfollow" twitter::unfollow
bind pub -|- "!twit_updates" twitter::updates
bind pub -|- "!twit_msgs" twitter::msgs
bind pub -|- "!twit_search" twitter::search
bind pub -|- "!followers" twitter::followers
bind pub -|- "!following" twitter::following
bind pub -|- "!retweet" twitter::retweet
bind evnt -|- "save" twitter::write_states
setudef flag twitter
}
# Output decoded/split string to given channel
proc twitter::output {chan str} {
set str [twitter::decode_html $str]
foreach line [twitter::split_line 400 $str] {
$twitter::output_cmd "PRIVMSG $chan :$line"
}
}
# Format status updates and output
proc twitter::output_update {chan name id text} {
twitter::output $chan "\[\002$name\002\] $text ($id)"
}
# Retweet given id
proc twitter::retweet {nick uhost hand chan argv} {
if {![channel get $chan twitter]} { return }
if {[string length $argv] < 1 || ![regexp {^\d+$} $argv]} {
$twitter::output_cmd "PRIVMSG $chan :Usage: !retweet <id>"
return
}
# Setup url since id is not given as params for some reason...
set url "${twitter::retweet_url}${argv}.json"
if {[catch {twitter::query $url {} POST} result]} {
$twitter::output_cmd "PRIVMSG $chan :Retweet failure. ($argv) (You can't retweet your own updates!)"
return
}
$twitter::output_cmd "PRIVMSG $chan :Retweet sent."
}
# Follow a user (by screen name)
proc twitter::follow {nick uhost hand chan argv} {
if {![channel get $chan twitter]} { return }
if {[string length $argv] < 1} {
$twitter::output_cmd "PRIVMSG $chan :Usage: !follow <screen name>"
return
}
if {[catch {twitter::query $twitter::follow_url [list screen_name $argv]} result]} {
$twitter::output_cmd "PRIVMSG $chan :Twitter failed or already friends with $argv!"
return
}
if {[dict exists $result error]} {
twitter::output $chan "Follow failed ($argv): [dict get $result error]"
return
}
twitter::output $chan "Now following [dict get $result screen_name]!"
}
# Unfollow a user (by screen name)
proc twitter::unfollow {nick uhost hand chan argv} {
if {![channel get $chan twitter]} { return }
if {[string length $argv] < 1} {
$twitter::output_cmd "PRIVMSG $chan :Usage: !unfollow <screen name>"
return
}
if {[catch {twitter::query $twitter::unfollow_url [list screen_name $argv]} result]} {
$twitter::output_cmd "PRIVMSG $chan :Unfollow failed. ($argv)"
return
}
if {[dict exists $result error]} {
twitter::output $chan "Unfollow failed ($argv): [dict get $result error]"
return
}
twitter::output $chan "Unfollowed [dict get $result screen_name]."
}
# Get last n, n [1, 20] updates
proc twitter::updates {nick uhost hand chan argv} {
if {![channel get $chan twitter]} { return }
if {[string length $argv] < 1 || ![string is integer $argv] || $argv > 20 || $argv < 1} {
$twitter::output_cmd "PRIVMSG $chan :Usage: !twit_updates <#1 to 20>"
return
}
if {[catch {twitter::query $twitter::home_url [list count $argv]} result]} {
$twitter::output_cmd "PRIVMSG $chan :Retrieval error."
return
}
if {[llength $result] == 0} {
$twitter::output_cmd "PRIVMSG $chan :No updates."
return
}
set result [lreverse $result]
foreach status $result {
dict with status {
# twitter::output $chan "\[\002[dict get $user screen_name]\002\] $text"
twitter::output_update $chan [dict get $user screen_name] $id $text
}
}
}
# Return top 5 results for query $argv
proc twitter::search {nick uhost hand chan argv} {
if {![channel get $chan twitter]} { return }
if {[string length $argv] < 1 || [string length $argv] > 140} {
$twitter::output_cmd "PRIVMSG $chan :Usage: !twit_search <string 140 chars or less>"
return
}
if {[catch {twitter::query $twitter::search_url [list q $argv]} data]} {
$twitter::output_cmd "PRIVMSG $chan :Search error ($argv)"
return
}
if {[dict exists $data error]} {
twitter::output $chan "Search failed ($argv): [dict get $result error]"
return
}
set results [dict get $data results]
set count 0
foreach result $results {
twitter::output $chan "#[incr count] \002[dict get $result from_user]\002 [dict get $result text]"
if {$count > 4} {
break
}
}
}
# Return latest followers (up to 100)
proc twitter::followers {nick uhost hand chan argv} {
if {![channel get $chan twitter]} { return }
if {[catch {twitter::query $twitter::followers_url} result]} {
$twitter::output_cmd "PRIVMSG $chan :Error fetching followers."
}
# Make first followers -> last followers
set result [lreverse $result]
set followers []
foreach user $result {
set followers "$followers[dict get $user screen_name] "
}
twitter::output $chan "Followers: $followers"
}
# Returns the latest users following acct is following (up to 100)
proc twitter::following {nick uhost hand chan argv} {
if {![channel get $chan twitter]} { return }
if {[catch {twitter::query $twitter::following_url} result]} {
$twitter::output_cmd "PRIVMSG $chan :Error fetching friends."
return
}
# Make first following -> last following
set result [lreverse $result]
set following []
foreach user $result {
set following "$following[dict get $user screen_name] "
}
twitter::output $chan "Following: $following"
}
# Get trends
proc twitter::trends {nick uhost hand chan argv} {
if {![channel get $chan twitter]} { return }
if {[catch {twitter::query $twitter::trends_curr_url} result]} {
$twitter::output_cmd "PRIVMSG $chan :Trend fetch failed!"
return
}
set trends [dict get $result trends]
set output []
set count 0
foreach day [dict keys $trends] {
foreach trend [dict get $trends $day] {
set output "$output\002#[incr count]\002 [dict get $trend name] "
}
}
twitter::output $chan $output
}
# Direct messages
# Get last n, n [1, 20] messages or new if no argument
proc twitter::msgs {nick uhost hand chan argv} {
if {![channel get $chan twitter]} { return }
if {[string length $argv] == 1 && [string is integer $argv] && $argv < 20} {
set params [list count $argv]
} else {
set params [list since_id $twitter::last_msg]
}
if {[catch {twitter::query $twitter::msgs_url $params GET} result]} {
$twitter::output_cmd "PRIVMSG $chan :Messages retrieval failed."
return
}
if {[llength $result] == 0} {
$twitter::output_cmd "PRIVMSG $chan :No new messages."
return
}
foreach msg $result {
dict with msg {
if {$id > $twitter::last_msg} {
set twitter::last_msg $id
}
twitter::output $chan "\002From\002 $sender_screen_name: $text ($created_at)"
}
}
}
# Send direct message to a user
proc twitter::msg {nick uhost hand chan argv} {
if {![channel get $chan twitter]} { return }
if {[llength [split $argv]] < 2 || [string length [join [lrange [split $argv] 1 end]]] > 140} {
$twitter::output_cmd "PRIVMSG $chan :Usage: !twit_msg <username> <msg 140 chars or less>"
return
}
set l [list screen_name [lindex $argv 0] text [lrange $argv 1 end]]
if {[catch {twitter::query $twitter::msg_url $l} data]} {
$twitter::output_cmd "PRIVMSG $chan :Message to \002$argv\002 failed! (Are they following you?)"
} else {
twitter::output $chan "Message sent."
}
}
# Send status update (tweet)
proc twitter::tweet {nick uhost hand chan argv} {
if {![channel get $chan twitter]} { return }
if {[string length $argv] > 140 || $argv == ""} {
$twitter::output_cmd "PRIVMSG $chan :Usage: !tweet <less than 140 characters>"
}
if {[catch {twitter::query $twitter::status_url [list status $argv]} result]} {
$twitter::output_cmd "PRIVMSG $chan :Tweet failed! HTTP error. ($argv)"
return
}
set update_id [dict get $result id]
if {$update_id == $twitter::last_update} {
$twitter::output_cmd "PRIVMSG $chan :Tweet failed: Duplicate of tweet #$update_id. ($argv)"
return
}
set twitter::last_update $update_id
twitter::output $chan "Tweet sent."
}
# Grab unseen status updates
proc twitter::update {min hour day month year} {
if {[catch {twitter::query $twitter::home_url [list since_id $twitter::last_id]} result]} {
putlog "Twitter is busy."
return
}
set result [lreverse $result]
foreach status $result {
dict with status {
# twitter::output $twitter::channel "\[\002[dict get $user screen_name]\002\] $text"
twitter::output_update $twitter::channel [dict get $user screen_name] $id $text
if {$id > $twitter::last_id} {
set twitter::last_id $id
}
}
}
}
# Twitter http query
proc twitter::query {url {query_list {}} {http_method {}}} {
set auth [base64::encode "${twitter::user}:${twitter::pass}"]
set header [list Authorization [concat "Basic" $auth]]
# Set http mode of query
if {$http_method eq "" && $query_list ne ""} {
set method POST
} elseif {$http_method eq "" && $query_list eq ""} {
set method GET
} else {
set method $http_method
}
set query [http::formatQuery {*}$query_list]
set token [http::geturl $url -headers $header -query $query -method $method]
# if {$query_list ne ""} {
# set query [http::formatQuery {*}$query_list]
# set token [http::geturl $url -headers $header -query $query]
# } else {
# set token [http::geturl $url -headers $header]
# }
set data [http::data $token]
set ncode [http::ncode $token]
http::cleanup $token
if {$ncode != 200} {
putlog "HTTP query failed: $ncode (URL: $url) (QUERY_LIST: $query_list) (QUERY: $query) (METHOD: $http_method) (USED METHOD: $method)"
error "HTTP query failed: $ncode"
}
return [json::json2dict $data]
}
# Get saved ids/state
proc twitter::get_states {} {
if {[catch {open $twitter::idfile r} fid]} {
set twitter::last_id 1
set twitter::last_update 1
set twitter::last_msg 1
return
}
set data [read -nonewline $fid]
set states [split $data \n]
close $fid
set twitter::last_id [lindex $states 0]
set twitter::last_update [lindex $states 1]
set twitter::last_msg [lindex $states 2]
}
# Save states to file
proc twitter::write_states {args} {
set fid [open $twitter::idfile w]
puts $fid $twitter::last_id
puts $fid $twitter::last_update
puts $fid $twitter::last_msg
close $fid
}
# Split long line into list of strings for multi line output to irc
# Splits into strings of ~max
# by fedex
proc twitter::split_line {max str} {
set last [expr {[string length $str] -1}]
set start 0
set end [expr {$max -1}]
set lines []
while {$start <= $last} {
if {$last >= $end} {
set end [string last { } $str $end]
}
lappend lines [string trim [string range $str $start $end]]
set start $end
set end [expr {$start + $max}]
}
return $lines
}
# From perpleXa's urbandictionary script
# Replaces html special chars with their hex equivalent
proc twitter::decode_html {str} {
set escapes {
\x20 " \x22 & \x26 ' \x27 – \x2D
< \x3C > \x3E ˜ \x7E € \x80 ¡ \xA1
¢ \xA2 £ \xA3 ¤ \xA4 ¥ \xA5 ¦ \xA6
§ \xA7 ¨ \xA8 © \xA9 ª \xAA « \xAB
¬ \xAC \xAD ® \xAE &hibar; \xAF ° \xB0
± \xB1 ² \xB2 ³ \xB3 ´ \xB4 µ \xB5
¶ \xB6 · \xB7 ¸ \xB8 ¹ \xB9 º \xBA
» \xBB ¼ \xBC ½ \xBD ¾ \xBE ¿ \xBF
À \xC0 Á \xC1 Â \xC2 Ã \xC3 Ä \xC4
Å \xC5 Æ \xC6 Ç \xC7 È \xC8 É \xC9
Ê \xCA Ë \xCB Ì \xCC Í \xCD Î \xCE
Ï \xCF Ð \xD0 Ñ \xD1 Ò \xD2 Ó \xD3
Ô \xD4 Õ \xD5 Ö \xD6 × \xD7 Ø \xD8
Ù \xD9 Ú \xDA Û \xDB Ü \xDC Ý \xDD
Þ \xDE ß \xDF à \xE0 á \xE1 â \xE2
ã \xE3 ä \xE4 å \xE5 æ \xE6 ç \xE7
è \xE8 é \xE9 ê \xEA ë \xEB ì \xEC
í \xED î \xEE ï \xEF ð \xF0 ñ \xF1
ò \xF2 ó \xF3 ô \xF4 õ \xF5 ö \xF6
÷ \xF7 ø \xF8 ù \xF9 ú \xFA û \xFB
ü \xFC ý \xFD þ \xFE ÿ \xFF
}
return [string map $escapes $str]
}
# Read states on load
twitter::get_states
putlog "twitter 0.1 (c) fedex"