From ea969750efc4110e1e6eb844a578b33cad575699 Mon Sep 17 00:00:00 2001
From: "roberto.borghes" <roberto.borghes@elettra.eu>
Date: Tue, 20 Oct 2020 17:37:35 +0200
Subject: [PATCH] First alfa-tested release

---
 README.md                                     |   1 +
 RocketChat.py                                 | 201 ++++++++++++
 RocketChat.xmi                                |  47 +++
 rocketChatLib.py                              | 115 +++++++
 rocketchat/__init__.py                        |   0
 rocketchat/api.py                             | 310 ++++++++++++++++++
 rocketchat/calls/__init__.py                  |   0
 rocketchat/calls/auth/__init__.py             |   0
 rocketchat/calls/auth/get_me.py               |  15 +
 rocketchat/calls/base.py                      | 134 ++++++++
 rocketchat/calls/channels/__init__.py         |   0
 .../calls/channels/create_public_room.py      |  23 ++
 .../calls/channels/delete_public_room.py      |  21 ++
 rocketchat/calls/channels/get_history.py      |  24 ++
 rocketchat/calls/channels/get_public_rooms.py |  31 ++
 rocketchat/calls/channels/get_room_info.py    |  18 +
 rocketchat/calls/chat/__init__.py             |   0
 rocketchat/calls/chat/send_message.py         |  11 +
 rocketchat/calls/groups/__init__.py           |   0
 .../calls/groups/get_private_room_history.py  |  25 ++
 .../calls/groups/get_private_room_info.py     |  18 +
 rocketchat/calls/groups/get_private_rooms.py  |  31 ++
 rocketchat/calls/groups/get_room_id.py        |  20 ++
 rocketchat/calls/groups/set_room_topic.py     |  21 ++
 rocketchat/calls/groups/upload_file.py        |  23 ++
 rocketchat/calls/im/__init__.py               |   0
 rocketchat/calls/im/close_room.py             |  19 ++
 rocketchat/calls/im/create_room.py            |  34 ++
 rocketchat/calls/im/get_history.py            |  47 +++
 rocketchat/calls/im/get_rooms.py              |  39 +++
 rocketchat/calls/im/open_room.py              |  19 ++
 rocketchat/calls/users/__init__.py            |   0
 rocketchat/calls/users/create_user.py         |  31 ++
 rocketchat/calls/users/delete_user.py         |  21 ++
 rocketchat/calls/users/get_user_info.py       |  19 ++
 rocketchat/calls/users/get_users.py           |  37 +++
 36 files changed, 1355 insertions(+)
 create mode 100755 RocketChat.py
 create mode 100644 RocketChat.xmi
 create mode 100644 rocketChatLib.py
 create mode 100644 rocketchat/__init__.py
 create mode 100644 rocketchat/api.py
 create mode 100644 rocketchat/calls/__init__.py
 create mode 100644 rocketchat/calls/auth/__init__.py
 create mode 100644 rocketchat/calls/auth/get_me.py
 create mode 100644 rocketchat/calls/base.py
 create mode 100644 rocketchat/calls/channels/__init__.py
 create mode 100644 rocketchat/calls/channels/create_public_room.py
 create mode 100644 rocketchat/calls/channels/delete_public_room.py
 create mode 100644 rocketchat/calls/channels/get_history.py
 create mode 100644 rocketchat/calls/channels/get_public_rooms.py
 create mode 100644 rocketchat/calls/channels/get_room_info.py
 create mode 100644 rocketchat/calls/chat/__init__.py
 create mode 100644 rocketchat/calls/chat/send_message.py
 create mode 100644 rocketchat/calls/groups/__init__.py
 create mode 100644 rocketchat/calls/groups/get_private_room_history.py
 create mode 100644 rocketchat/calls/groups/get_private_room_info.py
 create mode 100644 rocketchat/calls/groups/get_private_rooms.py
 create mode 100644 rocketchat/calls/groups/get_room_id.py
 create mode 100644 rocketchat/calls/groups/set_room_topic.py
 create mode 100644 rocketchat/calls/groups/upload_file.py
 create mode 100644 rocketchat/calls/im/__init__.py
 create mode 100644 rocketchat/calls/im/close_room.py
 create mode 100644 rocketchat/calls/im/create_room.py
 create mode 100644 rocketchat/calls/im/get_history.py
 create mode 100644 rocketchat/calls/im/get_rooms.py
 create mode 100644 rocketchat/calls/im/open_room.py
 create mode 100644 rocketchat/calls/users/__init__.py
 create mode 100644 rocketchat/calls/users/create_user.py
 create mode 100644 rocketchat/calls/users/delete_user.py
 create mode 100644 rocketchat/calls/users/get_user_info.py
 create mode 100644 rocketchat/calls/users/get_users.py

diff --git a/README.md b/README.md
index 9ada66c..1454200 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@ Rocket Chat Client Device Server
 
 Allows to send textual messages to a Rocket Chat Private Group.
 It is based on the rocket-python Python library.
+Python Dependencies: requests, urllib3.
 
 It needs 2 DB properties:
      - Host : the RocketChat host to be used;
