XMPP-0.0.1: XMPP libraryContentsIndex
XMPP
Contents
The XMPP monad
XML functions
Stanza manipulation
JID functions
Authentication
TCP connections
Abstract connections
Description

This library aims to make writing XMPP clients (in particular bots) easy and fun. Here is a small example:

 import XMPP
 import Network
 
 -- The bot's JID is "[email protected]"
 botUsername = "bot"
 botServer = "example.com"
 botPassword = "secret"
 
 main :: IO ()
 main = withSocketsDo $
   do
     -- Connect to server...
     c <- openStream botServer
     getStreamStart c
 
     runXMPP c $ do
       -- ...authenticate...
       startAuth botUsername botServer botPassword
       sendPresence
       -- ...and do something.
       run
 
 run :: XMPP ()
 run = do
   -- Wait for an incoming message...
   msg <- waitForStanza (isChat `conj` hasBody)
   let sender = maybe "" id (getAttr "from" msg)
       len = length $ maybe "" id (getMessageBody msg)
   -- ...answer...
   sendMessage sender ("Your message was "++(show len)++" characters long.")
   -- ...and repeat.
   run

XMPP is a protocol for streaming XML also known as Jabber. It is described in RFCs 3920 and 3921, and in a series of XMPP Extension Protocols (XEPs). All of this can be found at http://www.xmpp.org.

For a larger example, see werewolf.

Synopsis
data XMPP a
runXMPP :: XMPPConnection c => c -> XMPP () -> IO ()
sendStanza :: XMLElem -> XMPP ()
addHandler :: StanzaPredicate -> StanzaHandler -> Bool -> XMPP ()
waitForStanza :: StanzaPredicate -> XMPP XMLElem
quit :: XMPP ()
type StanzaPredicate = XMLElem -> Bool
type StanzaHandler = XMLElem -> XMPP ()
liftIO
data XMLElem
= XML String [(String, String)] [XMLElem]
| CData String
xmlPath :: [String] -> XMLElem -> Maybe XMLElem
getAttr :: String -> XMLElem -> Maybe String
getCdata :: XMLElem -> Maybe String
xmlToString :: Bool -> XMLElem -> String
sendIq :: String -> String -> [XMLElem] -> XMPP String
sendIqWait :: String -> String -> [XMLElem] -> XMPP XMLElem
hasBody :: StanzaPredicate
getMessageBody :: XMLElem -> Maybe String
sendMessage :: String -> String -> XMPP ()
sendPresence :: XMPP ()
conj :: (a -> Bool) -> (a -> Bool) -> a -> Bool
attributeMatches :: String -> (String -> Bool) -> StanzaPredicate
isMessage :: StanzaPredicate
isPresence :: StanzaPredicate
isIq :: StanzaPredicate
isChat :: StanzaPredicate
isFrom :: String -> StanzaPredicate
iqXmlns :: String -> StanzaPredicate
iqGet :: String -> StanzaPredicate
iqSet :: String -> StanzaPredicate
handleVersion :: String -> String -> String -> XMPP ()
getUsername :: String -> String
getResource :: String -> String
getBareJid :: String -> String
startAuth :: String -> String -> String -> XMPP ()
data TCPConnection
openStream :: String -> IO TCPConnection
getStreamStart :: TCPConnection -> IO XMLElem
class XMPPConnection c where
getStanzas :: c -> IO [XMLElem]
sendStanza :: c -> XMLElem -> IO ()
closeConnection :: c -> IO ()
The XMPP monad
data XMPP a
A function in the XMPP monad behaves a bit like a thread in a cooperative threading system: when it decides to wait for more input, it "sleeps", letting other "threads" run, until input matching a certain predicate arrives.
show/hide Instances
runXMPP :: XMPPConnection c => c -> XMPP () -> IO ()
Run a function in the XMPP monad using the given XMPP connection. After that, keep looping as long as there are handlers waiting for incoming stanzas.
sendStanza :: XMLElem -> XMPP ()
Send an XMPP stanza.
addHandler
:: StanzaPredicateStanza predicate.
-> StanzaHandlerStanza handler.
-> BoolCatch more than one stanza?
-> XMPP ()

When a stanza matching the predicate arrives, call the given handler. This is analogous to spawning a new thread, except that the "thread" is only run if and when a matching stanza arrives.

Stanza handlers can be one-shot or permanent, as indicated by the third argument.

