Youtube eggdrop script using API v3

Just a very simple eggdrop script that allows users to search on youtube using the youtube and will also return some information for any youtube link spamming into the channel set with +youtube. This uses the youtube v3 API. You can grab your own API key [here].

This script is in use so hopefully I’ll keep it up to date as things more on but any issues or suggestions just let me know. Example of each current function below and the script is there too or [here] in zip format πŸ™‚


# Name          m00nie::youtube
# Description       Uses youtube v3 API to search and return videos
# Version       1.8 - Chanset +youtube now controls search access!
#           1.7 - Modify SSL params (fixes issues on some systems)
#           1.6 - Small correction to "stream" categorisation.....
#           1.5 - Added UTF-8 support thanks to CatboxParadox (Requires eggdrop
#               to be compiled with UTF-8 support)
#           1.4 - Correct time format and live streams gaming etc
#                   1.3 - Updated output to be RFC compliant for some IRCDs
#           1.2 - Added auto info grabber for spammed links
#          1.1 - Fixing regex!
#          1.0 - Initial release
# Website       https://www.m00nie.com
# Notes         Grab your own key @ https://developers.google.com/youtube/v3/
namespace eval m00nie {
   namespace eval youtube {
    package require http
    package require json
    package require tls
        tls::init -tls1 true -ssl2 false -ssl3 false
    http::register https 443 tls::socket
    bind pub - !yt m00nie::youtube::search
    bind pubm - * m00nie::youtube::autoinfo
    variable version "1.8"
    setudef flag youtube
    variable key "GET-YOUR-OWN"
    variable regex {(?:http(?:s|).{3}|)(?:www.|)(?:youtube.com\/watch\?.*v=|youtu.be\/)([\w-]{11})}
    ::http::config -useragent "Mozilla/5.0 (X11; Linux x86_64; rv:29.0) Gecko/20100101 Firefox/29.0"

proc autoinfo {nick uhost hand chan text} {
    if {[channel get $chan youtube] && [regexp -nocase -- $m00nie::youtube::regex $text url id]} {
        putlog "m00nie::youtube::autoinfo is running"
        putlog "m00nie::youtube::autoinfo url is: $url and id is: $id"
        set url "https://www.googleapis.com/youtube/v3/videos?id=$id&key=$m00nie::youtube::key&part=snippet,statistics,contentDetails&fields=items(snippet(title,channelTitle,publishedAt),statistics(viewCount),contentDetails(duration))"
        set ids [getinfo $url]
        set title [encoding convertfrom [lindex $ids 0 1 3]]
        set pubiso [lindex $ids 0 1 1]
        regsub {\.000Z} $pubiso "" pubiso
        set pubtime [clock format [clock scan $pubiso]]
        set user [encoding convertfrom [lindex $ids 0 1 5]]
        # Yes all quite horrible...
        set isotime [lindex $ids 0 3 1]
        regsub -all {PT|S} $isotime "" isotime
                regsub -all {H|M} $isotime ":" isotime
        if { [string index $isotime end-1] == ":" } {
            set sec [string index $isotime end]
                        set trim [string range $isotime 0 end-1]
                        set isotime ${trim}0$sec
        } elseif { [string index $isotime 0] == "0" } {
            set isotime "stream"
        } elseif { [string index $isotime end-2] != ":" } {
            set isotime "${isotime}s"
        set views [lindex $ids 0 5 1]
        puthelp "PRIVMSG $chan :\002\00301,00You\00300,04Tube\003\002 \002$title\002 by $user (duration: $isotime) on $pubtime, $views views"


proc getinfo { url } {
    for { set i 1 } { $i <= 5 } { incr i } {
            set rawpage [::http::data [::http::geturl "$url" -timeout 5000]]
            if {[string length rawpage] > 0} { break }
        putlog "m00nie::youtube::getinfo Rawpage length is: [string length $rawpage]"
        if {[string length $rawpage] == 0} { error "youtube returned ZERO no data :( or we couldnt connect properly" }
        set ids [dict get [json::json2dict $rawpage] items]
    putlog "m00nie::youtube::getinfo IDS are $ids"
    return $ids


proc search {nick uhost hand chan text} {
        if {![channel get $chan youtube] } {
    putlog "m00nie::youtube::search is running"
    regsub -all {\s+} $text "%20" text
    set url "https://www.googleapis.com/youtube/v3/search?part=snippet&fields=items(id(videoId),snippet(title))&key=$m00nie::youtube::key&q=$text"
    set ids [getinfo $url]
    set output "\002\00301,00You\00300,04Tube\003\002 "
    for {set i 0} {$i < 5} {incr i} {
        set id [lindex $ids $i 1 1]
        set desc [encoding convertfrom [lindex $ids $i 3 1]]
        set yout "https://youtu.be/$id"
        append output "\002" $desc "\002 - " $yout " | "
    set output [string range $output 0 end-2]
    puthelp "PRIVMSG $chan :$output"
putlog "m00nie::youtube $m00nie::youtube::version loaded"

As ever any feedback or suggestions are welcome πŸ™‚



  • hey thanks but i have an error:
    [05:20:22] m00nie::youtube failed: wrong # args: should be “set varName ?newValue?”

    do you know what to do please ?

  • Hi Destiny

    Sorry hard to say from that error what the prob could be apart from an arg being undefined properly.
    I’ve tested the script as it is above and it loads error free for me.
    Did you define your own API key using quotes?


  • hey thanks for answering, i tried to define my own key but i’m not sure about it, can i give it to you if you have time to test it ?

  • Hi Destiny

    Sure my email is on the about page πŸ™‚
    The line should read something like
    set ::key "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"


  • [18:39:30] Tcl error in file ‘eggdrop.conf’:
    [18:39:30] can’t find package json
    while executing
    “package require json”
    (in namespace eval “::m00nie::youtube” script line 3)
    invoked from within
    “namespace eval youtube {
    package require http
    package require json
    package require tls
    http::register https 443 tls::s…”
    (in namespace eval “::m00nie” script line 2)
    invoked from within
    “namespace eval m00nie {
    namespace eval youtube {
    package require http
    package require json

    Connection closed by foreign host.

  • Hi m00nie thanks for the packages it works! but when i do !yt something in partyline there is
    [08:12:07] m00nie::youtube failed: wrong # args: should be “set varName ?newValue?”

    i define my API Key in set ::key

  • Hi Tom

    I think there was a typo on the line “getids ($nick $chan $url $repeat)” Ive now corrected this, did that resolve the issue?

    m00nie πŸ™‚

  • Hey m00nie, would you like to add a proc that reads the title of the youtube link sent in channel?

  • Hi Arkadio

    Ive updated the script again and now it will spam some into about and youtube links pasted into the channel πŸ™‚


  • hi,

    I have it setup BUT when i trigger the search event with !yt or paste a link the only text the bot says in the channel is YouTube… the rest of the output is only in the party line window and the logs. the output in the party line looks something like this.

    [15:15:24] m00nie::youtube::autoinfo is running
    [15:15:24] m00nie::youtube::autoinfo url is: https://www.youtube.com/watch?v=jOkZCydRHBw and id is: jOkZCydRHBw
    [15:15:24] m00nie::youtube::getinfo Rawpage length is: 280
    [15:15:24] m00nie::youtube::getinfo IDS are {snippet {publishedAt 2015-06-21T22:53:58.000Z title {Nd YAG Laser Strip Down}
    channelTitle Photonicinduction} contentDetails {duration PT14M3S} statistics {viewCount 42745}}

    I do have chanset to +youtube

  • This is the log from the eggdrop:

    [07:38:29] m00nie::youtube::autoinfo is running
    [07:38:29] m00nie::youtube::autoinfo url is: https://www.youtube.com/watch?v=OCZIGxpB2qQ and id is: OCZIGxpB2qQ
    [07:38:29] m00nie::youtube::getinfo Rawpage length is: 313
    [07:38:29] m00nie::youtube::getinfo IDS are {snippet {publishedAt 2013-12-09T16:47:01.000Z title {Pop The Hatch ft Kidd Sham – All Seeing Eye (Hydraulix Remix)} channelTitle JustTrapMusic} contentDetails {duration PT3M16S} statistics {viewCount 9987}}

    Everything looks ok but… it’s not working properly. This si the output on the channel :

    JustTrapMusic (duration: 3:16) on Mon Dec 09 18:47:01 EST 2013, 9987 views

    I tried to eliminate the channel title, date and views but i only get the last word from the title “Remix)”
    Can you do something about it ?

  • Hi Spinti89

    Does this affect just the auto info spamming part of the script? Do you get the titles spammed ok with !yt?
    You could try adding this line:
    putlog "m00nie::youtube::autoinfo Title = $title"
    Just after this line “set views [lindex $ids 0 5 1]” (line 39) and that should at least confirm the script has grabbed the info from the API?


  • Hi m00nie,

    The only output in the #channel is the stylized YouTube with white and red ascii text. the rest of the output is in the eggdrop party line. my issue is similar to Sprinti89’s…. so i added that extra putlog and I do get the title in the log just still no output in the #channel

    [10:31:49] m00nie::youtube::autoinfo is running
    [10:31:49] m00nie::youtube::autoinfo url is: https://www.youtube.com/watch?v=L0jQz6jqQS0 and id is: L0jQz6jqQS0
    [10:31:49] m00nie::youtube::getinfo Rawpage length is: 312
    [10:31:49] m00nie::youtube::getinfo IDS are {snippet {publishedAt 2015-08-10T06:30:00.000Z title {Last Week Tonight with John Oliver: Sex Education (HBO)} channelTitle LastWeekTonight} contentDetails {duration PT21M5S} statistics {viewCount 2251395}}
    [10:31:49] m00nie::youtube::autoinfo Title = Last Week Tonight with John Oliver: Sex Education (HBO)

    Thanks for the help

  • Hi MikeD

    Thanks for testing. Did you download the script via the link [here] or copy from this page?
    Could you try changing the output line to something simpler like:
    puthelp "PRIVMSG $chan $title by $user (duration: $isotime) on $pubtime, $views views"
    Testing from a fresh bot I cant recreate this problem sadly πŸ™


  • hey m00nie,

    A little more progress now… with the new output line we get the first word of the title into the #channel example:

    14:53:42 https://www.youtube.com/watch?v=YyDcKINFugE
    14:53:43 IFC’s

    log file is as follows:
    [14:53:42] m00nie::youtube::autoinfo is running
    [14:53:42] m00nie::youtube::autoinfo url is: https://www.youtube.com/watch?v=YyDcKINFugE and id is: YyDcKINFugE
    [14:53:42] m00nie::youtube::getinfo Rawpage length is: 287
    [14:53:42] m00nie::youtube::getinfo IDS are {snippet {publishedAt 2015-08-10T22:24:25.000Z title {IFC’s VICE Parody: ‘DRONEZ’ (Full Episode)} channelTitle VICE} contentDetails {duration PT22M52S} statistics {viewCount 36205}}
    [14:53:42] m00nie::youtube::autoinfo Title = IFC’s VICE Parody: ‘DRONEZ’ (Full Episode)


  • Hey m00nie,

    I found a solution… All i really wanted was the title so this is my puthelp line

    puthelp “PRIVMSG $chan :02$title02”


  • Hi MikeD

    Thanks for the feedback:) Maybe something to do with the spam allowed in the channel perhaps? I’ll update the script and add a small note to cover this.


  • Just a quick question, are there any plans to support UTF-8 for the retrieved titles? Languages like Japanese, and Cyrillic don’t seem too happy when returned. Thanks!

  • @random4t4x14: try using

    set title [encoding convertfrom [lindex $ids 0 1 3]]

    if your eggdrop bot is compiled with UTF-8 support.

  • here sc youtube-dl can u help sir?
    set piccheck(version) “0.1”
    set filePath “/var/www/html/*.mp3”
    set your_site “http://localhost”
    set mp3 “.mp3”

    bind pub -|- !download yotube
    proc yotube filePath your_site mp3 {nick uhost hand chan text} {
    set ******* [exec *******-dl –extract-audio –audio-format mp3 –output “/var/www/html/%(title)s.(ext)s” [split $text]]
    foreach line [split $******* \n] {
    set file [open $filePath r]
    set data [read $file]
    close $file
    if {[string match “*Destination*” $line] || [string match “*100.0%*” $line]} {
    puthelp “PRIVMSG $chan :$line $your_site$mp3”

    how to run localhost sir?? any ide sir?

  • Hi m00nie,

    Somtime between 17:00 and 02:00 last night the script has stopped functioning normal.

    I am getting these kinds error in the log:
    [00:49:39] Tcl error [m00nie::youtube::autoinfo]: error reading “sock8a692b0”: software caused connection abort
    [02:04:52] Tcl error [m00nie::youtube::autoinfo]: error reading “sock8a691b0”: software caused connection abort
    [02:06:23] Tcl error [m00nie::youtube::autoinfo]: error reading “sock8a68db0”: software caused connection abort
    [03:49:10] Tcl error [m00nie::youtube::autoinfo]: error reading “sock8a6b4f0”: software caused connection abort
    [03:44:47] Tcl error [m00nie::youtube::autoinfo]: error reading “sock9ed5548”: software caused connection abort

    Any thoughts?

  • Hi m00nie,

    The problem has not resolved itself…. it still throws that error I have yet to nail down the exact time slot when it starts and stops. I changed my API key and let it run for the last 24 hours and it still fails over the midnight hours.

    this affects both the autoinfo and the lookup.

    so strange…

  • OK it just cut out now at 02:00 UTC and it resumes sometime around 12:30 UTC
    It has been doing this every night this week since Tuesday.

  • Hi MikeD

    Its been working ok here and no other reports so a little tough to debug. As a random stab in the dark I have had similar errors logged when there were SSL issues to other sites. So this might be work a try. Add: tls::init -tls1 true -ssl2 false -ssl3 false on a new line right after “package require tls” ~line 20 and reload.


  • Hi m00nie,

    The bot was working fine up till a week ago… I have put the tls commands from your post on May 21 into my config and this has solved the issue. Thanks!

  • Hey Mr M00nie, I saw this script in action, thought I would give it a go. I negotatied packages, script loads, but I get a curious error, any hints?
    [18:04:14] m00nie::youtube 1.7 loaded

    [18:04:30] m00nie::youtube::search is running
    [18:04:30] m00nie::youtube::getinfo Rawpage length is: 176
    [18:04:30] Tcl error [m00nie::youtube::search]: key “items” not known in dictionary

  • Hi Charlie

    It looks as though you may not have a valid API key or its misconfigured maybe? I’d double check its exactly as youtube sent you and enclose with quote πŸ™‚


  • I love the script, is it possible to add a funtcion for egg owners n|n or so, to enable the script in channels?
    like a channel command !youtube on, for now the partyline .chanset #channel +youtube isnt working..

  • Hi Stanley

    Thanks for the feedback that wasn’t my intended behavior so something Id missed tested myself πŸ˜› I’ve updated the script to 1.8 and +youtube now controls access to the search functions as well as the auto info parts of the scripts.


  • Hello Again Sir m00nie.
    I have re-copied my key. This is the Youtube API v3 Browser key right? (just to check i got the right type of key…)
    I can see the requests and a 100% error rate on the google dev browser so it looks like things are happening on that side?
    YouTube Data API v3 (req) 4 (Error) 4 100%
    I have updated to 1.8, made a fresh file, triple-checked the key. Eggdrop v1.8.0, Running on Debian Wheezy,TCL 8.5 (http & json packages!?!) TLSv1.2 The only grey area perhaps is json, struggling to find a way of verifying the version.

    Yet I still get:
    m00nie::youtube 1.8 loaded
    Tcl error [m00nie::youtube::search]: key “items” not known in dictionary

    Sorry to be a pain, everyone else seems to be doing this successfully, it seems straight forward, so I assume it is my system config somewhere along the way.

    I will keep digging, will update if I have success.
    Thanks again.


  • Hi Charlie

    The best way to confirm your API key could be to pop this in your browser and replace MYAPIKEY with the key you have πŸ™‚ https://www.googleapis.com/youtube/v3/search?part=snippet&fields=items(id(videoId),snippet(title))&key=MYAPIKEY&q=charlie. TLS and the underlying connection seems to be working ok though I’d guess or you’d get a different error from the script.


Leave a Reply