'Emits something to a session attached to the object.
Args:
text (str or tuple, optional): The message to send. This
is treated internally like any send-command, so its
value can be a tuple if sending multiple arguments to
the `text` oob command.
from_obj (obj, optional): object that is sending. If
given, at_msg_send will be called. This value will be
passed on to the protocol.
session (Session or list, optional): Session or list of
Sessions to relay data to, if any. If set, will force send
to these sessions. If unset, who receives the message
depends on the MULTISESSION_MODE.
options (dict, optional): Message-specific option-value
pairs. These will be applied at the protocol level.
Kwargs:
any (string or tuples): All kwarg keys not listed above
will be treated as send-command names and their arguments
(which can be a string or a tuple).
Notes:
`at_msg_receive` will be called on this Object.
All extra kwargs will be passed on to the protocol.'

def msg(self, text=None, from_obj=None, session=None, options=None, **kwargs):

    if from_obj:
        try:
            from_obj.at_msg_send(text=text, to_obj=self, **kwargs)
        except Exception:
            logger.log_trace()
    try:
        if (not self.at_msg_receive(text=text, **kwargs)):
            return
    except Exception:
        logger.log_trace()
    kwargs['options'] = options
    sessions = (make_iter(session) if session else self.sessions.all())
    for session in sessions:
        session.data_out(text=text, **kwargs)