diff --git a/RocketChat.py b/RocketChat.py
new file mode 100755
index 0000000..06f3212
--- /dev/null
+++ b/RocketChat.py
@@ -0,0 +1,201 @@
+#!/usr/bin/env python
+# -*- coding:utf-8 -*-
+
+
+# ############################################################################
+#  license :
+# ============================================================================
+#
+#  File :        RocketChat.py
+#
+#  Project :     RocketChat client
+#
+# This file is part of Tango device class.
+# 
+# Tango is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+# 
+# Tango is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Tango.  If not, see <http://www.gnu.org/licenses/>.
+# 
+#
+#  $Author :      sci.comp$
+#
+#  $Revision :    $
+#
+#  $Date :        $
+#
+#  $HeadUrl :     $
+# ============================================================================
+#            This file is generated by POGO
+#     (Program Obviously used to Generate tango Object)
+# ############################################################################
+
+__all__ = ["RocketChat", "RocketChatClass", "main"]
+
+__docformat__ = 'restructuredtext'
+
+import PyTango
+import sys
+# Add additional import
+#----- PROTECTED REGION ID(RocketChat.additionnal_import) ENABLED START -----#
+from rocketChatLib import rocketChat
+
+#----- PROTECTED REGION END -----#	//	RocketChat.additionnal_import
+
+# Device States Description
+# No states for this device
+
+
+class RocketChat (PyTango.Device_4Impl):
+    """RocketChat mmessage client"""
+    
+    # -------- Add you global variables here --------------------------
+    #----- PROTECTED REGION ID(RocketChat.global_variables) ENABLED START -----#
+    
+    #----- PROTECTED REGION END -----#	//	RocketChat.global_variables
+
+    def __init__(self, cl, name):
+        PyTango.Device_4Impl.__init__(self,cl,name)
+        self.debug_stream("In __init__()")
+        RocketChat.init_device(self)
+        #----- PROTECTED REGION ID(RocketChat.__init__) ENABLED START -----#
+        try:
+			with open(self.AuthenticationFile) as fp:
+				self.usrname = fp.readline().strip()
+				self.pwd = fp.readline().strip()
+        except:
+			self.set_state(PyTango.DevState.FAULT)
+			self.set_status("Unable to load authentication file")
+			return
+        self.chat = rocketChat(self.usrname,self.pwd,self.Host)
+        if self.chat.api is None:
+			self.set_state(PyTango.DevState.FAULT)
+			self.set_status("Unable to connect to %s" % self.Host)
+			return
+        try:
+			self.chat.Login()
+			self.set_state(PyTango.DevState.ON)
+        except:
+			self.set_state(PyTango.DevState.ALARM)
+			self.set_status("Unable to login on %s" % self.Host)
+        #----- PROTECTED REGION END -----#	//	RocketChat.__init__
+        
+    def delete_device(self):
+        self.debug_stream("In delete_device()")
+        #----- PROTECTED REGION ID(RocketChat.delete_device) ENABLED START -----#
+        
+        #----- PROTECTED REGION END -----#	//	RocketChat.delete_device
+
+    def init_device(self):
+        self.debug_stream("In init_device()")
+        self.get_device_properties(self.get_device_class())
+        #----- PROTECTED REGION ID(RocketChat.init_device) ENABLED START -----#
+        
+        #----- PROTECTED REGION END -----#	//	RocketChat.init_device
+
+    def always_executed_hook(self):
+        self.debug_stream("In always_excuted_hook()")
+        #----- PROTECTED REGION ID(RocketChat.always_executed_hook) ENABLED START -----#
+        
+        #----- PROTECTED REGION END -----#	//	RocketChat.always_executed_hook
+
+    # -------------------------------------------------------------------------
+    #    RocketChat read/write attribute methods
+    # -------------------------------------------------------------------------
+    
+    
+    
+            
+    def read_attr_hardware(self, data):
+        self.debug_stream("In read_attr_hardware()")
+        #----- PROTECTED REGION ID(RocketChat.read_attr_hardware) ENABLED START -----#
+        
+        #----- PROTECTED REGION END -----#	//	RocketChat.read_attr_hardware
+
+
+    # -------------------------------------------------------------------------
+    #    RocketChat command methods
+    # -------------------------------------------------------------------------
+    
+    def SendMessage(self, argin):
+        """ 
+        :param argin: [private_group_name,message]
+        :type argin: PyTango.DevVarStringArray
+        """
+        self.debug_stream("In SendMessage()")
+        #----- PROTECTED REGION ID(RocketChat.SendMessage) ENABLED START -----#
+        dest = argin[0]
+        txt = argin[1]
+        self.chat.SendMessage(txt,dest)
+        #----- PROTECTED REGION END -----#	//	RocketChat.SendMessage
+        
+
+    #----- PROTECTED REGION ID(RocketChat.programmer_methods) ENABLED START -----#
+    
+    #----- PROTECTED REGION END -----#	//	RocketChat.programmer_methods
+
+class RocketChatClass(PyTango.DeviceClass):
+    # -------- Add you global class variables here --------------------------
+    #----- PROTECTED REGION ID(RocketChat.global_class_variables) ENABLED START -----#
+    
+    #----- PROTECTED REGION END -----#	//	RocketChat.global_class_variables
+
+
+    #    Class Properties
+    class_property_list = {
+        }
+
+
+    #    Device Properties
+    device_property_list = {
+        'AuthenticationFile':
+            [PyTango.DevString, 
+            "Full path of the file containing the authentication info.\nThe file should contain 2 lines:\nUSRNAME\nPASSWORD",
+            ["/opt/rocketchat.auth"] ],
+        'Host':
+            [PyTango.DevString, 
+            "Rocket chat server url",
+            ["https://rocket.chat"] ],
+        }
+
+
+    #    Command definitions
+    cmd_list = {
+        'SendMessage':
+            [[PyTango.DevVarStringArray, "[private_group_name,message]"],
+            [PyTango.DevVoid, "none"]],
+        }
+
+
+    #    Attribute definitions
+    attr_list = {
+        }
+
+
+def main():
+    try:
+        py = PyTango.Util(sys.argv)
+        py.add_class(RocketChatClass, RocketChat, 'RocketChat')
+        #----- PROTECTED REGION ID(RocketChat.add_classes) ENABLED START -----#
+        
+        #----- PROTECTED REGION END -----#	//	RocketChat.add_classes
+
+        U = PyTango.Util.instance()
+        U.server_init()
+        U.server_run()
+
+    except PyTango.DevFailed as e:
+        print ('-------> Received a DevFailed exception:', e)
+    except Exception as e:
+        print ('-------> An unforeseen exception occured....', e)
+
+if __name__ == '__main__':
+    main()
diff --git a/RocketChat.xmi b/RocketChat.xmi
new file mode 100644
index 0000000..229f175
--- /dev/null
+++ b/RocketChat.xmi
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="ASCII"?>
+<pogoDsl:PogoSystem xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pogoDsl="http://www.esrf.fr/tango/pogo/PogoDsl">
+  <classes name="RocketChat" pogoRevision="9.4">
+    <description description="RocketChat mmessage client" title="RocketChat client" sourcePath="/store/home/roberto/devel/TWINMIC/servers/RocketChat" language="Python" filestogenerate="XMI   file,Code files,Protected Regions" license="GPL" copyright="" hasMandatoryProperty="false" hasConcreteProperty="true" hasAbstractCommand="false" hasAbstractAttribute="false">
+      <inheritances classname="Device_Impl" sourcePath=""/>
+      <identification contact="at elettra.eu - sci.comp" author="sci.comp" emailDomain="elettra.eu" classFamily="Communication" siteSpecific="" platform="All Platforms" bus="Ethernet" manufacturer="Rocket.Chat" reference=""/>
+    </description>
+    <deviceProperties name="AuthenticationFile" description="Full path of the file containing the authentication info.&#xA;The file should contain 2 lines:&#xA;USRNAME&#xA;PASSWORD">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+      <DefaultPropValue>/opt/rocketchat.auth</DefaultPropValue>
+    </deviceProperties>
+    <deviceProperties name="Host" description="Rocket chat server url">
+      <type xsi:type="pogoDsl:StringType"/>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+      <DefaultPropValue>https://rocket.chat</DefaultPropValue>
+    </deviceProperties>
+    <commands name="State" description="This command gets the device state (stored in its device_state data member) and returns it to the caller." execMethod="dev_state" displayLevel="OPERATOR" polledPeriod="0">
+      <argin description="none">
+        <type xsi:type="pogoDsl:VoidType"/>
+      </argin>
+      <argout description="Device state">
+        <type xsi:type="pogoDsl:StateType"/>
+      </argout>
+      <status abstract="true" inherited="true" concrete="true"/>
+    </commands>
+    <commands name="Status" description="This command gets the device status (stored in its device_status data member) and returns it to the caller." execMethod="dev_status" displayLevel="OPERATOR" polledPeriod="0">
+      <argin description="none">
+        <type xsi:type="pogoDsl:VoidType"/>
+      </argin>
+      <argout description="Device status">
+        <type xsi:type="pogoDsl:ConstStringType"/>
+      </argout>
+      <status abstract="true" inherited="true" concrete="true"/>
+    </commands>
+    <commands name="SendMessage" description="" execMethod="send_message" displayLevel="OPERATOR" polledPeriod="0" isDynamic="false">
+      <argin description="[private_group_name,message]">
+        <type xsi:type="pogoDsl:StringArrayType"/>
+      </argin>
+      <argout description="">
+        <type xsi:type="pogoDsl:VoidType"/>
+      </argout>
+      <status abstract="false" inherited="false" concrete="true" concreteHere="true"/>
+    </commands>
+    <preferences docHome="./doc_html" makefileHome="/usr/share/pogo/preferences"/>
+  </classes>
+</pogoDsl:PogoSystem>
diff --git a/rocketChatLib.py b/rocketChatLib.py
new file mode 100644
index 0000000..1b8465b
--- /dev/null
+++ b/rocketChatLib.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+#pip install --user rocket-python
+
+import subprocess,time,sys
+import datetime
+from rocketchat.api import RocketChatAPI
+from rocketchat.calls.base import RocketChatBase
+import requests
+from xml.etree import ElementTree as ET
+from xml.dom import minidom
+from urllib import unquote
+
+
+class rocketPrivateRoomHistory(RocketChatBase):
+    endpoint = '/api/v1/groups.history'
+
+    def build_endpoint(self, **kwargs):
+        endpointUrl = '{endpoint}?roomId={room_id}'.format(
+                endpoint=self.endpoint,
+                room_id=kwargs.get('room_id')
+            )
+        if 'latest' in kwargs:
+			endpointUrl += '&latest=%s' % kwargs.get('latest')
+        if 'oldest' in kwargs:
+			endpointUrl += '&oldest=%s' % kwargs.get('oldest')
+        if 'count' in kwargs:
+			endpointUrl += '&count=%s' % kwargs.get('count')
+        if 'unreads' in kwargs:
+			endpointUrl += '&unreads=%s' % kwargs.get('unreads')
+        return endpointUrl
+
+    def post_response(self, result):
+        return result
+
+
+class rocketDownloader(RocketChatBase):
+    def call(self, *args, **kwargs):
+        fileurl = kwargs.get('url', None)
+        timeout = kwargs.get('timeout', None)
+        self.method = 'get'
+        url = '{domain}{endpoint}'.format(
+            domain=self.settings['domain'],
+            endpoint= fileurl+ '/?download'
+        )
+        result = requests.request(method=self.method, url=url,
+                                  data=self.build_payload(**kwargs),
+                                  headers=self.headers, timeout=timeout,
+                                  files=self.build_files(**kwargs))
+        request_data = {
+            'url': url,
+            'method': self.method,
+            'payload': self.build_payload(**kwargs),
+            'headers': self.headers,
+            'files': self.files
+        }
+        result.raise_for_status()
+        self.logoff()
+        try:
+            return result
+        except Exception as e:
+            print ('RESTful {classname} call failed. {message}'.format(
+                classname=self.__class__.__name__, message=e))
+            raise e
+
+
+class rocketChat:
+    def __init__(self, usrname, pwd, host):
+		try:
+			self.chat_settings = {}
+			self.chat_settings['username'] = usrname
+			self.chat_settings['password'] = pwd
+			self.chat_settings['domain'] = host
+			self.api = RocketChatAPI(settings = self.chat_settings)
+		except:
+			self.api = None
+
+    def Login(self):
+		dummybase = RocketChatBase(self.api.settings)
+
+    def SendMessage(self, txt, dest):
+		self.api.send_message(str(txt), dest)
+
+
+    def SendFile(self, filepath, dest, mimeType='text/plain',  descr = '', txt = ''):
+		if not dest.startswith('@'):
+			dest = self.api.get_room_id(str(dest))
+		else:
+			print 'Not available at the moment'
+			return
+		self.api.upload_file(room_id=dest,file=str(filepath),description=str(descr),message=str(txt), mime_type=str(mimeType))
+
+
+    def ExportMessages(self, channelName, count_in = 20):
+		if not channelName.startswith('@'):
+			dest = self.api.get_room_id(channelName)
+		else:
+			print 'Not available at the moment'
+			return
+		#print self.api.get_room_history(room_id=dest,oldest='n/a',latest='now')
+		return rocketPrivateRoomHistory(self.api.settings).call(room_id=dest,count=str(count_in))
+
+
+    def DownloadFile(self, url_in):
+		filename = url_in.split('/')[-2] + '_' + url_in.split('/')[-1]
+		pic_url = self.chat_settings['domain'] + '/' + url_in + '/?download'
+		response = rocketDownloader(self.api.settings).call(url=url_in)
+		with open(unquote(filename).decode('utf8'), 'wb') as handle:
+			if not response.ok:
+				print response
+			for block in response.iter_content(1024):
+				if not block:
+					break
+				handle.write(block)
+		return filename
+
diff --git a/rocketchat/__init__.py b/rocketchat/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/rocketchat/api.py b/rocketchat/api.py
new file mode 100644
index 0000000..3103a1c
--- /dev/null
+++ b/rocketchat/api.py
@@ -0,0 +1,310 @@
+from rocketchat.calls.chat.send_message import SendMessage
+from rocketchat.calls.channels.get_public_rooms import GetPublicRooms
+from rocketchat.calls.groups.get_private_rooms import GetPrivateRooms
+from rocketchat.calls.channels.get_room_info import GetRoomInfo
+from rocketchat.calls.groups.get_private_room_info import GetPrivateRoomInfo
+from rocketchat.calls.groups.get_room_id import GetRoomId
+from rocketchat.calls.groups.set_room_topic import SetRoomTopic
+from rocketchat.calls.channels.get_history import GetRoomHistory
+from rocketchat.calls.groups.get_private_room_history import GetPrivateRoomHistory
+from rocketchat.calls.channels.create_public_room import CreatePublicRoom
+from rocketchat.calls.channels.delete_public_room import DeletePublicRoom
+from rocketchat.calls.auth.get_me import GetMe
+from rocketchat.calls.users.get_users import GetUsers
+from rocketchat.calls.users.get_user_info import GetUserInfo
+from rocketchat.calls.users.create_user import CreateUser
+from rocketchat.calls.users.delete_user import DeleteUser
+from rocketchat.calls.groups.upload_file import UploadFile
+from rocketchat.calls.im.create_room import CreateImRoom
+from rocketchat.calls.im.open_room import OpenImRoom
+from rocketchat.calls.im.close_room import CloseImRoom
+from rocketchat.calls.im.get_rooms import GetImRooms
+from rocketchat.calls.im.get_history import GetImRoomHistory
+from datetime import datetime
+
+
+class RocketChatAPI(object):
+    settings = None
+
+    def __init__(self, settings=None, *args, **kwargs):
+        if settings:
+            self.settings = settings
+        else:
+            raise NotImplementedError('You must pass in settings for RocketChat')
+
+    def send_message(self, message, room_id, **kwargs):
+        """
+        Send a message to a given room
+        """
+        return SendMessage(settings=self.settings, **kwargs).call(
+            message=message,
+            room_id=room_id,
+            **kwargs
+        )
+
+    def get_private_rooms(self, **kwargs):
+        """
+        Get a listing of all private rooms with their names and IDs
+        """
+        return GetPrivateRooms(settings=self.settings, **kwargs).call(**kwargs)
+
+    def get_private_room_history(self, room_id, oldest=None, **kwargs):
+        """
+        Get various history of specific private group in this case private
+
+        :param room_id:
+        :param kwargs:
+        :return:
+        """
+        return GetPrivateRoomHistory(settings=self.settings, **kwargs).call(
+            room_id=room_id,
+            oldest=oldest,
+            **kwargs
+        )
+
+    def get_public_rooms(self, **kwargs):
+        """
+        Get a listing of all public rooms with their names and IDs
+        """
+        return GetPublicRooms(settings=self.settings, **kwargs).call(**kwargs)
+
+    def get_room_info(self, room_id, **kwargs):
+        """
+        Get various information about a specific channel/room
+
+        :param room_id:
+        :param kwargs:
+        :return:
+        """
+        return GetRoomInfo(settings=self.settings, **kwargs).call(
+            room_id=room_id,
+            **kwargs
+        )
+
+    def upload_file(self, room_id, description, file, message, mime_type='text/plain', **kwargs):
+        """
+        Upload file to room
+        :param room_id:
+        :param description:
+        :param file:
+        :param kwargs:
+        :return:
+        """
+        return UploadFile(settings=self.settings, **kwargs).call(
+            room_id=room_id,
+            description=description,
+            file=file,
+            message=message,
+            mime_type=mime_type,
+            **kwargs
+        )
+
+    def get_private_room_info(self, room_id, **kwargs):
+        """
+        Get various information about a specific private group
+
+        :param room_id:
+        :param kwargs:
+        :return:
+        """
+        return GetPrivateRoomInfo(settings=self.settings, **kwargs).call(
+            room_id=room_id,
+            **kwargs
+        )
+
+    def get_room_id(self, room_name, **kwargs):
+        """
+        Get room ID
+        :param room_name:
+        :param kwargs:
+        :return:
+        """
+        return GetRoomId(settings=self.settings, **kwargs).call(
+            room_name=room_name,
+            **kwargs
+        )
+
+    def get_room_history(
+                         self,
+                         room_id,
+                         oldest=None,
+                         latest=datetime.now(),
+                         inclusive=False,
+                         count=20,
+                         unreads=False,
+                         **kwargs
+                        ):
+        """
+        Get various history of specific channel/room
+
+        :param room_id:
+        :param kwargs:
+        :return:
+        """
+        return GetRoomHistory(settings=self.settings, **kwargs).call(
+            room_id=room_id,
+            oldest=oldest,
+            latest=latest,
+            inclusive=inclusive,
+            count=count,
+            unreads=unreads,
+            **kwargs
+        )
+
+    def create_public_room(self, name, **kwargs):
+        """
+        Create room with given name
+        :param name: Room name
+        :param kwargs:
+        members: The users to add to the channel when it is created.
+            Optional; Ex.: ["rocket.cat"], Default: []
+        read_only: Set if the channel is read only or not.
+            Optional; Ex.: True, Default: False
+        :return:
+        """
+        return CreatePublicRoom(settings=self.settings, **kwargs).call(name=name, **kwargs)
+
+    def delete_public_room(self, room_id, **kwargs):
+        """
+        Delete room with given ID
+        :param room_id: Room ID
+        :param kwargs:
+        :return:
+        """
+        return DeletePublicRoom(settings=self.settings, **kwargs).call(room_id=room_id, **kwargs)
+
+    def get_my_info(self, **kwargs):
+        return GetMe(settings=self.settings, **kwargs).call(**kwargs)
+
+    def get_users(self, **kwargs):
+        """
+        Gets all of the users in the system and their information
+        :param kwargs:
+        :return:
+        """
+        return GetUsers(settings=self.settings, **kwargs).call(**kwargs)
+
+    def get_user_info(self, user_id, **kwargs):
+        """
+        Retrieves information about a user,
+        the result is only limited to what the callee has access to view.
+        :param user_id:
+        :param kwargs:
+        :return:
+        """
+        return GetUserInfo(settings=self.settings, **kwargs).call(
+            user_id=user_id,
+            **kwargs
+        )
+
+    def create_user(self, email, name, password, username, **kwargs):
+        """
+        Create user
+        :param email: E-mail
+        :param name: Full name
+        :param password: Password
+        :param username: Username
+        :param kwargs:
+        active:
+        roles:
+        join_default_channels:
+        require_password_change:
+        send_welcome_email:
+        verified:
+        custom_fields:
+        :return:
+        """
+        return CreateUser(settings=self.settings, **kwargs).call(
+            email=email,
+            name=name,
+            password=password,
+            username=username,
+            **kwargs
+        )
+
+    def delete_user(self, user_id, **kwargs):
+        """
+        Delete user
+        :param user_id: User ID
+        :param kwargs:
+        :return:
+        """
+        return DeleteUser(settings=self.settings, **kwargs).call(user_id=user_id, **kwargs)
+
+    def set_room_topic(self, room_id, topic, **kwargs):
+        return SetRoomTopic(settings=self.settings, **kwargs).call(
+            room_id=room_id,
+            topic=topic,
+            **kwargs
+        )
+
+    def create_im_room(self, username, **kwargs):
+        """
+        Create direct message room with user
+
+        :param username:
+        :return:
+        """
+        return CreateImRoom(settings=self.settings, **kwargs).call(
+            username=username,
+            **kwargs
+        )
+
+    def open_im_room(self, room_id, **kwargs):
+        """
+        Open direct message room
+
+        :param room_id:
+        :return:
+        """
+        return OpenImRoom(settings=self.settings, **kwargs).call(
+            room_id=room_id,
+            **kwargs
+        )
+
+    def close_im_room(self, room_id, **kwargs):
+        """
+        Close direct message room
+
+        :param room_id:
+        :return:
+        """
+        return CloseImRoom(settings=self.settings, **kwargs).call(
+            room_id=room_id,
+            **kwargs
+        )
+
+    def get_im_rooms(self, **kwargs):
+        """
+        Get direct message rooms
+
+        :return:
+        """
+        return GetImRooms(settings=self.settings, **kwargs).call(**kwargs)
+
+    def get_im_room_history(
+                         self,
+                         room_id,
+                         oldest=None,
+                         latest=datetime.now(),
+                         inclusive=False,
+                         count=20,
+                         unreads=False,
+                         **kwargs
+                        ):
+        """
+        Get various history of specific direct message room
+
+        :param room_id:
+        :param kwargs:
+        :return:
+        """
+        return GetImRoomHistory(settings=self.settings, **kwargs).call(
+            room_id=room_id,
+            oldest=oldest,
+            latest=latest,
+            inclusive=inclusive,
+            count=count,
+            unreads=unreads,
+            **kwargs
+        )
diff --git a/rocketchat/calls/__init__.py b/rocketchat/calls/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/rocketchat/calls/auth/__init__.py b/rocketchat/calls/auth/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/rocketchat/calls/auth/get_me.py b/rocketchat/calls/auth/get_me.py
new file mode 100644
index 0000000..f4f413a
--- /dev/null
+++ b/rocketchat/calls/auth/get_me.py
@@ -0,0 +1,15 @@
+import logging
+
+from rocketchat.calls.base import RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class GetMe(RocketChatBase):
+    endpoint = '/api/v1/me'
+
+    def build_endpoint(self, **kwargs):
+        return self.endpoint
+
+    def post_response(self, result):
+        return result
diff --git a/rocketchat/calls/base.py b/rocketchat/calls/base.py
new file mode 100644
index 0000000..c76960e
--- /dev/null
+++ b/rocketchat/calls/base.py
@@ -0,0 +1,134 @@
+import logging
+import pprint
+import requests
+
+
+logger = logging.getLogger(__name__)
+
+
+class RocketChatBase(object):
+    settings = None
+    endpoint = None
+    headers = {}
+    method = 'get'
+    auth_token = None
+    auth_user_id = None
+    files = None
+
+    def __init__(self, settings=None, *args, **kwargs):
+        self.settings = settings
+
+        # Prepare for a call by fetching an Auth Token
+        self.set_auth_token()
+        self.set_auth_headers()
+
+    def set_auth_token(self):
+        if self.settings.get('token') and self.settings.get('user_id'):
+            self.auth_token = self.settings.get('token')
+            self.auth_user_id = self.settings.get('user_id')
+            return
+
+        url = '{domain}/api/v1/login'.format(
+            domain=self.settings['domain']
+        )
+        response = requests.post(url,
+                                 data={'user': self.settings['username'],
+                                       'password': self.settings['password']})
+
+        try:
+            self.auth_token = response.json()['data']['authToken']
+            self.auth_user_id = response.json()['data']['userId']
+        except KeyError:
+            response.raise_for_status()
+
+    def set_auth_headers(self):
+        self.headers['X-Auth-Token'] = self.auth_token
+        self.headers['X-User-Id'] = self.auth_user_id
+
+    def logoff(self):
+        url = '{domain}/api/v1/logout'.format(
+            domain=self.settings['domain']
+        )
+        requests.get(url, headers=self.headers)
+
+    def post_response(self, result):
+        return result
+
+    def build_endpoint(self, **kwargs):
+        """
+        Build the endpoint for the user given some kwargs
+        from the initial calling.
+
+        :return:
+        """
+
+        raise NotImplementedError()
+
+    def build_payload(self, **kwargs):
+        """
+        Build a payload dict that will be passed directly to the
+        endpoint.  If you need to pass this as plain text or whatever
+        you'll need to the dumping here.
+
+        :return:
+        """
+
+        return None
+
+    def build_files(self, **kwargs):
+        """
+        Build files
+        :param kwargs:
+        :return:
+        """
+        return None
+
+    def call(self, *args, **kwargs):
+        """
+
+        :param args:
+        :param kwargs:
+        :return:
+        """
+
+        timeout = kwargs.get('timeout', None)
+        url = '{domain}{endpoint}'.format(
+            domain=self.settings['domain'],
+            endpoint=self.build_endpoint(**kwargs)
+        )
+
+        result = requests.request(method=self.method, url=url,
+                                  data=self.build_payload(**kwargs),
+                                  headers=self.headers, timeout=timeout,
+                                  files=self.build_files(**kwargs))
+
+        request_data = {
+            'url': url,
+            'method': self.method,
+            'payload': self.build_payload(**kwargs),
+            'headers': self.headers,
+            'files': self.files
+        }
+
+        logger.debug('API Request - {request}'.format(
+            request=pprint.pformat(request_data)
+        ))
+
+        result.raise_for_status()
+        self.logoff()
+
+        try:
+            logger.debug('API Response - {data}'.format(
+                data=pprint.pformat(result.json())
+            ))
+            return self.post_response(result.json())
+
+        except Exception as e:
+            logger.error('RESTful {classname} call failed. {message}'.format(
+                classname=self.__class__.__name__, message=e),
+                exc_info=True)
+            raise e
+
+
+class PostMixin(object):
+    method = 'post'
diff --git a/rocketchat/calls/channels/__init__.py b/rocketchat/calls/channels/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/rocketchat/calls/channels/create_public_room.py b/rocketchat/calls/channels/create_public_room.py
new file mode 100644
index 0000000..419069b
--- /dev/null
+++ b/rocketchat/calls/channels/create_public_room.py
@@ -0,0 +1,23 @@
+import logging
+import json
+
+from rocketchat.calls.base import PostMixin, RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class CreatePublicRoom(PostMixin, RocketChatBase):
+    endpoint = '/api/v1/channels.create'
+
+    def build_endpoint(self, **kwargs):
+        return self.endpoint
+
+    def build_payload(self, **kwargs):
+        return json.dumps({
+                'name': kwargs.get('name'),
+                'members': kwargs.get('members', []),
+                'readOnly': kwargs.get('read_only', False)
+        })
+
+    def post_response(self, result):
+        return result
diff --git a/rocketchat/calls/channels/delete_public_room.py b/rocketchat/calls/channels/delete_public_room.py
new file mode 100644
index 0000000..b12c62a
--- /dev/null
+++ b/rocketchat/calls/channels/delete_public_room.py
@@ -0,0 +1,21 @@
+import logging
+import json
+
+from rocketchat.calls.base import PostMixin, RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class DeletePublicRoom(PostMixin, RocketChatBase):
+    endpoint = '/api/v1/channels.delete'
+
+    def build_endpoint(self, **kwargs):
+        return self.endpoint
+
+    def build_payload(self, **kwargs):
+        return json.dumps({
+            'roomId': kwargs.get('room_id')
+        })
+
+    def post_response(self, result):
+        return result
diff --git a/rocketchat/calls/channels/get_history.py b/rocketchat/calls/channels/get_history.py
new file mode 100644
index 0000000..01b91c7
--- /dev/null
+++ b/rocketchat/calls/channels/get_history.py
@@ -0,0 +1,24 @@
+import logging
+
+from rocketchat.calls.base import RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class GetRoomHistory(RocketChatBase):
+    endpoint = '/api/v1/channels.history'
+
+    def build_endpoint(self, **kwargs):
+        return '{endpoint}?roomId={room_id}&oldest={oldest}&inclusive={inclusive}'\
+                '&count={count}&unreads={unreads}&latest={latest}'.format(
+                 endpoint=self.endpoint,
+                 oldest=kwargs.get('oldest'),
+                 room_id=kwargs.get('room_id'),
+                 inclusive=kwargs.get('inclusive'),
+                 count=kwargs.get('count'),
+                 unreads=kwargs.get('unreads'),
+                 latest=kwargs.get('latest')
+                )
+
+    def post_response(self, result):
+        return result
diff --git a/rocketchat/calls/channels/get_public_rooms.py b/rocketchat/calls/channels/get_public_rooms.py
new file mode 100644
index 0000000..67b6031
--- /dev/null
+++ b/rocketchat/calls/channels/get_public_rooms.py
@@ -0,0 +1,31 @@
+import logging
+
+from rocketchat.calls.base import RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class GetPublicRooms(RocketChatBase):
+    endpoint = '/api/v1/channels.list'
+
+    def build_endpoint(self):
+        return self.endpoint
+
+    def post_response(self, result):
+        rooms = []
+
+        try:
+            _rooms = result.get('channels')
+
+            for room in _rooms:
+                room_dict = {}
+                room_dict['name'] = room.get('name')
+                room_dict['id'] = room.get('_id')
+                rooms.append(room_dict)
+
+        except Exception as e:
+            logger.error('Exception in fetching public rooms {e}'.format(
+                e=e
+            ), exc_info=True)
+
+        return rooms
diff --git a/rocketchat/calls/channels/get_room_info.py b/rocketchat/calls/channels/get_room_info.py
new file mode 100644
index 0000000..e541841
--- /dev/null
+++ b/rocketchat/calls/channels/get_room_info.py
@@ -0,0 +1,18 @@
+import logging
+
+from rocketchat.calls.base import RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class GetRoomInfo(RocketChatBase):
+    endpoint = '/api/v1/channels.info'
+
+    def build_endpoint(self, **kwargs):
+        return '{endpoint}?roomId={room_id}'.format(
+            endpoint=self.endpoint,
+            room_id=kwargs.get('room_id')
+        )
+
+    def post_response(self, result):
+        return result
diff --git a/rocketchat/calls/chat/__init__.py b/rocketchat/calls/chat/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/rocketchat/calls/chat/send_message.py b/rocketchat/calls/chat/send_message.py
new file mode 100644
index 0000000..3180dc1
--- /dev/null
+++ b/rocketchat/calls/chat/send_message.py
@@ -0,0 +1,11 @@
+from rocketchat.calls.base import PostMixin, RocketChatBase
+
+
+class SendMessage(PostMixin, RocketChatBase):
+    endpoint = '/api/v1/chat.postMessage'
+
+    def build_endpoint(self, **kwargs):
+        return self.endpoint
+
+    def build_payload(self, **kwargs):
+        return {'text': kwargs.get('message'), 'roomId': kwargs.get('room_id')}
diff --git a/rocketchat/calls/groups/__init__.py b/rocketchat/calls/groups/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/rocketchat/calls/groups/get_private_room_history.py b/rocketchat/calls/groups/get_private_room_history.py
new file mode 100644
index 0000000..ffb80b5
--- /dev/null
+++ b/rocketchat/calls/groups/get_private_room_history.py
@@ -0,0 +1,25 @@
+import logging
+
+from rocketchat.calls.base import RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class GetPrivateRoomHistory(RocketChatBase):
+    endpoint = '/api/v1/groups.history'
+
+    def build_endpoint(self, **kwargs):
+        if 'oldest' in kwargs:
+            return '{endpoint}?roomId={room_id}&oldest={oldest}'.format(
+                endpoint=self.endpoint,
+                oldest=kwargs.get('oldest'),
+                room_id=kwargs.get('room_id')
+            )
+        else:
+            return '{endpoint}?roomId={room_id}'.format(
+                endpoint=self.endpoint,
+                room_id=kwargs.get('room_id')
+            )
+
+    def post_response(self, result):
+        return result
diff --git a/rocketchat/calls/groups/get_private_room_info.py b/rocketchat/calls/groups/get_private_room_info.py
new file mode 100644
index 0000000..8fc0c63
--- /dev/null
+++ b/rocketchat/calls/groups/get_private_room_info.py
@@ -0,0 +1,18 @@
+import logging
+
+from rocketchat.calls.base import RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class GetPrivateRoomInfo(RocketChatBase):
+    endpoint = '/api/v1/groups.info'
+
+    def build_endpoint(self, **kwargs):
+        return '{endpoint}?roomId={room_id}'.format(
+            endpoint=self.endpoint,
+            room_id=kwargs.get('room_id')
+        )
+
+    def post_response(self, result):
+        return result
diff --git a/rocketchat/calls/groups/get_private_rooms.py b/rocketchat/calls/groups/get_private_rooms.py
new file mode 100644
index 0000000..5f649bc
--- /dev/null
+++ b/rocketchat/calls/groups/get_private_rooms.py
@@ -0,0 +1,31 @@
+import logging
+
+from rocketchat.calls.base import RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class GetPrivateRooms(RocketChatBase):
+    endpoint = '/api/v1/groups.list'
+
+    def build_endpoint(self):
+        return self.endpoint
+
+    def post_response(self, result):
+        rooms = []
+
+        try:
+            _rooms = result.get('groups')
+
+            for room in _rooms:
+                room_dict = {}
+                room_dict['name'] = room.get('name')
+                room_dict['id'] = room.get('_id')
+                rooms.append(room_dict)
+
+        except Exception as e:
+            logger.error('Exception in fetching private rooms {e}'.format(
+                e=e
+            ), exc_info=True)
+
+        return rooms
diff --git a/rocketchat/calls/groups/get_room_id.py b/rocketchat/calls/groups/get_room_id.py
new file mode 100644
index 0000000..a956ec8
--- /dev/null
+++ b/rocketchat/calls/groups/get_room_id.py
@@ -0,0 +1,20 @@
+import logging
+
+from rocketchat.calls.base import RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class GetRoomId(RocketChatBase):
+    endpoint = '/api/v1/groups.info'
+
+    def build_endpoint(self, **kwargs):
+
+        return '{endpoint}?roomName={room_name}'.format(
+            endpoint=self.endpoint,
+            room_name=kwargs.get('room_name')
+        )
+
+    def post_response(self, result):
+        # print(result['group']['_id'])
+        return result['group']['_id']
diff --git a/rocketchat/calls/groups/set_room_topic.py b/rocketchat/calls/groups/set_room_topic.py
new file mode 100644
index 0000000..76dcaab
--- /dev/null
+++ b/rocketchat/calls/groups/set_room_topic.py
@@ -0,0 +1,21 @@
+import logging
+
+from rocketchat.calls.base import PostMixin, RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class SetRoomTopic(PostMixin, RocketChatBase):
+    endpoint = '/api/v1/groups.setTopic'
+
+    def build_endpoint(self, **kwargs):
+        return self.endpoint
+
+    def build_payload(self, **kwargs):
+        return {
+            'topic': kwargs.get('topic'),
+            'roomId': kwargs.get('room_id')
+        }
+
+    def post_response(self, result):
+        return result['success']
diff --git a/rocketchat/calls/groups/upload_file.py b/rocketchat/calls/groups/upload_file.py
new file mode 100644
index 0000000..0ec611e
--- /dev/null
+++ b/rocketchat/calls/groups/upload_file.py
@@ -0,0 +1,23 @@
+import logging
+
+from rocketchat.calls.base import RocketChatBase, PostMixin, logger
+logger.setLevel(logging.DEBUG)
+
+
+class UploadFile(PostMixin, RocketChatBase):
+    endpoint = '/api/v1/rooms.upload'
+
+    def build_endpoint(self, **kwargs):
+        return '{endpoint}/{room_id}'.format(endpoint=self.endpoint,
+                                             room_id=kwargs.get('room_id'))
+
+    def build_files(self, **kwargs):
+        return {'file': (kwargs.get('file'),
+                         open(kwargs.get('file'), 'rb'),
+                         kwargs.get('mime_type'))}
+
+    def build_payload(self, **kwargs):
+        return {'description': kwargs.get('description'), 'msg': kwargs.get('message')}
+
+    def post_response(self, result):
+        return result
diff --git a/rocketchat/calls/im/__init__.py b/rocketchat/calls/im/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/rocketchat/calls/im/close_room.py b/rocketchat/calls/im/close_room.py
new file mode 100644
index 0000000..1423217
--- /dev/null
+++ b/rocketchat/calls/im/close_room.py
@@ -0,0 +1,19 @@
+import json
+import logging
+
+from rocketchat.calls.base import PostMixin, RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class CloseImRoom(PostMixin, RocketChatBase):
+    endpoint = "/api/v1/im.create"
+
+    def build_endpoint(self, **kwargs):
+        return self.endpoint
+
+    def build_payload(self, **kwargs):
+        return json.dumps({"roomId": kwargs.get("room_id")})
+
+    def post_response(self, result):
+        return result
diff --git a/rocketchat/calls/im/create_room.py b/rocketchat/calls/im/create_room.py
new file mode 100644
index 0000000..17af901
--- /dev/null
+++ b/rocketchat/calls/im/create_room.py
@@ -0,0 +1,34 @@
+import json
+import logging
+
+from rocketchat.calls.base import PostMixin, RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class CreateImRoom(PostMixin, RocketChatBase):
+    endpoint = "/api/v1/im.create"
+
+    def build_endpoint(self, **kwargs):
+        return self.endpoint
+
+    def build_payload(self, **kwargs):
+        return json.dumps({"username": kwargs.get("username")})
+
+    def post_response(self, result):
+        try:
+            _room = result.get('room')
+            room_dict = dict()
+            room_dict['id'] = _room.get('_id')
+
+            for username in _room.get("usernames"):
+                if username != self.settings["username"]:
+                    room_dict['username'] = username
+                    break
+
+        except Exception as e:
+            logger.error('Exception in creating im rooms {e}'.format(
+                e=e
+            ), exc_info=True)
+
+        return room_dict
diff --git a/rocketchat/calls/im/get_history.py b/rocketchat/calls/im/get_history.py
new file mode 100644
index 0000000..8535b9d
--- /dev/null
+++ b/rocketchat/calls/im/get_history.py
@@ -0,0 +1,47 @@
+import logging
+
+from rocketchat.calls.base import RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class GetImRoomHistory(RocketChatBase):
+    endpoint = '/api/v1/im.history'
+
+    def build_endpoint(self, **kwargs):
+        return '{endpoint}?roomId={room_id}&oldest={oldest}&inclusive={inclusive}'\
+                '&count={count}&unreads={unreads}&latest={latest}'.format(
+                 endpoint=self.endpoint,
+                 oldest=kwargs.get('oldest'),
+                 room_id=kwargs.get('room_id'),
+                 inclusive=kwargs.get('inclusive'),
+                 count=kwargs.get('count'),
+                 unreads=kwargs.get('unreads'),
+                 latest=kwargs.get('latest')
+                )
+
+    def post_response(self, result):
+        messages = []
+
+        try:
+            _messages = result.get('messages')
+
+            for msg in _messages:
+                msg_dict = dict()
+                msg_dict['msg'] = msg.get('msg')
+                msg_dict['room_id'] = msg.get('rid')
+                msg_dict['ts'] = msg.get('ts')
+                msg_dict['user'] = {
+                    'id': msg.get('u', {}).get('_id'),
+                    'username': msg.get('u', {}).get('username'),
+                }
+                msg_dict['id'] = msg.get('_id')
+
+                messages.append(msg_dict)
+
+        except Exception as e:
+            logger.error('Exception in fetching direct message rooms {e}'.format(
+                e=e
+            ), exc_info=True)
+
+        return messages
diff --git a/rocketchat/calls/im/get_rooms.py b/rocketchat/calls/im/get_rooms.py
new file mode 100644
index 0000000..1f9236b
--- /dev/null
+++ b/rocketchat/calls/im/get_rooms.py
@@ -0,0 +1,39 @@
+import logging
+
+from rocketchat.calls.base import RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class GetImRooms(RocketChatBase):
+    endpoint = "/api/v1/im.list"
+
+    def build_endpoint(self):
+        return self.endpoint
+
+    def post_response(self, result):
+        rooms = []
+
+        try:
+            _rooms = result.get("ims")
+
+            for room in _rooms:
+                if not room.get("usernames"):
+                    continue
+
+                for username in room.get("usernames"):
+                    if username != self.settings["username"]:
+                        break
+
+                room_dict = {}
+                room_dict["username"] = username
+                room_dict["id"] = room.get("_id")
+                rooms.append(room_dict)
+
+        except Exception as e:
+            logger.error(
+                "Exception in fetching im rooms {e}".format(e=e),
+                exc_info=True,
+            )
+
+        return rooms
diff --git a/rocketchat/calls/im/open_room.py b/rocketchat/calls/im/open_room.py
new file mode 100644
index 0000000..88957c0
--- /dev/null
+++ b/rocketchat/calls/im/open_room.py
@@ -0,0 +1,19 @@
+import json
+import logging
+
+from rocketchat.calls.base import PostMixin, RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class OpenImRoom(PostMixin, RocketChatBase):
+    endpoint = "/api/v1/im.create"
+
+    def build_endpoint(self, **kwargs):
+        return self.endpoint
+
+    def build_payload(self, **kwargs):
+        return json.dumps({"roomId": kwargs.get("room_id")})
+
+    def post_response(self, result):
+        return result
diff --git a/rocketchat/calls/users/__init__.py b/rocketchat/calls/users/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/rocketchat/calls/users/create_user.py b/rocketchat/calls/users/create_user.py
new file mode 100644
index 0000000..43c7e85
--- /dev/null
+++ b/rocketchat/calls/users/create_user.py
@@ -0,0 +1,31 @@
+import logging
+import json
+
+from rocketchat.calls.base import PostMixin, RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class CreateUser(PostMixin, RocketChatBase):
+    endpoint = '/api/v1/users.create'
+
+    def build_endpoint(self, **kwargs):
+        return self.endpoint
+
+    def build_payload(self, **kwargs):
+        return json.dumps({
+            'email': kwargs.get('email'),
+            'name': kwargs.get('name'),
+            'password': kwargs.get('password'),
+            'username': kwargs.get('username'),
+            'active': kwargs.get('active', True),
+            'roles': kwargs.get('roles', ['user']),
+            'joinDefaultChannels': kwargs.get('join_default_channels', True),
+            'requirePasswordChange': kwargs.get('require_password_change', False),
+            'sendWelcomeEmail': kwargs.get('send_welcome_email', False),
+            'verified': kwargs.get('verified', False),
+            'customFields': kwargs.get('customFields', {})
+        })
+
+    def post_response(self, result):
+        return result
diff --git a/rocketchat/calls/users/delete_user.py b/rocketchat/calls/users/delete_user.py
new file mode 100644
index 0000000..b25455b
--- /dev/null
+++ b/rocketchat/calls/users/delete_user.py
@@ -0,0 +1,21 @@
+import logging
+import json
+
+from rocketchat.calls.base import PostMixin, RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class DeleteUser(PostMixin, RocketChatBase):
+    endpoint = '/api/v1/users.delete'
+
+    def build_endpoint(self, **kwargs):
+        return self.endpoint
+
+    def build_payload(self, **kwargs):
+        return json.dumps({
+            'userId': kwargs.get('user_id')
+        })
+
+    def post_response(self, result):
+        return result
diff --git a/rocketchat/calls/users/get_user_info.py b/rocketchat/calls/users/get_user_info.py
new file mode 100644
index 0000000..d056df1
--- /dev/null
+++ b/rocketchat/calls/users/get_user_info.py
@@ -0,0 +1,19 @@
+import logging
+
+
+from rocketchat.calls.base import RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class GetUserInfo(RocketChatBase):
+    endpoint = '/api/v1/users.info'
+
+    def build_endpoint(self, **kwargs):
+        return '{endpoint}?userId={room_id}'.format(
+            endpoint=self.endpoint,
+            room_id=kwargs.get('user_id')
+        )
+
+    def post_response(self, result):
+        return result
diff --git a/rocketchat/calls/users/get_users.py b/rocketchat/calls/users/get_users.py
new file mode 100644
index 0000000..bcc51c2
--- /dev/null
+++ b/rocketchat/calls/users/get_users.py
@@ -0,0 +1,37 @@
+import logging
+
+
+from rocketchat.calls.base import RocketChatBase
+
+logger = logging.getLogger(__name__)
+
+
+class GetUsers(RocketChatBase):
+    endpoint = '/api/v1/users.list'
+
+    def build_endpoint(self):
+        return self.endpoint
+
+    def post_response(self, result):
+        users = []
+
+        try:
+            _users = result.get('users')
+
+            for user in _users:
+                user_dict = dict()
+                user_dict['name'] = user.get('name')
+                user_dict['emails'] = [email['address'] for email in user.get('emails')]
+                user_dict['username'] = user.get('username')
+                user_dict['type'] = user.get('type')
+                user_dict['status'] = user.get('status')
+                user_dict['roles'] = user.get('roles')
+                user_dict['id'] = user.get('_id')
+                users.append(user_dict)
+
+        except Exception as e:
+            logger.error('Exception in fetching public rooms {e}'.format(
+                e=e
+            ), exc_info=True)
+
+        return users
-- 
GitLab