-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | An IRC client library. -- -- An IRC client library built atop irc-conduit. Why another IRC -- client library, you cry? I didn't really find one that did what I -- wanted (specifically, handle connecting to servers and calling event -- handlers, possibly with TLS), but which didn't implement almost a full -- IRC bot for you. That takes out all the fun! -- -- irc-conduit and irc-ctcp are my solution to the first -- part of that, this is my solution to the latter. It's a simple IRC -- client library that does the basics for you, but isn't an all-singing, -- all-dancing, fully-featured IRC application. It is a merely a -- simple library. @package irc-client @version 1.1.2.1 -- | Types and functions for dealing with optics without depending on the -- lens library. -- -- This module is NOT considered to form part of the public interface of -- this library. module Network.IRC.Client.Internal.Lens -- | See Control.Lens.Lens.Lens. type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t -- | A Simple Lens. type Lens' s a = Lens s s a a -- | See Control.Lens.Getter.Getter. type Getter s a = forall f. (Contravariant f, Functor f) => (a -> f a) -> s -> f s -- | See Control.Lens.Getter.Getting. type Getting r s a = (a -> Const r a) -> s -> Const r s -- | See Control.Lens.Prism.Prism. type Prism s t a b = forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t) -- | A Simple Prism. type Prism' s a = Prism s s a a -- | Get a value from a lens. get :: Getting a s a -> s -> a -- | Set a value in a lens. set :: Lens' s a -> a -> s -> s -- | Modify a value in a lens. modify :: Lens' s a -> (a -> a) -> s -> s -- | Read a value from a prism. preview :: Prism' s a -> s -> Maybe a -- | Atomically snapshot some shared state. snapshot :: MonadIO m => Getting (TVar a) s (TVar a) -> s -> m a -- | Atomically snapshot and modify some shared state. snapshotModify :: MonadIO m => Lens' s (TVar a) -> (a -> STM (a, b)) -> s -> m b -- | Internal types. Most of these are re-exported elsewhere as lenses. -- -- This module is NOT considered to form part of the public interface of -- this library. module Network.IRC.Client.Internal.Types -- | The IRC monad. newtype IRC s a IRC :: ReaderT (IRCState s) IO a -> IRC s a [runIRC] :: IRC s a -> ReaderT (IRCState s) IO a -- | The state of an IRC session. data IRCState s IRCState :: ConnectionConfig s -> TVar s -> TVar (InstanceConfig s) -> TVar (TBMChan (Message ByteString)) -> TVar ConnectionState -> TVar (Set ThreadId) -> IRCState s -- | Read-only connection configuration [_connectionConfig] :: IRCState s -> ConnectionConfig s -- | Mutable user state [_userState] :: IRCState s -> TVar s -- | Mutable instance configuration in STM [_instanceConfig] :: IRCState s -> TVar (InstanceConfig s) -- | Message send queue. [_sendqueue] :: IRCState s -> TVar (TBMChan (Message ByteString)) -- | State of the connection. [_connectionState] :: IRCState s -> TVar ConnectionState -- | Threads which will be killed when the client disconnects. [_runningThreads] :: IRCState s -> TVar (Set ThreadId) -- | The static state of an IRC server connection. data ConnectionConfig s ConnectionConfig :: (IO () -> ConduitM (Either ByteString (Event ByteString)) Void IO () -> ConduitM () (Message ByteString) IO () -> IO ()) -> ByteString -> Int -> Text -> Text -> Maybe Text -> NominalDiffTime -> NominalDiffTime -> IRC s () -> (Maybe SomeException -> IRC s ()) -> (Origin -> ByteString -> IO ()) -> ConnectionConfig s -- | Function to connect and start the conduits. [_func] :: ConnectionConfig s -> IO () -> ConduitM (Either ByteString (Event ByteString)) Void IO () -> ConduitM () (Message ByteString) IO () -> IO () -- | The server host. [_server] :: ConnectionConfig s -> ByteString -- | The server port. [_port] :: ConnectionConfig s -> Int -- | Client username; sent to the server during the initial set-up. [_username] :: ConnectionConfig s -> Text -- | Client realname; sent to the server during the initial set-up. [_realname] :: ConnectionConfig s -> Text -- | Client password; sent to the server during the initial set-up. [_password] :: ConnectionConfig s -> Maybe Text -- | The minimum time between two adjacent messages. [_flood] :: ConnectionConfig s -> NominalDiffTime -- | The maximum time (in seconds) between received messages from the -- server. If no messages arrive from the server for this period, the -- client is sent a Timeout exception and disconnects. [_timeout] :: ConnectionConfig s -> NominalDiffTime -- | Action to run after sending the PASS and USER -- commands to the server. The default behaviour is to send the -- NICK command. [_onconnect] :: ConnectionConfig s -> IRC s () -- | Action to run after disconnecting from the server, both by local -- choice and by losing the connection. This is run after tearing down -- the connection. If the connection terminated due to an exception, it -- is given. The default behaviour is to reconnect if a timeout, -- otherwise rethrow any exception. [_ondisconnect] :: ConnectionConfig s -> Maybe SomeException -> IRC s () -- | Function to log messages sent to and received from the server. [_logfunc] :: ConnectionConfig s -> Origin -> ByteString -> IO () -- | The updateable state of an IRC connection. data InstanceConfig s InstanceConfig :: Text -> [Text] -> Text -> [EventHandler s] -> [(Text, Maybe Text)] -> InstanceConfig s -- | Client nick [_nick] :: InstanceConfig s -> Text -- | Current channels: this list both determines the channels to join on -- connect, and is modified by the default event handlers when channels -- are joined or parted. [_channels] :: InstanceConfig s -> [Text] -- | The version is sent in response to the CTCP "VERSION" request by the -- default event handlers. [_version] :: InstanceConfig s -> Text -- | The registered event handlers. The order in this list is the order in -- which they are executed. [_handlers] :: InstanceConfig s -> [EventHandler s] -- | List of nicks (optionally restricted to channels) to ignore messages -- from. Nothing ignores globally. [_ignore] :: InstanceConfig s -> [(Text, Maybe Text)] -- | The state of the connection. data ConnectionState Connected :: ConnectionState Disconnecting :: ConnectionState Disconnected :: ConnectionState -- | The origin of a message. data Origin FromServer :: Origin FromClient :: Origin -- | A function which handles an event. data EventHandler s [EventHandler] :: (Event Text -> Maybe b) -> (Source Text -> b -> IRC s ()) -> EventHandler s -- | Exception thrown to kill the client if the timeout elapses with -- nothing received from the server. data Timeout Timeout :: Timeout -- | Exception thrown to all managed threads when the client disconnects. data Disconnect Disconnect :: Disconnect instance GHC.Show.Show Network.IRC.Client.Internal.Types.ConnectionState instance GHC.Read.Read Network.IRC.Client.Internal.Types.ConnectionState instance GHC.Classes.Ord Network.IRC.Client.Internal.Types.ConnectionState instance GHC.Classes.Eq Network.IRC.Client.Internal.Types.ConnectionState instance GHC.Enum.Enum Network.IRC.Client.Internal.Types.ConnectionState instance GHC.Enum.Bounded Network.IRC.Client.Internal.Types.ConnectionState instance GHC.Show.Show Network.IRC.Client.Internal.Types.Origin instance GHC.Read.Read Network.IRC.Client.Internal.Types.Origin instance GHC.Classes.Ord Network.IRC.Client.Internal.Types.Origin instance GHC.Classes.Eq Network.IRC.Client.Internal.Types.Origin instance GHC.Enum.Enum Network.IRC.Client.Internal.Types.Origin instance GHC.Enum.Bounded Network.IRC.Client.Internal.Types.Origin instance Control.Monad.Catch.MonadMask (Network.IRC.Client.Internal.Types.IRC s) instance Control.Monad.Catch.MonadCatch (Network.IRC.Client.Internal.Types.IRC s) instance Control.Monad.Catch.MonadThrow (Network.IRC.Client.Internal.Types.IRC s) instance Control.Monad.Reader.Class.MonadReader (Network.IRC.Client.Internal.Types.IRCState s) (Network.IRC.Client.Internal.Types.IRC s) instance Control.Monad.IO.Class.MonadIO (Network.IRC.Client.Internal.Types.IRC s) instance GHC.Base.MonadPlus (Network.IRC.Client.Internal.Types.IRC s) instance GHC.Base.Monad (Network.IRC.Client.Internal.Types.IRC s) instance GHC.Base.Alternative (Network.IRC.Client.Internal.Types.IRC s) instance GHC.Base.Applicative (Network.IRC.Client.Internal.Types.IRC s) instance GHC.Base.Functor (Network.IRC.Client.Internal.Types.IRC s) instance GHC.Show.Show Network.IRC.Client.Internal.Types.Timeout instance GHC.Read.Read Network.IRC.Client.Internal.Types.Timeout instance GHC.Classes.Ord Network.IRC.Client.Internal.Types.Timeout instance GHC.Classes.Eq Network.IRC.Client.Internal.Types.Timeout instance GHC.Enum.Enum Network.IRC.Client.Internal.Types.Timeout instance GHC.Enum.Bounded Network.IRC.Client.Internal.Types.Timeout instance GHC.Show.Show Network.IRC.Client.Internal.Types.Disconnect instance GHC.Read.Read Network.IRC.Client.Internal.Types.Disconnect instance GHC.Classes.Ord Network.IRC.Client.Internal.Types.Disconnect instance GHC.Classes.Eq Network.IRC.Client.Internal.Types.Disconnect instance GHC.Enum.Enum Network.IRC.Client.Internal.Types.Disconnect instance GHC.Enum.Bounded Network.IRC.Client.Internal.Types.Disconnect instance GHC.Exception.Type.Exception Network.IRC.Client.Internal.Types.Disconnect instance GHC.Exception.Type.Exception Network.IRC.Client.Internal.Types.Timeout instance Control.Monad.State.Class.MonadState s (Network.IRC.Client.Internal.Types.IRC s) -- | Lenses and Prisms. module Network.IRC.Client.Lens -- | Getter for _connectionConfig. connectionConfig :: Getter (IRCState s) (ConnectionConfig s) -- | Lens for _userState. userState :: Lens' (IRCState s) (TVar s) -- | Lens for _instanceConfig. instanceConfig :: Lens' (IRCState s) (TVar (InstanceConfig s)) -- | Lens for _connectionState. connectionState :: Lens' (IRCState s) (TVar ConnectionState) -- | Getter for _server. server :: Getter (ConnectionConfig s) ByteString -- | Getter for _port. port :: Getter (ConnectionConfig s) Int -- | Lens for _username. username :: Lens' (ConnectionConfig s) Text -- | Lens for _realname. realname :: Lens' (ConnectionConfig s) Text -- | Lens for _password. password :: Lens' (ConnectionConfig s) (Maybe Text) -- | Lens for _flood. flood :: Lens' (ConnectionConfig s) NominalDiffTime -- | Lens for _timeout. timeout :: Lens' (ConnectionConfig s) NominalDiffTime -- | Lens for _onconnect. onconnect :: Lens' (ConnectionConfig s) (IRC s ()) -- | Lens for _ondisconnect. ondisconnect :: Lens' (ConnectionConfig s) (Maybe SomeException -> IRC s ()) -- | Lens for _logfunc. logfunc :: Lens' (ConnectionConfig s) (Origin -> ByteString -> IO ()) -- | Lens for _nick. nick :: Lens' (InstanceConfig s) Text -- | Lens for _channels. channels :: Lens' (InstanceConfig s) [Text] -- | Lens for _version. version :: Lens' (InstanceConfig s) Text -- | Lens for _version. handlers :: Lens' (InstanceConfig s) [EventHandler s] -- | Lens for _ignore. ignore :: Lens' (InstanceConfig s) [(Text, Maybe Text)] -- | Prism for Connected. _Connected :: Prism' ConnectionState () -- | Prism for Disconnecting. _Disconnecting :: Prism' ConnectionState () -- | Prism for Disconnected. _Disconnected :: Prism' ConnectionState () -- | Prism for FromServer. _FromServer :: Prism' Origin () -- | Prism for FromClient. _FromClient :: Prism' Origin () -- | Most of the hairy code. This isn't all internal, due to messy -- dependencies, but I've tried to make this as "internal" as reasonably -- possible. -- -- This module is NOT considered to form part of the public interface of -- this library. module Network.IRC.Client.Internal -- | Config to connect to a server using the supplied connection function. setupInternal :: (IO () -> ConduitM (Either ByteString (Event ByteString)) Void IO () -> ConduitM () (Message ByteString) IO () -> IO ()) -> IRC s () -> (Maybe SomeException -> IRC s ()) -> (Origin -> ByteString -> IO ()) -> ByteString -> Int -> ConnectionConfig s -- | The event loop. runner :: IRC s () -- | Forget failed decodings. forgetful :: Monad m => ConduitM (Either a b) b m () -- | Block on receiving a message and invoke all matching handlers. eventSink :: MonadIO m => IORef UTCTime -> IRCState s -> ConduitM (Event ByteString) o m () -- | Check if an event is ignored or not. isIgnored :: MonadIO m => IRCState s -> Event Text -> m Bool -- | A conduit which logs everything which goes through it. logConduit :: MonadIO m => (a -> IO ()) -> ConduitM a a m () -- | Print messages to stdout, with the current time. stdoutLogger :: Origin -> ByteString -> IO () -- | Append messages to a file, with the current time. fileLogger :: FilePath -> Origin -> ByteString -> IO () -- | Do no logging. noopLogger :: a -> b -> IO () -- | Clear passwords from logs. concealPass :: Message ByteString -> Message ByteString -- | Send a message as UTF-8, using TLS if enabled. This blocks if messages -- are sent too rapidly. send :: Message Text -> IRC s () -- | Send a message, using TLS if enabled. This blocks if messages are sent -- too rapidly. sendBS :: Message ByteString -> IRC s () -- | Disconnect from the server, properly tearing down the TLS session (if -- there is one). disconnect :: IRC s () -- | Disconnect from the server (this will wait for all messages to be -- sent, or a minute to pass), and then connect again. -- -- This can be called after the client has already disconnected, in which -- case it will just connect again. -- -- Like runClient and runClientWith, this will not -- return until the client terminates (ie, disconnects without -- reconnecting). reconnect :: IRC s () -- | Interact with a client from the outside, by using its IRCState. runIRCAction :: MonadIO m => IRC s a -> IRCState s -> m a -- | Access the client state. getIRCState :: IRC s (IRCState s) -- | Get the connection state from an IRC state. getConnectionState :: IRCState s -> STM ConnectionState -- | Block until an action is successful or a timeout is reached. timeoutBlock :: MonadIO m => NominalDiffTime -> IO Bool -> m () -- | A simple wrapper around a TBMChan. As data is pushed into the channel, -- the source will read it and pass it down the conduit pipeline. When -- the channel is closed, the source will close also. -- -- If the channel fills up, the pipeline will stall until values are -- read. -- -- From stm-conduit-3.0.0 (by Clark Gaebel cg.wowus.cg@gmail.com) sourceTBMChan :: MonadIO m => TBMChan a -> ConduitM () a m () -- | Commonly-used utility functions for IRC clients. module Network.IRC.Client.Utils -- | Update the nick in the instance configuration and also send an update -- message to the server. This doesn't attempt to resolve nick -- collisions, that's up to the event handlers. setNick :: Text -> IRC s () -- | Update the channel list in the instance configuration and also part -- the channel. leaveChannel :: Text -> Maybe Text -> IRC s () -- | Remove a channel from the list without sending a part command (be -- careful not to let the channel list get out of sync with the -- real-world state if you use it for anything!) delChan :: TVar (InstanceConfig s) -> Text -> STM () -- | Add an event handler addHandler :: EventHandler s -> IRC s () -- | Send a message to the source of an event. reply :: Event Text -> Text -> IRC s () -- | Send a message to the source of an event. replyTo :: Source Text -> Text -> IRC s () -- | Construct a PRIVMSG containing a CTCP ctcp :: Text -> Text -> [Text] -> Message Text -- | Construct a NOTICE containing a CTCP ctcpReply :: Text -> Text -> [Text] -> Message Text -- | Check if the client is connected. isConnected :: IRC s Bool -- | Check if the client is in the process of disconnecting. isDisconnecting :: IRC s Bool -- | Check if the client is disconnected isDisconnected :: IRC s Bool -- | Snapshot the connection state. snapConnState :: IRC s ConnectionState -- | Fork a thread which will be thrown a Disconnect exception when -- the client disconnects. fork :: IRC s () -> IRC s ThreadId -- | Atomically snapshot some shared state. snapshot :: MonadIO m => Getting (TVar a) s (TVar a) -> s -> m a -- | Atomically snapshot and modify some shared state. snapshotModify :: MonadIO m => Lens' s (TVar a) -> (a -> STM (a, b)) -> s -> m b -- | Get a value from a lens. get :: Getting a s a -> s -> a -- | Set a value in a lens. set :: Lens' s a -> a -> s -> s -- | Modify a value in a lens. modify :: Lens' s a -> (a -> a) -> s -> s -- | Events and event handlers. When a message is received from the server, -- all matching handlers are executed sequentially in the order that they -- appear in the handlers list. module Network.IRC.Client.Events -- | A function which handles an event. data EventHandler s [EventHandler] :: (Event Text -> Maybe b) -> (Source Text -> b -> IRC s ()) -> EventHandler s -- | Match the verb of a CTCP, ignoring case, and returning the arguments. -- --
-- matchCTCP "ping" ":foo PRIVMSG #bar :\001PING\001" ==> Just [] -- matchCTCP "PING" ":foo PRIVMSG #bar :\001PING\001" ==> Just [] -- matchCTCP "ACTION" ":foo PRIVMSG #bar :\001ACTION dances\001" ==> Just ["dances"] --matchCTCP :: Text -> Event Text -> Maybe [Text] -- | Match a numeric server message. Numeric messages are sent in response -- to most things, such as connecting to the server, or joining a -- channel. -- -- Numerics in the range 001 to 099 are informative messages, numerics in -- the range 200 to 399 are responses to commands. Some common numerics -- are: -- --
-- matchNumeric 001 "001 :Welcome to irc.example.com" ==> True -- matchNumeric 332 "332 :#haskell: We like Haskell" ==> True --matchNumeric :: Int -> Event a -> Maybe [a] -- | Match events of the given type. Refer to -- Network.IRC.Conduit.Lens#Message for the list of -- Prism's. -- --
-- matchType _Privmsg ":foo PRIVMSG #bar :hello world" ==> Just ("#bar", Right "hello world")
-- matchType _Quit ":foo QUIT :goodbye world" ==> Just (Just "goodbye world")
--
matchType :: Prism' (Message a) b -> Event a -> Maybe b
-- | Match a predicate against an event.
--
-- -- matchWhen (const True) ":foo PRIVMSG #bar :hello world" ==> Just ":foo PRIVMSG :hello world" --matchWhen :: (Event a -> Bool) -> Event a -> Maybe (Message a) -- | The default event handlers, the following are included: -- --
-- run :: ByteString -> Int -> Text -> IO () -- run host port nick = do -- let conn = plainConnection host port -- let cfg = defaultInstanceConfig nick & handlers %~ (yourCustomEventHandlers:) -- runClient conn cfg () ---- -- You shouldn't really need to tweak anything other than the event -- handlers, as everything has been designed to be as simple as possible. module Network.IRC.Client -- | The static state of an IRC server connection. data ConnectionConfig s -- | Connect to a server without TLS. plainConnection :: ByteString -> Int -> ConnectionConfig s -- | How to connect to a server over TLS. data TLSConfig -- | Use Network.IRC.Conduit.defaultTLSConfig. WithDefaultConfig :: ByteString -> Int -> TLSConfig -- | Use the given configuration. The hostname and port are stored as -- fields of the TLSClientConfig. WithClientConfig :: TLSClientConfig -> TLSConfig -- | Use Network.IRC.Conduit.defaultTLSConfig, with the -- given certificate verifier. The certificate verifier is a function -- which returns a list of reasons to reject the certificate. WithVerifier :: ByteString -> Int -> (CertificateStore -> ValidationCache -> ServiceID -> CertificateChain -> IO [FailedReason]) -> TLSConfig -- | Connect to a server with TLS. tlsConnection :: TLSConfig -> ConnectionConfig s -- | The origin of a message. data Origin FromServer :: Origin FromClient :: Origin -- | Print messages to stdout, with the current time. stdoutLogger :: Origin -> ByteString -> IO () -- | Append messages to a file, with the current time. fileLogger :: FilePath -> Origin -> ByteString -> IO () -- | Do no logging. noopLogger :: a -> b -> IO () -- | The updateable state of an IRC connection. data InstanceConfig s -- | Construct a default IRC configuration from a nick defaultInstanceConfig :: Text -> InstanceConfig s -- | The IRC monad. data IRC s a -- | Send a message as UTF-8, using TLS if enabled. This blocks if messages -- are sent too rapidly. send :: Message Text -> IRC s () -- | Send a message, using TLS if enabled. This blocks if messages are sent -- too rapidly. sendBS :: Message ByteString -> IRC s () -- | Disconnect from the server, properly tearing down the TLS session (if -- there is one). disconnect :: IRC s () -- | Disconnect from the server (this will wait for all messages to be -- sent, or a minute to pass), and then connect again. -- -- This can be called after the client has already disconnected, in which -- case it will just connect again. -- -- Like runClient and runClientWith, this will not -- return until the client terminates (ie, disconnects without -- reconnecting). reconnect :: IRC s () -- | The state of an IRC session. data IRCState s -- | Access the client state. getIRCState :: IRC s (IRCState s) -- | Interact with a client from the outside, by using its IRCState. runIRCAction :: MonadIO m => IRC s a -> IRCState s -> m a -- | The state of the connection. data ConnectionState Connected :: ConnectionState Disconnecting :: ConnectionState Disconnected :: ConnectionState -- | Get the connection state from an IRC state. getConnectionState :: IRCState s -> STM ConnectionState -- | Connect to the IRC server and run the client: receiving messages and -- handing them off to handlers as appropriate. runClient :: MonadIO m => ConnectionConfig s -> InstanceConfig s -> s -> m () -- | Construct a new IRC state newIRCState :: MonadIO m => ConnectionConfig s -> InstanceConfig s -> s -> m (IRCState s) -- | Like runClient, but use the provided initial IRCState. -- -- Multiple clients should not be run with the same IRCState. The -- utility of this is to be able to run IRC s a actions in order -- to interact with the client from the outside. runClientWith :: MonadIO m => IRCState s -> m () -- | Exception thrown to kill the client if the timeout elapses with -- nothing received from the server. data Timeout Timeout :: Timeout -- | Fork a thread which will be thrown a Disconnect exception when -- the client disconnects. fork :: IRC s () -> IRC s ThreadId -- | Exception thrown to all managed threads when the client disconnects. data Disconnect Disconnect :: Disconnect -- | Get a value from a lens. get :: Getting a s a -> s -> a -- | Set a value in a lens. set :: Lens' s a -> a -> s -> s -- | Modify a value in a lens. modify :: Lens' s a -> (a -> a) -> s -> s -- | Atomically snapshot some shared state. snapshot :: MonadIO m => Getting (TVar a) s (TVar a) -> s -> m a -- | Atomically snapshot and modify some shared state. snapshotModify :: MonadIO m => Lens' s (TVar a) -> (a -> STM (a, b)) -> s -> m b -- | Update the nick in the instance configuration and also send an update -- message to the server. This doesn't attempt to resolve nick -- collisions, that's up to the event handlers. setNick :: Text -> IRC s () -- | Update the channel list in the instance configuration and also part -- the channel. leaveChannel :: Text -> Maybe Text -> IRC s () -- | Remove a channel from the list without sending a part command (be -- careful not to let the channel list get out of sync with the -- real-world state if you use it for anything!) delChan :: TVar (InstanceConfig s) -> Text -> STM () -- | Add an event handler addHandler :: EventHandler s -> IRC s () -- | Send a message to the source of an event. reply :: Event Text -> Text -> IRC s () -- | Send a message to the source of an event. replyTo :: Source Text -> Text -> IRC s () -- | Construct a PRIVMSG containing a CTCP ctcp :: Text -> Text -> [Text] -> Message Text -- | Construct a NOTICE containing a CTCP ctcpReply :: Text -> Text -> [Text] -> Message Text -- | Check if the client is connected. isConnected :: IRC s Bool -- | Check if the client is in the process of disconnecting. isDisconnecting :: IRC s Bool -- | Check if the client is disconnected isDisconnected :: IRC s Bool -- | Snapshot the connection state. snapConnState :: IRC s ConnectionState -- | Construct a raw message. rawMessage :: ByteString -> [ByteString] -> IrcMessage -- | Encode an IRC message into a single bytestring suitable for sending to -- the server. toByteString :: IrcMessage -> ByteString