# encoding: ascii
# api: powershell
# title: Start-IRCJabberBridge
# description: Creates a bridge between (any) MUC chatroom and a Jabber user — by default it joins the #PowerShell channel at IRC.FreeNode.net and echos everything said there to you, and everything you say to it … to the chat room. Really quite useless, except as a demonstration.
# version: 0.1
# type: function
# author: Joel Bennnett
# license: CC0
# function: Start-PowerBot
# x-poshcode-id: 178
# x-archived: 2009-11-28T08:35:49
#
#
## Depends on the PoshXmpp.dll from http://CodePlex.com/PoshXmpp
#requires -pssnapin PoshXmpp
##########################################################################################
# @Author: Joel Bennnett
# @Usage:
# Start-JabberMirror.ps1 User@JabberServer.com Password "groupchat@oneserver.com" "groupchat@anotherserver.com" "BridgeBot" "http://rssfeed"
##########################################################################################
param (
$JabberId = $(Read-Host "Jabber Login (eg: 'mybot@im.flosoft.biz') ")
,$Password = $(Read-Host "Jabber Password")
,$IRC = $(Read-Host "First Jabber conference address (IRC) (eg: powershell%irc.freenode.net@irc.im.flosoft.biz )")
,$JabberConf = $(Read-Host "Second Jabber conference address (eg: powershell@conference.im.flosoft.biz) ")
,$ChatNick = $(Read-Host "The nickname you want to use")
,$IRCPassword= $(Read-Host "IRC Password")
,[string[]]$AtomFeeds = @("http://groups.google.com/group/microsoft.public.windows.powershell/feed/atom_v1_0_topics.xml")
)
## Requires System.Web for the RSS-feed option
[Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null
function Start-PowerBot([switch]$announce) {
$global:LastNewsCheck = [DateTime]::Now
$global:feedReader = new-object Xml.XmlDocument
$global:PoshXmppClient = PoshXmpp\New-Client $JabberId $Password http://im.flosoft.biz:5280/http-poll/
PoshXmpp\Connect-Chat $IRC $ChatNick
PoshXmpp\Connect-Chat $JabberConf $ChatNick
$global:PoshXmppClient.SendMyPresence()
if($announce) {
PoshXmpp\Send-Message $IRC "Starting Mirror to $('{0}@{1}' -f $JabberConf.Split(@('%','@'),3))"
PoshXmpp\Send-Message $JabberConf "Starting Mirror to $('{0}@{1}' -f $IRC.Split(@('%','@'),3))"
}
if($IRCPassword) {
Send-PrivMsg "nickserv" "id $IRCPassword"
}
}
function Send-PrivMsg($to,$msg) {
PoshXmpp\Send-Message $IRC "/msg $to :$msg"
}
function Process-Command($Chat, $Message) {
$split = $message.Body.Split(" |;")
$from = $Message.From.Bare.ToLower()
switch -regex ( $split[0] ) {
"!list" {
Write-Host "!LIST COMMAND. Send users of [$Chat] to [$($Message.From.Bare)]" -fore Magenta
$users = @($PoshXmppClient.ChatManager.GetUsers( $Chat ).Values)
PoshXmpp\Send-Message $from ("There are $($users.Count) on $($Chat):")
PoshXmpp\Send-Message $from [string].join(', ',$users)
}
"!gh|!get-help|!man" {
$help = get-help $split[1] | Select Name,Synopsis,Syntax
if($?) {
if($help -is [array]) {
PoshXmpp\Send-Message $from ("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)")
} else {
PoshXmpp\Send-Message $from $help.Synopsis;
PoshXmpp\Send-Message $from ($help.Syntax | Out-String -w 1000).Split("`n",4,[StringSplitOptions]::RemoveEmptyEntries)[1]
}
} else {
PoshXmpp\Send-Message $from "I couldn't find the help file for that, sorry. Jaykul probably didn't get the cmdlet installed right."
}
}
}
}
# Max IRC Message Length http://www.faqs.org/rfcs/rfc1459.html
# PRIVMSG CHANNEL MSG
$IrcMaxLen = 510 - ("PRIVMSG :".Length + $IRC.Length + $JabberId.split('@')[0].Length)
function Get-Feeds([string[]]$JIDs,[string[]]$AtomFeeds) {
Write-Verbose "Checking feeds..."
foreach($feed in $AtomFeeds) {
$feedReader.Load($feed)
for($i = $feedReader.feed.entry.count - 1; $i -ge 0; $i--) {
$e = $feedReader.feed.entry[$i]
if([datetime]$e.updated -gt $global:LastNewsCheck) {
foreach($jid in $JIDs) {
$msg = ([System.Web.HttpUtility]::HtmlDecode($e.summary."#text") -replace "<br>", "").Trim()
$template = "{0} (Posted at {1:hh:mm} by {2}) {{0}} :: {3}" -f
$e.title."#text", [datetime]$e.updated, $e.author.name, $e.link.href
$len = [math]::Min($IrcMaxLen,($template.Length + $msg.Length)) - ($template.Length +3)
PoshXmpp\Send-Message $jid $($template -f $msg.SubString(0,$len))
}
[Threading.Thread]::Sleep( 500 )
}
}
}
$global:LastNewsCheck = [DateTime]::Now
}
[regex]$anagram = "^Unscramble ... (.*)$"
function Bridge {
foreach( $msg in (PoshXmpp\Receive-Message -All) )
{
$Chat = $Null;
if( $msg.Type -eq "Error" )
{
Write-Error $msg.Error
}
elseif( $msg.From.Resource -ne $ChatNick )
{
switch($msg.From.Bare) {
$IRC { $Chat = $JabberConf }
$JabberConf { $Chat = $IRC; }
default { Write-Debug $msg }
}
}
if($Chat) {
switch($msg) {
{ ![String]::IsNullOrEmpty($_.Body) -and ($_.Body[0] -eq '!') }{
PoshXmpp\Send-Message $Chat ("<{0}> {1}" -f $_.From.Resource, $_.Body)
Process-Command $Chat $_
}
{ ($_.From.Resource -eq "GeoBot") -and $_.Body.StartsWith("Unscramble ... ") }{
Write-Verbose "KILL ANAGRAM! $($anagram.Match($_.Body).Groups[1].value)"
$answers = Solve-Anagram $($anagram.Match($_.Body).Groups[1].value)
foreach($ans in $answers) {
Write-Verbose "ANAGRAM: $($_.From.Bare) $ans"
PoshXmpp\Send-Message "$($_.From.Bare.ToLower())" "$ans (PowerShell Scripting FTW!)"
}
}
{ ![String]::IsNullOrEmpty($_.Subject) }{
$_.To = $Chat
# Send it directly using a method on the PoshXmppClient
$PoshXmppClient.Send($_)
}
{ $_.From.Resource }{
PoshXmpp\Send-Message $Chat ("<{0}> {1}" -f $_.From.Resource, $_.Body)
}
}
}
}
}
function Start-Bridge {
"PRESS ANY KEY TO STOP"
while(!$Host.UI.RawUI.KeyAvailable) {
$Host.UI.RawUI.WindowTitle = "PowerBot"
$global:PoshXmppClient.SendMyPresence()
Bridge
Get-Feeds @($IRC,$JabberConf) $AtomFeeds
$counter = 0
Write-Verbose "PRESS ANY KEY TO STOP" # we're going to wait 3 * 60 seconds
while(!$Host.UI.RawUI.KeyAvailable -and ($counter++ -lt 1800)) {
Bridge
[Threading.Thread]::Sleep( 100 )
}
}
}
function Stop-PowerBot {
PoshXmpp\Disconnect-Chat $IRC $ChatNick
PoshXmpp\Disconnect-Chat $JabberConf $ChatNick
$global:PoshXmppClient.Close();
}
##
## Silly anagram spoiler
##
function Solve-Anagram($anagram) {
((Post-HTTP "http://www.easypeasy.com/anagrams/results.php" "name=$anagram").Split("`n") |
select-string "res 1" ) -replace ".*res 1.*value=""\s*([^""]*)\s*"".*",'$1'
}
function Post-HTTP($url,$bytes) {
$request = [System.Net.WebRequest]::Create($url)
# $bytes = [Text.Encoding]::UTF8.GetBytes( $bytes )
$request.ContentType = "application/x-www-form-urlencoded"
$request.ContentLength = $bytes.Length
$request.Method = "POST"
$rq = new-object IO.StreamWriter $request.GetRequestStream()
$rq.Write($bytes)#,0,$bytes.Length)
$rq.Flush()
$rq.Close()
$response = $request.GetResponse()
$reader = new-object IO.StreamReader $response.GetResponseStream(),[Text.Encoding]::UTF8
return $reader.ReadToEnd()
}