waitForStanza :: StanzaPredicate -> XMPP XMLElem
Suspend execution of current function while waiting for a stanza matching the predicate.
quit :: XMPP ()
Terminate the loop as soon as the current function exits. This works by removing all stanza handlers, which makes runXMPP exit.
type StanzaPredicate = XMLElem -> Bool
A stanza predicate.
type StanzaHandler = XMLElem -> XMPP ()
A handler function for a stanza.
liftIO
XML functions
data XMLElem
A data structure representing an XML element.
Constructors
XML String [(String, String)] [XMLElem]Tags have a name, a list of attributes, and a list of child elements.
CData StringCharacter data just contains a string.
show/hide Instances
xmlPath :: [String] -> XMLElem -> Maybe XMLElem
Follow a "path" of named subtags in an XML tree. For every element in the given list, find the subtag with that name and proceed recursively.
getAttr :: String -> XMLElem -> Maybe String
Get the value of an attribute in the given tag.
getCdata :: XMLElem -> Maybe String
Get the character data subelement of the given tag.
xmlToString :: Bool -> XMLElem -> String
Convert the tag back to XML. If the first parameter is true, close the tag.
Stanza manipulation
sendIq
:: StringJID of recipient
-> StringType of IQ, either "get" or "set"
-> [XMLElem]Payload elements
-> XMPP StringID of sent stanza
Send an IQ request, returning the randomly generated ID.
sendIqWait
:: StringJID of recipient
-> StringType of IQ, either "get" or "set"
-> [XMLElem]Payload elements
-> XMPP XMLElemResponse stanza
Send an IQ request and wait for the response, without blocking other activity.
hasBody :: StanzaPredicate
Return true if the message stanza has body text.
getMessageBody :: XMLElem -> Maybe String
Get the body text of the message stanza, if any.
sendMessage
:: StringJID of recipient
-> StringText of message
-> XMPP ()
Send an ordinary "chat" type message.
sendPresence :: XMPP ()
Send ordinary online presence.
conj :: (a -> Bool) -> (a -> Bool) -> a -> Bool
Conjunction ("and") of two predicates.
attributeMatches
:: StringAttribute name
-> (String -> Bool)Attribute value predicate
-> StanzaPredicate
Apply the predicate to the named attribute. Return false if the tag has no such attribute.
isMessage :: StanzaPredicate
Return true if the tag is a message stanza.
isPresence :: StanzaPredicate
Return true if the tag is a presence stanza.
isIq :: StanzaPredicate
Return true if the tag is an IQ stanza.
isChat :: StanzaPredicate
Return true if the tag is a chat message.
isFrom :: String -> StanzaPredicate
Return true if the stanza is from the given JID.
iqXmlns :: String -> StanzaPredicate
Return true if the stanza is an IQ stanza in the given namespace.
iqGet :: String -> StanzaPredicate
Return true if the stanza is a "get" request in the given namespace.
iqSet :: String -> StanzaPredicate
Return true if the stanza is a "set" request in the given namespace.
handleVersion
:: StringClient name
-> StringClient version
-> StringOperating system
-> XMPP ()
Establish a handler for answering to version requests with the given information. See XEP-0092: Software Version.
JID functions
getUsername :: String -> String
Get username part of JID, i.e. the part before the @ sign. Return "" if the JID contains no @ sign.
getResource :: String -> String
Get resource part of JID, i.e. the part after /. Return "" if the JID has no resource.
getBareJid :: String -> String
Get the bare JID, i.e. everything except the resource.
Authentication
startAuth
:: StringUsername (part before @ in JID)
-> StringServer (part after @ in JID)
-> StringResource (unique identifier for this connection)
-> XMPP ()
Perform authentication, following XEP-0078. Note that the password will be sent in cleartext; this is not by design. Calls error if authentication fails.
TCP connections
data TCPConnection
An XMPP connection over TCP.
show/hide Instances
openStream :: String -> IO TCPConnection
Open a TCP connection to the named server, port 5222, and send a stream header. This should really check SRV records.
getStreamStart :: TCPConnection -> IO XMLElem
Get the stream header that the server sent. This needs to be called before doing anything else with the stream.
Abstract connections
class XMPPConnection c where
A class for various kinds of XMPP connections.
Methods
getStanzas :: c -> IO [XMLElem]
Get incoming stanzas from the connection.
sendStanza :: c -> XMLElem -> IO ()
Send a stanza on the connection.
closeConnection :: c -> IO ()
Close the connection.
show/hide Instances
Produced by Haddock version 0.7