|
|
|
|
|
| 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 "bot@example.com"
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 |
|
|
|
|
| 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.
| 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 |
| :: StanzaPredicate | Stanza predicate.
| | -> StanzaHandler | Stanza handler.
| | -> Bool | Catch 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 String | Character data just contains a string.
|
| 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 |
| :: String | JID of recipient
| | -> String | Type of IQ, either "get" or "set"
| | -> [XMLElem] | Payload elements
| | -> XMPP String | ID of sent stanza
| | Send an IQ request, returning the randomly generated ID.
|
|
|
| sendIqWait |
| :: String | JID of recipient
| | -> String | Type of IQ, either "get" or "set"
| | -> [XMLElem] | Payload elements
| | -> XMPP XMLElem | Response 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 |
| :: String | JID of recipient
| | -> String | Text 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 |
| :: String | Attribute 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 |
| :: String | Client name
| | -> String | Client version
| | -> String | Operating 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 |
| :: String | Username (part before @ in JID)
| | -> String | Server (part after @ in JID)
| | -> String | Resource (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.
| 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.
|
| | Instances | |
|
|
| Produced by Haddock version 0.7 |