defmodule Exampple.Router.Conn do
@moduledoc """
Conn is a module to store the information related to a XMPP
request. Conn has the following information inside:
- `domain`: the component domain.
- `from_jid`: the JID where the stanza is coming from.
- `to_jid`: the JID where the stanza is sent to.
- `id`: the ID for the stanza.
- `type`: the type attribute of the stanza. Depending on the stanza
type it could be `chat`, `groupchat`, `normal`, `get`, `set`, ...
- `xmlns`: the namespace for the XML stanza.
- `stanza_type`: the stanza type, it could be `iq`, `message` or
`presence`. It is possible to receive other kind of XML stanzas,
but it is not common.
- `stanza`: the original stanza in `%Xmlel{}` format.
- `reponse`: the generated response in use if we pass the connection
to the `Exampple.Component` module.
- `envelope`: it is an anonymous function needed if we are receiving
stanzas which are using an envelope. It is not needed to handle it
manually, see further information about this in `Exampple.Router`.
"""
alias Exampple.Router.Conn
alias Exampple.Xml.Xmlel
alias Exampple.Xmpp.Jid
defstruct domain: nil,
from_jid: nil,
to_jid: nil,
id: nil,
type: nil,
xmlns: "",
stanza_type: nil,
stanza: nil,
response: nil,
envelope: nil
@type t() :: %__MODULE__{
domain: String.t() | nil,
from_jid: Jid.t() | nil,
to_jid: Jid.t() | nil,
id: String.t() | nil,
type: String.t() | nil,
xmlns: String.t() | nil,
stanza_type: String.t() | nil,
stanza: Xmlel.t() | nil,
response: Xmlel.t() | nil,
envelope: (Xmlel.t() -> Xmlel.t()) | nil
}
@doc """
Creates a new connection passing a `%Xmlel{}` struct in `xmlel` as the
first parameter and a `domain` as a second parameter (or `nil` by default)
to create a `%Conn{}` struct.
"""
def new(%Xmlel{} = xmlel, domain \\ nil) do
xmlns =
case xmlel.children do
[%Xmlel{} = subel | _] -> Xmlel.get_attr(subel, "xmlns", "")
_ -> ""
end
%Conn{
domain: domain,
from_jid: Jid.parse(Xmlel.get_attr(xmlel, "from")),
to_jid: Jid.parse(Xmlel.get_attr(xmlel, "to")),
id: Xmlel.get_attr(xmlel, "id"),
type:
case xmlel.name do
"message" -> Xmlel.get_attr(xmlel, "type", "normal")
"presence" -> Xmlel.get_attr(xmlel, "type", "available")
_ -> Xmlel.get_attr(xmlel, "type", "")
end,
xmlns: xmlns,
stanza_type: xmlel.name,
stanza: xmlel
}
end
@doc """
Obtains the response stored inside of the `conn`. Checking if there
is an envelope used or not.
"""
def get_response(%Conn{envelope: nil, response: response}) when response != nil do
to_string(response)
end
def get_response(%Conn{envelope: envelope, response: response}) when response != nil do
get_response(envelope.(response))
end
end