-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | XMPP library -- -- XMPP library @package XMPP @version 0.1.2 -- | This library aims to make writing XMPP clients (in particular bots) -- easy and fun. Here is a small example: -- --
--   import Network
--   import Network.XMPP
--   
--   -- The bot's JID is "bot@example.com"
--   botUsername = "bot"
--   botServer = "example.com"
--   botPassword = "secret"
--   botResource = "bot"
--   
--   main :: IO ()
--   main = withSocketsDo $
--     do
--       -- Connect to server...
--       c <- openStream botServer
--       getStreamStart c
--   
--       runXMPP c $ do
--         -- ...authenticate...
--         startAuth botUsername botServer botPassword botResource
--         sendpresence Nothing Nothing
--         -- ...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. module Network.XMPP -- | 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. data XMPP a -- | 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. runXMPP :: XMPPConnection c => c -> XMPP () -> IO () -- | Send an XMPP stanza. sendStanza :: XMLElem -> 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. addHandler :: StanzaPredicate -> StanzaHandler -> Bool -> XMPP () -- | Suspend execution of current function while waiting for a stanza -- matching the predicate. waitForStanza :: StanzaPredicate -> XMPP XMLElem -- | Terminate the loop as soon as the current function exits. This works -- by removing all stanza handlers, which makes runXMPP exit. quit :: XMPP () -- | A stanza predicate. type StanzaPredicate = XMLElem -> Bool -- | A handler function for a stanza. type StanzaHandler = XMLElem -> XMPP () -- | Lift a computation from the IO monad. liftIO :: MonadIO m => forall a. IO a -> m a -- | A data structure representing an XML element. data XMLElem -- | Tags have a name, a list of attributes, and a list of child elements. XML :: String -> [(String, String)] -> [XMLElem] -> XMLElem -- | Character data just contains a string. CData :: String -> 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. xmlPath :: [String] -> XMLElem -> Maybe XMLElem xmlPath' :: [String] -> [XMLElem] -> [XMLElem] -- | Get the value of an attribute in the given tag. getAttr :: String -> XMLElem -> Maybe String -- | Get the character data subelement of the given tag. getCdata :: XMLElem -> Maybe String -- | Get all childs of the XML element allChilds :: XMLElem -> [XMLElem] -- | Convert the tag back to XML. If the first parameter is true, close the -- tag. xmlToString :: Bool -> XMLElem -> String -- | Send an IQ request, returning the randomly generated ID. sendIq :: String -> String -> [XMLElem] -> XMPP String -- | Send an IQ request and wait for the response, without blocking other -- activity. sendIqWait :: String -> String -> [XMLElem] -> XMPP XMLElem -- | Return true if the message stanza has body text. hasBody :: StanzaPredicate -- | Get the body text of the message stanza, if any. getMessageBody :: XMLElem -> Maybe String -- | Send an ordinary "chat" type message. sendMessage :: String -> String -> XMPP () -- | Send ordinary online presence. sendPresence :: Maybe (String, [String]) -> Maybe Integer -> XMPP () -- | Conjunction ("and") of two predicates. conj :: (a -> Bool) -> (a -> Bool) -> (a -> Bool) -- | Apply the predicate to the named attribute. Return false if the tag -- has no such attribute. attributeMatches :: String -> (String -> Bool) -> StanzaPredicate -- | Return true if the tag is a message stanza. isMessage :: StanzaPredicate -- | Return true if the tag is a presence stanza. isPresence :: StanzaPredicate -- | Return true if the tag is an IQ stanza. isIq :: StanzaPredicate -- | Return true if the tag is a chat message. isChat :: StanzaPredicate -- | Return true if the stanza is from the given JID. isFrom :: String -> StanzaPredicate -- | Return true if the stanza is an IQ stanza in the given namespace. -- FIXME: query node not nessesary the first node in the iq stanza. iqXmlns :: String -> StanzaPredicate -- | Return true if the stanza is a "get" request in the given namespace. iqGet :: String -> StanzaPredicate -- | Return true if the stanza is a "set" request in the given namespace. iqSet :: String -> StanzaPredicate -- | Return true if the stanza is a "error" request in the given namespace. iqError :: String -> StanzaPredicate -- | Return true if the stanza is a "result" request in the given -- namespace. iqResult :: String -> StanzaPredicate -- | Establish a handler for answering to version requests with the given -- information. See XEP-0092: Software Version. handleVersion :: String -> String -> String -> XMPP () -- | Return stanza's error code or -1 (if can't parse error node). Zero if -- no error. getErrorCode :: XMLElem -> Integer -- | Return true if the tag has the given name. hasNodeName :: String -> StanzaPredicate -- | Get the stamp of message, if has any. getMessageStamp :: XMLElem -> Maybe String -- | Get the jid and the resource of stanza. getJidRes :: XMLElem -> (String, String) -- | Get cdata from xmlelem. cdata :: XMLElem -> String -- | Get maybe cdata from maybe xmlelem. cdata' :: Maybe XMLElem -> Maybe String -- | Get username part of JID, i.e. the part before the @ sign. Return -- "" if the JID contains no @ sign. getUsername :: String -> String -- | Get resource part of JID, i.e. the part after /. Return "" if -- the JID has no resource. getResource :: String -> String -- | Get the bare JID, i.e. everything except the resource. getBareJid :: String -> String -- | Non-SASL authentication, following XEP-0078. startAuth :: String -> String -> String -> String -> XMPP Integer -- | An XMPP connection over TCP. data TCPConnection -- | Open a TCP connection to the named server, port 5222 (or others found -- in SRV), and send a stream header. openStream :: String -> IO TCPConnection -- | Get the stream header that the server sent. This needs to be called -- before doing anything else with the stream. getStreamStart :: TCPConnection -> IO XMLElem -- | A class for various kinds of XMPP connections. class XMPPConnection c getStanzas :: XMPPConnection c => c -> IO [XMLElem] sendStanza :: XMPPConnection c => c -> XMLElem -> IO () closeConnection :: XMPPConnection c => c -> IO () data RosterItem RosterItem :: String -> String -> Subscription -> [String] -> RosterItem itemName :: RosterItem -> String itemJid :: RosterItem -> String itemSubscription :: RosterItem -> Subscription itemGroups :: RosterItem -> [String] data Subscription SBoth :: Subscription SFrom :: Subscription STo :: Subscription SNone :: Subscription SUnknown :: Subscription getRoster :: XMPP [RosterItem] data Presence Available :: Status -> Presence Unavailable :: Status -> Presence Subscribe :: Presence Subscribed :: Presence Unsubscribe :: Presence Unsubscribed :: Presence Probe :: Presence Error :: Presence -- | TODO: xml:lang for multiple statuses. data Status Status :: StatusType -> [String] -> Status data StatusType StatusOnline :: StatusType StatusAway :: StatusType StatusChat :: StatusType StatusDND :: StatusType StatusXA :: StatusType StatusOffline :: StatusType -- | Read presence stanza. doPresence :: XMLElem -> Presence -- | Read stanza status. doStatus :: XMLElem -> Status -- | Implementation of Multi-User Chat, according to XEP-0045. This API -- needs more thought and will change. module Network.XMPP.MUC -- | Return true if the stanza is from a JID whose "username@server" part -- matches the given string. matchesBare :: String -> StanzaPredicate -- | Join groupchat. joinGroupchat :: String -> String -> Maybe String -> XMPP () -- | Leave groupchat. leaveGroupchat :: String -> XMPP () -- | Return true if the stanza is a message of type "groupchat". isGroupchatMessage :: StanzaPredicate -- | Return true if the stanza is a private message in the named room. isGroupchatPrivmsg :: String -> StanzaPredicate -- | Send a groupchat message. sendGroupchatMessage :: String -> String -> XMPP () -- | Send a private message in a chat room. sendGroupchatPrivateMessage :: String -> String -> String -> XMPP () getMessageSubject :: XMLElem -> Maybe String setGroupchatSubject :: String -> String -> XMPP () -- | Groupchat occupant. data Occupant Occupant :: Role -> Affiliation -> String -> Maybe String -> Status -> Occupant occRole :: Occupant -> Role occAffiliation :: Occupant -> Affiliation occNick :: Occupant -> String occJid :: Occupant -> Maybe String occStatus :: Occupant -> Status data Role RModerator :: Role RParticipant :: Role RNone :: Role RVisitor :: Role data Affiliation AOwner :: Affiliation AAdmin :: Affiliation AMember :: Affiliation ANone :: Affiliation AOutcast :: Affiliation -- | Groupchat presence. Leave, Kick and Ban are role change too of course, -- but it separated for simplicity sake. data GroupchatPresence Leave :: GroupchatPresence -- | Kick reason Kick :: (Maybe String) -> GroupchatPresence -- | Ban reason Ban :: (Maybe String) -> GroupchatPresence -- | New nick NickChange :: String -> GroupchatPresence -- | Role change (also show/status change) with reason. RoleChange :: (Maybe String) -> GroupchatPresence -- | Create groupchat presence from stanza. doGroupchatPresence :: XMLElem -> (GroupchatPresence, Occupant) -- | Handler for groupchat events (joinleavekicksbansetc). isGroupchatPresence :: StanzaPredicate type Nick = String type JID = String -- | Do admin actions in groupchat. adminGroupchat :: Either Nick JID -> String -> String -> (Maybe String) -> XMPP () instance Eq Affiliation instance Show Affiliation instance Eq Role instance Show Role