PoshCode Logo PowerShell Code Repository

PowerBot 2.0 by Joel Bennett 3 years ago
embed code: <script type="text/javascript" src="http://PoshCode.org/embed/727"></script>download | new post

PowerBot is my IRC bot written in PowerShell script using SmartIrc4Net There’s a bit more to it than this, but this is the basic script, and all you have to do is add your own commands! Of course, you could also add your own additional message handlers and make a chatter-bot or whatever you like. Please share your mods back here!

  1. ## PowerBot 2.0
  2. ## A simple framework to get you started writing your own IRC bots in PowerShell
  3. ####################################################################################################
  4. ## Requires Meebey.SmartIrc4net.dll to be in your ...\WindowsPowerShell\Libraries\
  5. ## You can get Meebey.SmartIrc4net.dll from
  6. ## http://voxel.dl.sourceforge.net/sourceforge/smartirc4net/SmartIrc4net-0.4.0.bin.tar.bz2
  7. ####################################################################################################
  8. ## Add-Type -path $ProfileDir\Libraries\Meebey.SmartIrc4net.dll
  9. $null = [Reflection.Assembly]::LoadFrom("$ProfileDir\Libraries\Meebey.SmartIrc4net.dll")
  10.  
  11. function Start-PowerBot {
  12. PARAM(
  13.   $server = "irc.freenode.net"
  14. , [string[]]$channels = @("#PowerShell")
  15. , [string[]]$nick     = @(Read-Host 'You must provide a nickname')
  16. , [string]$password
  17. , $realname = "PowerShell Bot"
  18. , $port               = 6667
  19. )
  20.    
  21.    if(!$global:irc) {
  22.       $global:irc = New-Object Meebey.SmartIrc4net.IrcClient
  23.       $irc.ActiveChannelSyncing = $true # $irc will track channels for us
  24.       # $irc.Encoding = [Text.Encoding]::UTF8
  25.       $irc.Add_OnError( {Write-Error $_.ErrorMessage} )
  26.       $irc.Add_OnQueryMessage( {PrivateMessage} )
  27.       $irc.Add_OnChannelMessage( {ChannelMessage} )
  28.    }
  29.    
  30.    $irc.Connect($server, $port)
  31.    $irc.Login($nick, $realname, 0, $nick, $password)
  32.    ## $channels | % { $irc.RfcJoin( $_ ) }
  33.    foreach($channel in $channels) { $irc.RfcJoin( $channel ) }
  34.    Resume-PowerBot # Shortcut so starting this thing up only takes one command
  35. }
  36.  
  37. ## Note that PowerBot stops listening if you press a key ...
  38. ## You'll have to re-run Resume-Powerbot to get him to listen again
  39. function Resume-PowerBot {
  40.    while(!$Host.UI.RawUI.KeyAvailable) { $irc.ListenOnce($false) }
  41. }
  42.  
  43. function Stop-PowerBot {
  44.    $irc.RfcQuit("If people listened to themselves more often, they would talk less.")
  45.    $irc.Disconnect()
  46. }
  47.  
  48. ####################################################################################################
  49. ## Event Handlers
  50. ####################################################################################################
  51. ## Event handlers in powershell have TWO automatic variables: $This and $_
  52. ##   In the case of SmartIrc4Net:
  53. ##   $This  - usually the connection, and such ...
  54. ##   $_     - the IrcEventArgs, which just has the Data member:
  55. ##
  56.  
  57. function PrivateMessage {
  58.    $Data = $_.Data
  59.    # Write-Verbose $Data.From  
  60.    # Write-Verbose $Data.Message
  61.    Write-Verbose $($Data | Out-String)
  62.    
  63.    $command, $params = $Data.MessageArray
  64.    if($PowerBotCommands.ContainsKey($command)) {
  65.       &$PowerBotCommands[$command] $params $Data |
  66.          Out-String -width (510 - $Data.From.Length - $nick.Length - 3) |
  67.             % { $_.Trim().Split("`n") | %{ $irc.SendMessage("Message", $Data.Channel, $_.Trim() ) }}
  68.    }
  69. }
  70.  
  71. function ChannelMessage {
  72.    $Data = $_.Data
  73.    # Write-Verbose $Data.From
  74.    # Write-Verbose $Data.Channel
  75.    # Write-Verbose $Data.Message
  76.    Write-Verbose $($Data | Out-String)
  77.    
  78.    $command, $params = $Data.MessageArray
  79.    if($PowerBotCommands.ContainsKey($command)) {
  80.       &$PowerBotCommands[$command] $params $Data |
  81.          Out-String -width (510 - $Data.Channel.Length - $nick.Length - 3) |
  82.             % { $_.Trim().Split("`n") | %{ $irc.SendMessage("Message", $Data.Channel, $_.Trim() ) }}
  83.    }
  84. }
  85.  
  86. ####################################################################################################
  87. ## The PowerBotCommands hashtable is extremely simple ...
  88. ##
  89. ## You register a "command" which must be the FIRST WORD of a message (either private, or channel)
  90. ##   and you provide a scriptblock to process said message.  
  91. ## The handler scriptblock gets two parameters, for convenience:
  92. ##   $Params is the rest of the message text after the command word (which is probably all you need)
  93. ##   $Data is the Data propert of the IrcEventArgs, which has everything in it that you could want
  94. ##
  95. ## You may do whatever you want in the scriptblock (this runs on your PC, after all), but the
  96. ##   simplest thing is to respond by returning "something" which will be sent to wherever the message
  97. ##   came from.  
  98. ##
  99. ## NOTE 1: Evrything you return is output to Out-String and then the channel or user.  Be careful!
  100. ## NOTE 2: 510 is the Max IRC Message Length, including the channel name etc.
  101. ##         http`://www.faqs.org/rfcs/rfc1459.html
  102. ##
  103. $PowerBotCommands=@{}
  104.  
  105. ## A sample command to get you started
  106. $PowerBotCommands."Hello" = {Param($Query,$Data)
  107.    "Hello, $($Data.Nick)!"
  108. }
  109.  
  110. $PowerBotCommands."!Echo" = {Param($Query,$Data)
  111.    "$Query"
  112. }
  113.  
  114. ## "!gh|!get-help|!man"
  115. $PowerBotCommands."!Get-Help" = {Param($Query)
  116.    $help = get-help $Query | Select Name,Synopsis,Syntax
  117.    if($?) {
  118.       if($help -is [array]) {
  119.          "You're going to need to be more specific, I know all about $((($help | % { $_.Name })[0..($help.Length-2)] -join ', ') + ' and even ' + $help[-1].Name)"
  120.       } else {
  121.          @($help.Synopsis,($help.Syntax | Out-String -width 1000).Trim().Split("`n",4,"RemoveEmptyEntries")[0..3])
  122.       }
  123.    } else {
  124.       "I couldn't find the help file for '$Query', sorry.  I probably don't have that snapin loaded."
  125.    }
  126. }

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me