shellbot.spaces package¶
Submodules¶
Module contents¶
-
class
shellbot.spaces.
SpaceFactory
[source]¶ Bases:
object
Builds a space from configuration
Example:
my_context = Context(settings={ 'space': { 'type': "spark", 'room': 'My preferred room', 'participants': ['alan.droit@azerty.org', 'bob.nard@support.tv'], 'team': 'Anchor team', 'token': 'hkNWEtMJNkODk3ZDZLOGQ0OVGlZWU1NmYtyY', 'fuzzy_token': '$MY_FUZZY_SPARK_TOKEN', } }) space = SpaceFactory.build(context=my_context)
-
classmethod
build
(context, **kwargs)[source]¶ Builds an instance based on provided configuration
Parameters: context (Context) – configuration to be used Returns: a ready-to-use space Return type: Space This function “senses” for a type in the context itself, then provides with an instantiated object of this type.
A
ValueError
is raised when no type can be identified.
-
classmethod
get
(type, **kwargs)[source]¶ Loads a space by type
Parameters: type (str) – the required space Returns: a space instance This function seeks for a suitable space class in the library, and returns an instance of it.
Example:
space = SpaceFactory.get('spark', ex_token='123')
A
ValueError
is raised if the type is unknown.
-
classmethod
sense
(context)[source]¶ Detects type from configuration
Parameters: context (Context) – configuration to be analyzed Returns: a guessed type Return type: str Example:
type = SpaceFactory.sense(context)
A
ValueError
is raised if no type could be identified.
-
types
= {'spark': <class 'shellbot.spaces.ciscospark.SparkSpace'>, 'local': <class 'shellbot.spaces.local.LocalSpace'>, 'space': <class 'shellbot.spaces.base.Space'>}¶
-
classmethod
-
class
shellbot.spaces.
Space
(context=None, ears=None, fan=None, **kwargs)[source]¶ Bases:
object
Handles a collaborative space
A collaborative space supports multiple channels for interactions between persons and bots.
The life cycle of a space can be described as follows:
A space instance is created and configured:
>>>my_context = Context(...) >>>space = Space(context=my_context)
The space is connected to some back-end API:
space.connect()
Multiple channels can be handled by a single space:
channel = space.create(title) channel = space.get_by_title(title) channel = space.get_by_id(id) channel = space.get_by_person(label) channel.title = 'A new title' space.update(channel) space.delete(id)
Channels feature common attributes, yet can be extended to convey specificities of some platforms.
Messages can be posted:
space.post_message(id, 'Hello, World!') # for group channels space.post_message(person, 'Hello, World!') # for direct messages
You can add and remove participants to channels:
persons = space.list_participant(id) space.add_participants(id, persons) space.add_participant(id, person) space.remove_participants(id, persons) space.remove_participant(id, person)
Multiple modes can be considered for the handling of inbound events from the cloud.
Asynchronous reception - the back-end API sends updates over a web hook to this object, and messages are pushed to the listening queue.
Example:
# link local web server to this space server.add_route('/hook', space.webhook) # link cloud service to this local server space.register('http://my.server/hook')
Background loop - this object pulls the API in a loop, and new messages are pushed to the listening queue.
Example:
space.run()
-
DEFAULT_SETTINGS
= {'server': {'url': '$SERVER_URL', 'hook': '/hook', 'binding': None, 'port': 8080}, 'space': {'type': 'local', 'title': '$CHAT_ROOM_TITLE'}}¶
-
DEFAULT_SPACE_TITLE
= u'Collaboration space'¶
-
PULL_INTERVAL
= 0.05¶
-
add_participant
(id, person, is_moderator=False)[source]¶ Adds one participant
Parameters: - id (str) – the unique id of an existing channel
- person (str) – e-mail address of the person to add
- is_moderator (True or False) – if this person has special powers on this channel
The underlying platform may, or not, take the optional parameter
is_moderator
into account. The default bahaviour is to discard it, as if the parameter had the valueFalse
.This function should be implemented in sub-class. It should not raise exceptions, since this would kill
list_participants()
.Example:
@no_exception def add_participant(self, id, person): self.api.memberships.create(id=id, person=person)
-
add_participants
(id, persons=[])[source]¶ Adds multiple participants
Parameters: - id (str) – the unique id of an existing channel
- persons (list of str) – e-mail addresses of persons to add
-
check
()[source]¶ Checks settings
This function should be expanded in sub-class, where necessary.
Example:
def check(self): self.engine.context.check('space.title', is_mandatory=True)
-
configure
(settings={})[source]¶ Changes settings of the space
Parameters: settings (dict) – a dictionary with some statements for this instance After a call to this function,
bond()
has to be invoked to return to normal mode of operation.
-
configured_title
()[source]¶ Returns the title of the space as set in configuration
Returns: the configured title, or Collaboration space
Return type: str This function should be rewritten in sub-classes if space title does not come from
space.title
parameter.
-
connect
(**kwargs)[source]¶ Connects to the back-end API
This function should be expanded in sub-class, where required.
Example:
def connect(self, **kwargs): self.api = ApiFactory(self.token)
-
create
(title, **kwargs)[source]¶ Creates a channel
Parameters: title (str) – title of a new channel Returns: Channel This function returns a representation of the new channel on success, else it should raise an exception.
This function should be implemented in sub-class.
Example:
def create(self, title=None, **kwargs): handle = self.api.rooms.create(title=title) return Channel(handle.attributes)
-
delete
(id, **kwargs)[source]¶ Deletes a channel
Parameters: id (str) – the unique id of an existing channel After a call to this function the related channel does not appear anymore in the list of available resources in the chat space. This can be implemented in the back-end either by actual deletion of resources, or by archiving the channel. In the second scenario, the channel could be restored at a later stage if needed.
This function should be implemented in sub-class.
Example:
def delete(self, id=id, **kwargs): self.api.rooms.delete(id)
-
deregister
()[source]¶ Stops updates from the cloud back-end
This function should be implemented in sub-class.
-
get_by_id
(id, **kwargs)[source]¶ Looks for an existing channel by id
Parameters: id (str) – id of the target channel Returns: Channel instance or None If a channel already exists with this id, a representation of it is returned. Else the value ``None``is returned.
This function should be implemented in sub-class.
Example:
def get_by_id(self, id, **kwargs): handle = self.api.rooms.lookup(id=id) if handle: return Channel(handle.attributes)
-
get_by_person
(label, **kwargs)[source]¶ Looks for an existing private channel with a person
Parameters: label (str) – the display name of the person’s account Returns: Channel instance or None If a channel already exists for this person, a representation of it is returned. Else the value ``None``is returned.
This function should be implemented in sub-class.
Example:
def get_by_id(self, id, **kwargs): handle = self.api.rooms.lookup(id=id) if handle: return Channel(handle.attributes)
-
get_by_title
(title=None, **kwargs)[source]¶ Looks for an existing space by title
Parameters: title (str) – title of the target channel Returns: Channel instance or None If a channel already exists with this id, a representation of it is returned. Else the value ``None``is returned.
This function should be implemented in sub-class.
Example:
def get_by_title(self, title, **kwargs): for handle in self.api.rooms.list() if handle.title == title: return Channel(handle.attributes)
-
list_group_channels
(**kwargs)[source]¶ Lists available channels
Returns: list of Channel This function should be implemented in sub-class.
Example:
def list_group_channels(self, **kwargs): for handle in self.api.rooms.list(type='group'): yield Channel(handle.attributes)
-
list_messages
(id=None, quantity=10, stop_id=None, up_to=None, with_attachment=False, **kwargs)[source]¶ List messages
Parameters: - id (str) – the unique id of an existing channel
- quantity (positive integer) – maximum number of returned messages
- stop_id (str) – stop on this message id, and do not include it
- up_to (str of ISO date and time) – stop on this date and time
- with_attachment (True or False) – to get only messages with some attachments
Returns: a list of Message objects
This function fetches messages from one channel, from newest to the oldest. Compared to the bare
walk_messages
function, it brings additional capabilities listed below:- quantity - limit the maximum number of messages provided
- stop_id - get new messages since the latest we got
- up_to - get messages up a given date and time
- with_attachments - filter messages to retrieve attachments
Example:
for message in space.list_messages(id=channel_id): do_something_with_message(message) if message.url: do_something_with_attachment(message.url)
-
list_participants
(id)[source]¶ Lists participants to a channel
Parameters: id (str) – the unique id of an existing channel Returns: a list of persons Return type: list of str Note: this function returns all participants, except the bot itself.
-
on_init
(**kwargs)[source]¶ Handles extended initialisation parameters
This function should be expanded in sub-class, where necessary.
Example:
def on_init(self, ex_parameter='extra', **kwargs): ...
-
on_start
()[source]¶ Reacts when engine is started
This function should be expanded in sub-class, where necessary.
Example:
def on_start(self): self.load_cache_from_db()
-
on_stop
()[source]¶ reacts when engine is stopped
This function attempts to deregister webhooks, if any. This behaviour can be expanded in sub-class, where necessary.
-
post_message
(id=None, text=None, content=None, file=None, person=None, **kwargs)[source]¶ Posts a message
Parameters: - id (str) – the unique id of an existing channel
- person (str) – address for a direct message
- text (str) – message in plain text
- content (str) – rich format, such as Markdown or HTML
- file (str) – URL or local path for an attachment
Example message out of plain text:
space.post_message(id=id, text='hello world')
Example message with Markdown:
space.post_message(id, content='this is a **bold** statement')
Example file upload:
space.post_message(id, file='./my_file.pdf')
Of course, you can combine text with the upload of a file:
text = 'This is the presentation that was used for our meeting' space.post_message(id=id, text=text, file='./my_file.pdf')
For direct messages, provide who you want to reach instead of a channel id, like this:
space.post_message(person='foo.bar@acme.com', text='hello guy')
This function should be implemented in sub-class.
Example:
def post_message(self, id, text=None, **kwargs): self.api.messages.create(id=id, text=text)
-
pull
()[source]¶ Fetches updates
This function senses most recent items, and pushes them to the listening queue.
This function should be implemented in sub-class.
Example:
def pull(self): for message in self.api.list_message(): self.ears.put(message)
-
register
(hook_url)[source]¶ Registers to the cloud API for the reception of updates
Parameters: hook_url (str) – web address to be used by cloud service This function should be implemented in sub-class.
Example:
def register(self, hook_url): self.api.register(hook_url)
-
remove_participant
(id, person)[source]¶ Removes one participant
Parameters: - id (str) – the unique id of an existing channel
- person (str) – e-mail address of the person to delete
This function should be implemented in sub-class. It should not raise exceptions, since this would kill
remove_participants()
.Example:
@no_exception def remove_participant(self, id, person): self.api.memberships.delete(id=id, person=person)
-
remove_participants
(id, persons=[])[source]¶ Removes multiple participants
Parameters: - id (str) – the unique id of an existing channel
- persons (list of str) – e-mail addresses of persons to delete
-
run
()[source]¶ Continuously fetches updates
This function senses new items at regular intervals, and pushes them to the listening queue.
Processing is handled in a separate background process, like in the following example:
# gets updates in the background process = space.start() ... # wait for the end of the process process.join()
The recommended way for stopping the process is to change the parameter
general.switch
in the context. For example:engine.set('general.switch', 'off')
Note: this function should not be invoked if a webhok has been configured.
-
start
(hook_url=None)[source]¶ Starts the update process
Parameters: hook_url (str) – web address to be used by cloud service (optional) Returns: either the process that has been started, or None If an URL is provided, it is communicated to the back-end API for asynchronous updates.
Else this function starts a separate daemonic process to pull updates in the background.
-
update
(channel, **kwargs)[source]¶ Updates an existing channel
Parameters: channel (Channel) – a representation of the updated channel This function should raise an exception when the update is not successful.
This function should be implemented in sub-class.
Example:
def update(self, channel): self.api.rooms.update(channel.attributes)
-
walk_messages
(id=None, **kwargs)[source]¶ Walk messages
Parameters: id (str) – the unique id of an existing channel Returns: a iterator of Message objects This function returns messages from a channel, from the newest to the oldest.
This function should be implemented in sub-class
-
webhook
()[source]¶ Handles updates sent over the internet
This function should use the
request
object to retrieve details of the web transaction.This function should be implemented in sub-class.
Example:
def webhook(self): message_id = request.json['data']['id'] item = self.api.messages.get(messageId=message_id) self.ears.put(item._json) return "OK"
-
class
shellbot.spaces.
LocalSpace
(context=None, ears=None, fan=None, **kwargs)[source]¶ Bases:
shellbot.spaces.base.Space
Handles chat locally
This class allows developers to test their commands interface locally, without the need for a real API back-end.
If a list of commands is provided as input, then the space will consume all of them and then it will stop. All kinds of automated tests and scenarios can be build with this approach.
Example of automated interaction with some commands:
engine = Engine(command=Hello(), type='local') engine.space.push(['help', 'hello', 'help help']) engine.configure() engine.run()
If no input is provided, then the space provides a command-line interface so that you can play interactively with your bot. This setup is handy since it does not require access to a real chat back-end.
-
DEFAULT_PROMPT
= u'> '¶
-
add_participant
(id, person, is_moderator=False)[source]¶ Adds one participant
Parameters: - id (str) – the unique id of an existing channel
- person (str) – e-mail address of the person to add
- is_moderator (True or False) – if this person has special powers on this channel
-
check
()[source]¶ Check settings
This function reads key
local
and below, and update the context accordingly.This function also selects the right input for this local space. If some content has been provided during initialisation, it is used to simulate user input. Else stdin is read one line at a time.
-
create
(title, **kwargs)[source]¶ Creates a channel
Parameters: title (str) – title of a new channel Returns: Channel This function returns a representation of the local channel.
-
delete
(id, **kwargs)[source]¶ Deletes a channel
Parameters: id (str) – the unique id of an existing channel
-
get_by_id
(id, **kwargs)[source]¶ Looks for an existing channel by id
Parameters: id (str) – identifier of the target channel Returns: Channel instance or None
-
get_by_title
(title, **kwargs)[source]¶ Looks for an existing channel by title
Parameters: title (str) – title of the target channel Returns: Channel instance or None
-
list_participants
(id)[source]¶ Lists participants to a channel
Parameters: id (str) – the unique id of an existing channel Returns: a list of persons Return type: list of str Note: this function returns all participants, except the bot itself.
-
on_init
(input=None, **kwargs)[source]¶ Handles extended initialisation parameters
Parameters: input (str or list of str) – Lines of text to be submitted to the chat Example:
space = LocalSpace(input='hello world')
Here we create a new local space, and simulate a user typing ‘hello world’ in the chat space.
-
on_message
(item, queue)[source]¶ Normalizes message for the listener
Parameters: - item (dict) – attributes of the inbound message
- queue (Queue) – the processing queue
This function prepares a Message and push it to the provided queue.
-
post_message
(id=None, text=None, content=None, file=None, person=None, **kwargs)[source]¶ Posts a message
Parameters: - id (str) – the unique id of an existing channel
- person (str) – address for a direct message
- text (str) – message in plain text
- content (str) – rich format, such as MArkdown or HTML
- file (str) – URL or local path for an attachment
-
pull
()[source]¶ Fetches updates
This function senses most recent item, and pushes it to the listening queue.
-
push
(input)[source]¶ Adds more input to this space
Parameters: input (str or list of str) – Simulated user input This function is used to simulate input user to the bot.
-
remove_participant
(id, person)[source]¶ Removes one participant
Parameters: - id (str) – the unique id of an existing channel
- person (str) – e-mail address of the person to remove
-
-
class
shellbot.spaces.
SparkSpace
(context=None, ears=None, fan=None, **kwargs)[source]¶ Bases:
shellbot.spaces.base.Space
Handles a Cisco Spark room
This is a representation of a chat space hosted at Cisco Spark.
-
DEFAULT_SETTINGS
= {'server': {'url': '$SERVER_URL', 'hook': '/hook', 'binding': '0.0.0.0', 'port': 8080}, 'space': {'room': '$CHAT_ROOM_TITLE'}}¶
-
check
()[source]¶ Checks settings of the space
This function reads key
space
and below, and update the context accordingly:space.configure({'space': { 'type': 'spark', 'room': 'My preferred room', 'participants': ['alan.droit@azerty.org', 'bob.nard@support.tv'], 'team': 'Anchor team', 'token': '$MY_BOT_TOKEN', }})
This can also be written in a more compact form:
space.configure({'space.room': 'My preferred room', 'space.token': '$MY_BOT_TOKEN', })
This function handles following parameters:
space.room
- title of the associated Cisco Spark room. This can refer to an environment variable if it starts with$
, e.g.,$ROOM_TITLE
.space.participants
- list of initial participants. This can be taken from$CHANNEL_DEFAULT_PARTICIPANTS
from the environment.space.team
- title of a team associated with this roomspace.token
- private token of the bot, given by Cisco Spark. Instead of putting the real value of the token you are encouraged to use an environment variable instead, e.g.,$MY_BOT_TOKEN
. Ifspace.token
is not provided, then the function looks for an environment variableCISCO_SPARK_BOT_TOKEN
.space.audit_token
- token to be used for the audit of chat events. It is recommended that a token of a person is used, so that the visibility is maximised for the proper audit of events. Instead of putting the real value of the token you are encouraged to use an environment variable instead, e.g.,$MY_AUDIT_TOKEN
. Ifspace.audit_token
is not provided, then the function looks for an environment variableCISCO_SPARK_AUDIT_TOKEN
.
If a single value is provided for
participants
then it is turned automatically to a list.Example:
>>>space.configure({'space.participants': 'bobby@jah.com'}) >>>space.context.get('space.participants') ['bobby@jah.com']
-
configured_title
()[source]¶ Returns the title of the space as set in configuration
Returns: the configured title, or Collaboration space
Return type: str This function should be rewritten in sub-classes if space title does not come from
space.room
parameter.
-
connect
(factory=None, **kwargs)[source]¶ Connects to the back-end API
Parameters: factory – an API factory, for test purpose Type: object If a factory is provided, it is used to get API instances. Else the regular CiscoSparkAPI is invoked instead.
This function loads two instances of Cisco Spark API, one using the bot token, and one using the audit token, if this is available.
-
create
(title, ex_team=None, **kwargs)[source]¶ Creates a room
Parameters: - title (str) – title of a new channel
- ex_team (str or object) – the team attached to this room (optional)
If the parameter
ex_team
is provided, then it can be either a simple name, or a team object featuring an id.Returns: Channel or None This function returns a representation of the local channel.
-
delete
(id, **kwargs)[source]¶ Deletes a room
Parameters: id (str) – the unique id of an existing room
-
deregister
()[source]¶ Stops inbound flow from Cisco Spark
This function deregisters hooks that it may have created.
Previous webhooks registered with the bot token are all removed before registration. This means that only the most recent instance of the bot will be notified of new invitations.
This function also removes webhooks created with the audit token, if any. So after deregister the audit of individual rooms just stops.
-
get_attachment
(url, token=None, response=None)[source]¶ Retrieves a document attached to a room
Returns: a stream of BytesIO Return type: BytesIO #TODO: stream from requests response = requests.get(url, stream=True) response.decode_content = True shutil.copyfileobj(response.raw, target)
-
get_by_id
(id, **kwargs)[source]¶ Looks for an existing room by id
Parameters: id (str) – identifier of the target room Returns: Channel instance or None
-
get_by_person
(label, **kwargs)[source]¶ Looks for an existing private room with a person
Parameters: label (str) – the display name of the person’s account Returns: Channel instance or None If a channel already exists for this person, a representation of it is returned. Else the value ``None``is returned.
-
get_by_title
(title, **kwargs)[source]¶ Looks for an existing room by name
Parameters: title (str) – title of the target room Returns: Channel instance or None Note: This function looks only into group rooms. To get a direct room use
get_by_person()
instead.
-
get_team
(name)[source]¶ Gets a team by name
Parameters: name (str) – name of the target team Returns: attributes of the team Return type: Team or None >>>print(space.get_team(“Hello World”)) Team({
“id” : “Y2lzY29zcGFyazovL3VzL1RFQU0Yy0xMWU2LWE5ZDgtMjExYTBkYzc5NzY5”, “name” : “Hello World”, “created” : “2015-10-18T14:26:16+00:00”})
-
list_group_channels
(quantity=10, **kwargs)[source]¶ Lists available channels
Parameters: quantity (positive integer) – maximum quantity of channels to return Returns: list of Channel
-
list_participants
(id)[source]¶ Lists participants to a channel
Parameters: id (str) – the unique id of an existing channel Returns: a list of persons Return type: list of str Note: this function returns all participants, except the bot itself.
-
on_connect
()[source]¶ Retrieves attributes of this bot
This function queries the Cisco Spark API to remember the id of this bot. This is used afterwards to filter inbound messages to the shell.
-
on_init
(token=None, **kwargs)[source]¶ Handles extended initialisation parameters
Parameters: token (str) – bot authentication token for the Cisco Spark API Example:
space = SparkSpace(context=context)
-
on_join
(item, queue=None)[source]¶ Normalizes message for the listener
Parameters: - item (dict) – attributes of the inbound message
- queue (Queue) – the processing queue (optional)
Example item received on memberships:create:
{ 'isMonitor': False, 'created': '2017-05-31T21:25:30.424Z', 'personId': 'Y2lzY29zcGFyazovL3VRiMTAtODZkYy02YzU0Yjg5ODA5N2U', 'isModerator': False, 'personOrgId': 'Y2lzY29zcGFyazovL3V0FOSVpBVElPTi9jb25zdW1lcg', 'personDisplayName': 'foo.bar@acme.com', 'personEmail': 'foo.bar@acme.com', 'roomId': 'Y2lzY29zcGFyazovL3VzL1JP3LTk5MDAtMDU5MDI2YjBiNDUz', 'id': 'Y2lzY29zcGFyazovL3VzDctMTFlNy05OTAwLTA1OTAyNmIwYjQ1Mw' }
This function prepares a Join and push it to the provided queue.
type
is set tojoin
actor_id
is a copy ofpersonId
actor_address
is a copy ofpersonEmail
actor_label
is a copy ofpersonDisplayName
stamp
is a copy ofcreated
-
on_leave
(item, queue=None)[source]¶ Normalizes message for the listener
Parameters: - item (dict) – attributes of the inbound message
- queue (Queue) – the processing queue (optional)
Example item received on memberships:delete:
{ 'isMonitor': False, 'created': '2017-05-31T21:25:30.424Z', 'personId': 'Y2lzY29zcGFyazovL3VRiMTAtODZkYy02YzU0Yjg5ODA5N2U', 'isModerator': False, 'personOrgId': 'Y2lzY29zcGFyazovL3V0FOSVpBVElPTi9jb25zdW1lcg', 'personDisplayName': 'foo.bar@acme.com', 'personEmail': 'foo.bar@acme.com', 'roomId': 'Y2lzY29zcGFyazovL3VzL1JP3LTk5MDAtMDU5MDI2YjBiNDUz', 'id': 'Y2lzY29zcGFyazovL3VzDctMTFlNy05OTAwLTA1OTAyNmIwYjQ1Mw' }
This function prepares a Leave and push it to the provided queue.
type
is set toleave
actor_id
is a copy ofpersonId
actor_address
is a copy ofpersonEmail
actor_label
is a copy ofpersonDisplayName
stamp
is a copy ofcreated
-
on_message
(item, queue=None)[source]¶ Normalizes message for the listener
Parameters: - item (dict) – attributes of the inbound message
- queue (Queue) – the processing queue (optional)
Returns: a Message
This function prepares a Message and push it to the provided queue.
This function adds following keys to messages so that a neutral format can be used with the listener:
type
is set tomessage
content
is a copy ofhtml
from_id
is a copy ofpersonId
from_label
is a copy ofpersonEmail
is_direct
if the message is coming from 1:1 roommentioned_ids
is a copy ofmentionedPeople
channel_id
is a copy ofroomId
stamp
is a copy ofcreated
-
post_message
(id=None, text=None, content=None, file=None, person=None, **kwargs)[source]¶ Posts a message to a Cisco Spark room
Parameters: - id (str) – the unique id of an existing room
- person (str) – address for a direct message
- text (str) – message in plain text
- content (str) – rich format, such as Markdown or HTML
- file (str) – URL or local path for an attachment
Example message out of plain text:
space.post_message(id=id, text='hello world')
Example message with Markdown:
space.post_message(id, content='this is a **bold** statement')
Example file upload:
space.post_message(id, file='./my_file.pdf')
Of course, you can combine text with the upload of a file:
text = 'This is the presentation that was used for our meeting' space.post_message(id=id, text=text, file='./my_file.pdf')
For direct messages, provide who you want to reach instead of a channel id, like this:
space.post_message(person='foo.bar@acme.com', text='hello guy')
-
pull
()[source]¶ Fetches events from Cisco Spark
This function senses most recent items, and pushes them to a processing queue.
-
register
(hook_url)[source]¶ Connects in the background to Cisco Spark inbound events
Parameters: webhook (str) – web address to be used by Cisco Spark service This function registers the provided hook multiple times, so as to receive mutiple kind of updates:
- The bot is invited to a room, or kicked out of it. People are joining or leaving: webhook name = shellbot-memberships resource = memberships, event = all, registered with bot token
- Messages are sent, maybe with some files: webhook name = shellbot-messages resource = messages, event = created, registered with bot token
- Messages sent, maybe with some files, for audit purpose: webhook name = shellbot-audit resource = messages, event = created, registered with audit token
Previous webhooks registered with the bot token are all removed before registration. This means that only the most recent instance of the bot will be notified of new invitations.
-
update
(channel, **kwargs)[source]¶ Updates an existing room
Parameters: channel (Channel) – a representation of the updated room This function can change the title of a room.
For example, change the title from a bot instance:
bot.channel.title = "A new title" bot.space.update(bot.channel)
-
walk_messages
(id=None, **kwargs)[source]¶ Walk messages from a Cisco Spark room
Parameters: id (str) – the unique id of an existing room Returns: an iterator of Message objects
-
webhook
(item=None)[source]¶ Processes the flow of events from Cisco Spark
Parameters: item (dict) – if provided, do not invoke the request
objectThis function is called from far far away, over the Internet, most of the time. Or it is called locally, from test environment, when an item is provided.
The structure of the provided item should be identical to those of updates sent by Cisco Spark.
Example event on message creation:
{ "resource": "messages", "event": "created", "data": { "id": "...." }, "name": "shellbot-audit" }
-