Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#127 Update the existing Webex Teams API wrappers and data models #128

Merged
merged 11 commits into from
Jul 11, 2020
1 change: 1 addition & 0 deletions docs/user/api_structure_table.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
| | | :meth:`delete() <webeteamssdk.api.memberships.MembershipsAPI.delete>` |
+------------------------+---------------------------+---------------------------------------------------------------------------------+
| | :ref:`messages` | :meth:`list() <webeteamssdk.api.messages.MessagesAPI.list>` |
| | | :meth:`list_direct() <webeteamssdk.api.messages.MessagesAPI.list_direct>` |
| | | :meth:`create() <webeteamssdk.api.messages.MessagesAPI.create>` |
| | | :meth:`get() <webeteamssdk.api.messages.MessagesAPI.get>` |
| | | :meth:`delete() <webeteamssdk.api.messages.MessagesAPI.delete>` |
Expand Down
81 changes: 71 additions & 10 deletions tests/api/test_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def adaptive_card():


@pytest.fixture(scope="session")
def direct_message_by_email(api, test_people):
def direct_message_by_person_email(api, test_people):
person = test_people["member_added_by_email"]
message = api.messages.create(
toPersonEmail=person.emails[0],
Expand All @@ -69,6 +69,16 @@ def direct_message_by_email(api, test_people):
api.messages.delete(message.id)


@pytest.fixture(scope="session")
def direct_message_reply_by_person_email(api, direct_message_by_person_email):
text = create_string("Reply Message")
return api.messages.create(
toPersonEmail=direct_message_by_person_email.toPersonEmail,
parentId=direct_message_by_person_email.id,
text=text,
)


@pytest.fixture(scope="session")
def direct_message_by_email_with_card(api, test_people, adaptive_card):
person = test_people["member_added_by_email"]
Expand All @@ -89,7 +99,7 @@ def direct_message_by_email_with_card(api, test_people, adaptive_card):


@pytest.fixture(scope="session")
def direct_message_by_id(api, test_people):
def direct_message_by_person_id(api, test_people):
person = test_people["member_added_by_id"]
message = api.messages.create(
toPersonId=person.id,
Expand All @@ -101,6 +111,16 @@ def direct_message_by_id(api, test_people):
api.messages.delete(message.id)


@pytest.fixture(scope="session")
def direct_message_reply_by_person_id(api, direct_message_by_person_id):
text = create_string("Reply Message")
return api.messages.create(
toPersonId=direct_message_by_person_id.toPersonId,
parentId=direct_message_by_person_id.id,
text=text,
)


@pytest.fixture(scope="session")
def send_group_room_message(api):
messages = []
Expand All @@ -125,6 +145,16 @@ def group_room_text_message(group_room, send_group_room_message):
return send_group_room_message(group_room.id, text=text)


@pytest.fixture(scope="session")
def group_room_message_reply_by_id(api, group_room, group_room_text_message):
text = create_string("Reply Message")
return api.messages.create(
# roomId=group_room.id,
parentId=group_room_text_message.id,
text=text,
)


@pytest.fixture(scope="session")
def group_room_markdown_message(
me,
Expand Down Expand Up @@ -201,13 +231,13 @@ def group_room_messages(

@pytest.fixture(scope="session")
def direct_messages(
direct_message_by_email,
direct_message_by_id,
direct_message_by_person_email,
direct_message_by_person_id,
direct_message_by_email_with_card,
):
return [
direct_message_by_email,
direct_message_by_id,
direct_message_by_person_email,
direct_message_by_person_id,
direct_message_by_email_with_card,
]

Expand Down Expand Up @@ -258,8 +288,14 @@ def test_list_messages_mentioning_me(api, group_room,
assert are_valid_messages(messages_list)


def test_create_direct_messages_by_email(direct_message_by_email):
assert is_valid_message(direct_message_by_email)
def test_create_direct_messages_by_email(direct_message_by_person_email):
assert is_valid_message(direct_message_by_person_email)


def test_reply_to_direct_message_by_person_email(
direct_message_reply_by_person_email
):
assert is_valid_message(direct_message_reply_by_person_email)


def test_create_direct_messages_by_email_with_card(
Expand All @@ -268,14 +304,39 @@ def test_create_direct_messages_by_email_with_card(
assert is_valid_message(direct_message_by_email_with_card)


def test_create_direct_messages_by_id(direct_message_by_id):
assert is_valid_message(direct_message_by_id)
def test_create_direct_messages_by_id(direct_message_by_person_id):
assert is_valid_message(direct_message_by_person_id)


def test_reply_to_direct_message_by_person_id(
direct_message_reply_by_person_id
):
assert is_valid_message(direct_message_reply_by_person_id)


def test_list_direct_messages_by_person_id(api, direct_message_by_person_id):
messages = api.messages.list_direct(
personId=direct_message_by_person_id.toPersonId,
)
assert are_valid_messages(messages)


def test_list_direct_messages_by_person_email(api,
direct_message_by_person_email):
messages = api.messages.list_direct(
personEmail=direct_message_by_person_email.toPersonEmail,
)
assert are_valid_messages(messages)


def test_create_text_message(group_room_text_message):
assert is_valid_message(group_room_text_message)


def test_create_reply_message(group_room_text_message):
assert is_valid_message(group_room_text_message)


def test_create_markdown_message(group_room_markdown_message):
assert is_valid_message(group_room_markdown_message)

Expand Down
13 changes: 6 additions & 7 deletions webexteamssdk/api/attachment_actions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
"""Webex Teams Messages API wrapper.
"""Webex Teams Attachment Actions API wrapper.

Copyright (c) 2016-2019 Cisco and/or its affiliates.

Expand Down Expand Up @@ -106,12 +106,11 @@ def create(self, type, messageId, inputs, **request_parameters):
# Return a attachment action object created from the response JSON data
return self._object_factory(OBJECT_TYPE, json_data)

def get(self, attachmentId):
"""Get the details of a attachment action, by ID.
def get(self, id):
"""Get the details for a attachment action, by ID.

Args:
attachmentId(basestring): The ID of the attachment action to be
retrieved.
id(basestring): A unique identifier for the attachment action.

Returns:
AttachmentAction: A Attachment Action object with the details of
Expand All @@ -122,10 +121,10 @@ def get(self, attachmentId):
ApiError: If the Webex Teams cloud returns an error.

"""
check_type(attachmentId, basestring)
check_type(id, basestring)

# API request
json_data = self._session.get(API_ENDPOINT + '/' + attachmentId)
json_data = self._session.get(API_ENDPOINT + '/' + id)

# Return a message object created from the response JSON data
return self._object_factory(OBJECT_TYPE, json_data)
59 changes: 35 additions & 24 deletions webexteamssdk/api/guest_issuer.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@
import base64
import requests

API_ENDPOINT = 'jwt'
OBJECT_TYPE = 'guest_issuer_token'
API_ENDPOINT = "jwt"
OBJECT_TYPE = "guest_issuer_token"


class GuestIssuerAPI(object):
Expand Down Expand Up @@ -76,46 +76,57 @@ def __init__(self, session, object_factory):
self._session = session
self._object_factory = object_factory

def create(self, subject, displayName, issuerToken, expiration, secret):
def create(self, sub, name, iss, exp, secret):
"""Create a new guest issuer using the provided issuer token.

This function returns a guest issuer with an api access token.

Args:
subject(basestring): Unique and public identifier
displayName(basestring): Display Name of the guest user
issuerToken(basestring): Issuer token from developer hub
expiration(basestring): Expiration time as a unix timestamp
secret(basestring): The secret used to sign your guest issuers
sub(basestring): The subject of the token. This is your unique
and public identifier for the guest user. This claim may
contain only letters, numbers, and hyphens.
name(basestring): The display name of the guest user. This will be
the name shown in Webex Teams clients.
iss(basestring): The issuer of the token. Use the Guest
Issuer ID provided in My Webex Teams Apps.
exp(basestring): The exp time of the token, as a UNIX
timestamp in seconds. Use the lowest practical value for the
use of the token. This is not the exp time for the guest
user's session.
secret(basestring): Use the secret Webex provided you when you
created your Guest Issuer App. The secret will be used to sign
the token request.

Returns:
GuestIssuerToken: A Guest Issuer with a valid access token.
GuestIssuerToken: A Guest Issuer token with a valid access token.

Raises:
TypeError: If the parameter types are incorrect
ApiError: If the webex teams cloud returns an error.
"""
check_type(subject, basestring, optional=True)
check_type(displayName, basestring, optional=True)
check_type(issuerToken, basestring, optional=True)
check_type(expiration, basestring, optional=True)
check_type(secret, basestring, optional=True)
check_type(sub, basestring)
check_type(name, basestring)
check_type(iss, basestring)
check_type(exp, basestring)
check_type(secret, basestring)

payload = {
"sub": subject,
"name": displayName,
"iss": issuerToken,
"exp": expiration
"sub": sub,
"name": name,
"iss": iss,
"exp": exp
}

key = base64.b64decode(secret)
jwt_token = jwt.encode(payload, key, algorithm='HS256')
jwt_token = jwt.encode(payload, key, algorithm="HS256")

url = self._session.base_url + API_ENDPOINT + "/" + "login"
headers = {
'Authorization': "Bearer " + jwt_token.decode('utf-8')
"Authorization": "Bearer " + jwt_token.decode("utf-8")
}
response = requests.post(url, headers=headers)
check_response_code(response, EXPECTED_RESPONSE_CODE['GET'])

return self._object_factory(OBJECT_TYPE, response.json())
json_data = self._session.post(
API_ENDPOINT + "/" + "login",
headers=headers
)

return self._object_factory(OBJECT_TYPE, json_data)
71 changes: 66 additions & 5 deletions webexteamssdk/api/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ def __init__(self, session, object_factory):
self._object_factory = object_factory

@generator_container
def list(self, roomId, mentionedPeople=None, before=None,
beforeMessage=None, max=None, **request_parameters):
def list(self, roomId, parentId=None, mentionedPeople=None, before=None,
beforeMessage=None, max=50, **request_parameters):
"""Lists messages in a room.

Each message will include content attachments if present.
Expand All @@ -93,6 +93,7 @@ def list(self, roomId, mentionedPeople=None, before=None,

Args:
roomId(basestring): List messages for a room, by ID.
parentId(basestring): List messages with a parent, by ID.
mentionedPeople(basestring): List messages where the caller is
mentioned by specifying "me" or the caller `personId`.
before(basestring): List messages sent before a date and time, in
Expand All @@ -114,6 +115,7 @@ def list(self, roomId, mentionedPeople=None, before=None,

"""
check_type(roomId, basestring)
check_type(parentId, basestring, optional=True)
check_type(mentionedPeople, basestring, optional=True)
check_type(before, basestring, optional=True)
check_type(beforeMessage, basestring, optional=True)
Expand All @@ -122,6 +124,7 @@ def list(self, roomId, mentionedPeople=None, before=None,
params = dict_from_items_with_values(
request_parameters,
roomId=roomId,
parentId=parentId,
mentionedPeople=mentionedPeople,
before=before,
beforeMessage=beforeMessage,
Expand All @@ -135,9 +138,67 @@ def list(self, roomId, mentionedPeople=None, before=None,
for item in items:
yield self._object_factory(OBJECT_TYPE, item)

def create(self, roomId=None, toPersonId=None, toPersonEmail=None,
text=None, markdown=None, files=None, attachments=None,
parentId=None, **request_parameters):
@generator_container
def list_direct(self, personId=None, personEmail=None, parentId=None,
**request_parameters):
"""List all messages in a 1:1 (direct) room.

Use the `personId` or `personEmail` query parameter to specify the
room.

The list API sorts the messages in descending order by creation date.

This method supports Webex Teams's implementation of RFC5988 Web
Linking to provide pagination support. It returns a generator
container that incrementally yields all messages returned by the
query. The generator will automatically request additional 'pages' of
responses from Webex as needed until all responses have been returned.
The container makes the generator safe for reuse. A new API call will
be made, using the same parameters that were specified when the
generator was created, every time a new iterator is requested from the
container.

Args:
personId(basestring): List messages in a 1:1 room, by person ID.
personEmail(basestring): List messages in a 1:1 room, by person
email.
parentId(basestring): List messages with a parent, by ID.
**request_parameters: Additional request parameters (provides
support for parameters that may be added in the future).

Returns:
GeneratorContainer: A GeneratorContainer which, when iterated,
yields the messages returned by the Webex Teams query.

Raises:
TypeError: If the parameter types are incorrect.
ApiError: If the Webex Teams cloud returns an error.

"""
check_type(personId, basestring, optional=True)
check_type(personEmail, basestring, optional=True)
check_type(parentId, basestring, optional=True)

params = dict_from_items_with_values(
request_parameters,
personId=personId,
personEmail=personEmail,
parentId=parentId,
)

# API request - get items
items = self._session.get_items(
API_ENDPOINT + "/direct",
params=params,
)

# Yield message objects created from the returned items JSON objects
for item in items:
yield self._object_factory(OBJECT_TYPE, item)

def create(self, roomId=None, parentId=None, toPersonId=None,
toPersonEmail=None, text=None, markdown=None, files=None,
attachments=None, **request_parameters):
"""Post a message to a room.

The files parameter is a list, which accepts multiple values to allow
Expand Down
Loading