diff --git a/README.md b/README.md index b7b6237..3ba5589 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,10 @@ Implements the Microsoft Office365 Graph API for the follow * Place - List Places - Get Place +* Teams + - List channel messages + - Get channel message + - Send channel message ## Installation diff --git a/spec/chat_messages/channel_messages_spec.cr b/spec/chat_messages/channel_messages_spec.cr new file mode 100644 index 0000000..b71fa64 --- /dev/null +++ b/spec/chat_messages/channel_messages_spec.cr @@ -0,0 +1,45 @@ +require "../spec_helper" + +describe Office365::Places do + describe "list_messages" do + it "list_messages should return the list of messages in channel" do + SpecHelper.mock_client_auth + SpecHelper.mock_list_channel_msgs + + team_id = "fbe2bf47-16c8-47cf-b4a5-4b9b187c508b" + channel_id = "19:4a95f7d8db4c4e7fae857bcebe0623e6@thread.tacv2" + + client = Office365::Client.new(**SpecHelper.mock_credentials) + + messages = client.list_channel_messages(team_id: team_id, channel_id: channel_id, top: 3) + messages.count.should eq(3) + messages.next_link.should_not be_nil + messages.value.size.should eq(3) + end + + it "should get message in channel" do + SpecHelper.mock_client_auth + SpecHelper.mock_get_channel_msg + + team_id = "fbe2bf47-16c8-47cf-b4a5-4b9b187c508b" + channel_id = "19:4a95f7d8db4c4e7fae857bcebe0623e6@thread.tacv2" + msg_id = "1614618259349" + client = Office365::Client.new(**SpecHelper.mock_credentials) + + message = client.get_channel_message(team_id: team_id, channel_id: channel_id, message_id: msg_id) + message.id.should eq("1612289992105") + end + + it "should send message in channel" do + SpecHelper.mock_client_auth + SpecHelper.mock_channel_send_msg + + team_id = "fbe2bf47-16c8-47cf-b4a5-4b9b187c508b" + channel_id = "19:4a95f7d8db4c4e7fae857bcebe0623e6@thread.tacv2" + client = Office365::Client.new(**SpecHelper.mock_credentials) + + resp = client.send_channel_message(team_id, channel_id, "Hello World") + resp.status_code.should eq(201) + end + end +end diff --git a/spec/chat_messages/messages.json b/spec/chat_messages/messages.json new file mode 100644 index 0000000..e58351d --- /dev/null +++ b/spec/chat_messages/messages.json @@ -0,0 +1,144 @@ +{ + "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#teams('fbe2bf47-16c8-47cf-b4a5-4b9b187c508b')/channels('19%3A4a95f7d8db4c4e7fae857bcebe0623e6%40thread.tacv2')/messages", + "@odata.count": 3, + "@odata.nextLink": "https://graph.microsoft.com/v1.0/teams/fbe2bf47-16c8-47cf-b4a5-4b9b187c508b/channels/19:4a95f7d8db4c4e7fae857bcebe0623e6@thread.tacv2/messages?$skiptoken=...", + "value": [ + { + "id": "1616965872395", + "replyToId": null, + "etag": "1616965872395", + "messageType": "message", + "createdDateTime": "2021-03-28T21:11:12.395Z", + "lastModifiedDateTime": "2021-03-28T21:11:12.395Z", + "lastEditedDateTime": null, + "deletedDateTime": null, + "subject": null, + "summary": null, + "chatId": null, + "importance": "normal", + "locale": "en-us", + "webUrl": "https://teams.microsoft.com/l/message/19%3A4a95f7d8db4c4e7fae857bcebe0623e6%40thread.tacv2/1616965872395?groupId=fbe2bf47-16c8-47cf-b4a5-4b9b187c508b&tenantId=2432b57b-0abd-43db-aa7b-16eadd115d34&createdTime=1616965872395&parentMessageId=1616965872395", + "policyViolation": null, + "eventDetail": null, + "from": { + "application": null, + "device": null, + "user": { + "id": "8ea0e38b-efb3-4757-924a-5f94061cf8c2", + "displayName": "Robin Kline", + "userIdentityType": "aadUser" + } + }, + "body": { + "contentType": "html", + "content": "Hello World Jane Smith" + }, + "channelIdentity": { + "teamId": "fbe2bf47-16c8-47cf-b4a5-4b9b187c508b", + "channelId": "19:4a95f7d8db4c4e7fae857bcebe0623e6@thread.tacv2" + }, + "attachments": [], + "mentions": [ + { + "id": 0, + "mentionText": "Jane Smith", + "mentioned": { + "application": null, + "device": null, + "conversation": null, + "user": { + "id": "ef1c916a-3135-4417-ba27-8eb7bd084193", + "displayName": "Jane Smith", + "userIdentityType": "aadUser" + } + } + } + ], + "reactions": [], + "messageHistory": [] + }, + { + "id": "1616963377068", + "replyToId": null, + "etag": "1616963377068", + "messageType": "message", + "createdDateTime": "2021-03-28T20:29:37.068Z", + "lastModifiedDateTime": "2021-03-28T20:29:37.068Z", + "lastEditedDateTime": null, + "deletedDateTime": null, + "subject": "", + "summary": null, + "chatId": null, + "importance": "normal", + "locale": "en-us", + "webUrl": "https://teams.microsoft.com/l/message/19%3A4a95f7d8db4c4e7fae857bcebe0623e6%40thread.tacv2/1616963377068?groupId=fbe2bf47-16c8-47cf-b4a5-4b9b187c508b&tenantId=2432b57b-0abd-43db-aa7b-16eadd115d34&createdTime=1616963377068&parentMessageId=1616963377068", + "policyViolation": null, + "eventDetail": null, + "from": { + "application": null, + "device": null, + "user": { + "id": "8ea0e38b-efb3-4757-924a-5f94061cf8c2", + "displayName": "Robin Kline", + "userIdentityType": "aadUser" + } + }, + "body": { + "contentType": "html", + "content": "
" + }, + "channelIdentity": { + "teamId": "fbe2bf47-16c8-47cf-b4a5-4b9b187c508b", + "channelId": "19:4a95f7d8db4c4e7fae857bcebe0623e6@thread.tacv2" + }, + "attachments": [], + "mentions": [], + "reactions": [], + "messageHistory": [] + }, + { + "id": "1616883610266", + "replyToId": null, + "etag": "1616883610266", + "messageType": "unknownFutureValue", + "createdDateTime": "2021-03-28T03:50:10.266Z", + "lastModifiedDateTime": "2021-03-28T03:50:10.266Z", + "lastEditedDateTime": null, + "deletedDateTime": null, + "subject": null, + "summary": null, + "chatId": null, + "importance": "normal", + "locale": "en-us", + "webUrl": "https://teams.microsoft.com/l/message/19%3A4a95f7d8db4c4e7fae857bcebe0623e6%40thread.tacv2/1616883610266?groupId=fbe2bf47-16c8-47cf-b4a5-4b9b187c508b&tenantId=2432b57b-0abd-43db-aa7b-16eadd115d34&createdTime=1616883610266&parentMessageId=1616883610266", + "policyViolation": null, + "from": null, + "body": { + "contentType": "html", + "content": "" + }, + "channelIdentity": { + "teamId": "fbe2bf47-16c8-47cf-b4a5-4b9b187c508b", + "channelId": "19:4a95f7d8db4c4e7fae857bcebe0623e6@thread.tacv2" + }, + "attachments": [], + "mentions": [], + "reactions": [], + "messageHistory": [], + "eventDetail": { + "@odata.type": "#microsoft.graph.teamDescriptionUpdatedEventMessageDetail", + "teamId": "fbe2bf47-16c8-47cf-b4a5-4b9b187c508b", + "teamDescription": "Team for Microsoft Teams members", + "initiator": { + "application": null, + "device": null, + "user": { + "id": "1fb8890f-423e-4154-8fbf-db6809bc8756", + "displayName": null, + "userIdentityType": "aadUser" + } + } + } + } + ] + } \ No newline at end of file diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr index 7e11af1..9c7805b 100644 --- a/spec/spec_helper.cr +++ b/spec/spec_helper.cr @@ -648,6 +648,71 @@ module SpecHelper ], } end + + def mock_list_channel_msgs + WebMock.stub(:get, "https://graph.microsoft.com/v1.0/teams/fbe2bf47-16c8-47cf-b4a5-4b9b187c508b/channels/19%3A4a95f7d8db4c4e7fae857bcebe0623e6%40thread.tacv2/messages?%24top=3") + .to_return(body: mock_list_channel_messages) + end + + def mock_list_channel_messages + File.read("spec/chat_messages/messages.json") + end + + def mock_get_channel_msg + WebMock.stub(:get, "https://graph.microsoft.com/v1.0/teams/fbe2bf47-16c8-47cf-b4a5-4b9b187c508b/channels/19%3A4a95f7d8db4c4e7fae857bcebe0623e6%40thread.tacv2/messages/1614618259349") + .to_return(body: mock_get_channel_message) + end + + def mock_get_channel_message + %( +{ + "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#chats('19%3A8ea0e38b-efb3-4757-924a-5f94061cf8c2_97f62344-57dc-409c-88ad-c4af14158ff5%40unq.gbl.spaces')/messages/$entity", + "id": "1612289992105", + "replyToId": null, + "etag": "1612289992105", + "messageType": "message", + "createdDateTime": "2021-02-02T18:19:52.105Z", + "lastModifiedDateTime": "2021-02-02T18:19:52.105Z", + "lastEditedDateTime": null, + "deletedDateTime": null, + "subject": null, + "summary": null, + "chatId": "19:8ea0e38b-efb3-4757-924a-5f94061cf8c2_97f62344-57dc-409c-88ad-c4af14158ff5@unq.gbl.spaces", + "importance": "normal", + "locale": "en-us", + "webUrl": null, + "channelIdentity": null, + "policyViolation": null, + "eventDetail": null, + "from": { + "application": null, + "device": null, + "conversation": null, + "user": { + "@odata.type": "#microsoft.graph.teamworkUserIdentity", + "id": "8ea0e38b-efb3-4757-924a-5f94061cf8c2", + "displayName": "Robin Kline", + "userIdentityType": "aadUser", + "tenantId": "e61ef81e-8bd8-476a-92e8-4a62f8426fca" + } + }, + "body": { + "contentType": "text", + "content": "test" + }, + "attachments": [], + "mentions": [], + "reactions": [], + "messageHistory": [] +} + ) + end + + def mock_channel_send_msg + WebMock.stub(:post, "https://graph.microsoft.com/v1.0/teams/fbe2bf47-16c8-47cf-b4a5-4b9b187c508b/channels/19%3A4a95f7d8db4c4e7fae857bcebe0623e6%40thread.tacv2/messages") + .with(body: "{\"body\":{\"content\":\"Hello World\",\"contentType\":\"TEXT\"}}", headers: {"Authorization" => "Bearer access_token", "Content-Type" => "application/json", "Prefer" => "IdType=\"ImmutableId\""}) + .to_return(status: 201, body: "") + end end Spec.before_each do diff --git a/src/attachments.cr b/src/attachments.cr index 96bb499..b5db9ee 100644 --- a/src/attachments.cr +++ b/src/attachments.cr @@ -29,7 +29,7 @@ module Office365::Attachments name : String, content_bytes : String, calendar_group_id : String? = nil, - calendar_id : String? = nil + calendar_id : String? = nil, ) attachment = Attachment.new(name, content_bytes) endpoint = event_attachment_path(mailbox, event_id, calendar_group_id, calendar_id) @@ -57,7 +57,7 @@ module Office365::Attachments mailbox : String, event_id : String, calendar_group_id : String? = nil, - calendar_id : String? = nil + calendar_id : String? = nil, ) endpoint = "#{event_attachment_path(mailbox, event_id, calendar_group_id, calendar_id)}/#{id}" graph_http_request(request_method: "GET", path: endpoint) @@ -83,7 +83,7 @@ module Office365::Attachments mailbox : String, event_id : String, calendar_group_id : String? = nil, - calendar_id : String? = nil + calendar_id : String? = nil, ) endpoint = "#{event_attachment_path(mailbox, event_id, calendar_group_id, calendar_id)}/#{id}" @@ -109,7 +109,7 @@ module Office365::Attachments mailbox : String, event_id : String, calendar_group_id : String? = nil, - calendar_id : String? = nil + calendar_id : String? = nil, ) endpoint = "" diff --git a/src/channel_messages.cr b/src/channel_messages.cr new file mode 100644 index 0000000..a6303e4 --- /dev/null +++ b/src/channel_messages.cr @@ -0,0 +1,58 @@ +module Office365::ChannelMessages + def list_channel_messages_request(team_id : String, channel_id : String, filter : String? = nil, match : String? = nil, top : Int32? = nil, skip : Int32? = nil, count : Bool? = nil) + query_params = URI::Params.new + + if top + query_params["$top"] = top.to_s + end + + if count + query_params["$count"] = count.to_s + end + + if filter + query_params["$filter"] = filter + end + + if match + query_params["$select"] = match + end + + if skip + query_params["$skip"] = skip.to_s + end + + graph_http_request(request_method: "GET", path: "/v1.0/teams/#{team_id}/channels/#{channel_id}/messages", query: query_params) + end + + def list_channel_messages(*args, **opts) + request = list_channel_messages_request(*args, **opts) + response = graph_request(request) + + list_channel_messages(response) + end + + def list_channel_messages(response : HTTP::Client::Response) + ChatMessageList.from_json(response.body) + end + + def get_channel_message(team_id : String, channel_id : String, message_id : String) + request = graph_http_request(request_method: "GET", path: "/v1.0/teams/#{team_id}/channels/#{channel_id}/messages/#{message_id}") + response = graph_request(request) + ChatMessage.from_json(response.body) + end + + def send_channel_message(team_id : String, channel_id : String, message : String | IO) + body = message.is_a?(IO) ? message.gets_to_end : message + chat = ChatMessage.new(body: body) + request = graph_http_request(request_method: "POST", path: "/v1.0/teams/#{team_id}/channels/#{channel_id}/messages", data: chat.to_json) + graph_request(request) + end + + def send_channel_message(team_id : String, channel_id : String, message : String | IO, content_type : String) + body = message.is_a?(IO) ? message.gets_to_end : message + chat = ChatMessage.new(content: body, content_type: content_type) + request = graph_http_request(request_method: "POST", path: "/v1.0/teams/#{team_id}/channels/#{channel_id}/messages", data: chat.to_json) + graph_request(request) + end +end diff --git a/src/client.cr b/src/client.cr index dbc3a23..919004a 100644 --- a/src/client.cr +++ b/src/client.cr @@ -9,6 +9,7 @@ require "./subscriptions" require "./odata" require "./password_credentials" require "./places" +require "./channel_messages" module Office365 USERS_BASE = "/v1.0/users" @@ -27,6 +28,7 @@ module Office365 include Office365::OData include Office365::PasswordCredentials include Office365::Places + include Office365::ChannelMessages LOGIN_URI = URI.parse("https://login.microsoftonline.com") GRAPH_URI = URI.parse("https://graph.microsoft.com/") @@ -114,7 +116,7 @@ module Office365 path : String, data : String? = nil, query : URI::Params? = nil, - headers : HTTP::Headers = default_headers + headers : HTTP::Headers = default_headers, ) : HTTP::Request uri = if query && !query.empty? "#{URI.encode_path(URI.decode(path))}?#{query}" diff --git a/src/events.cr b/src/events.cr index 932a270..b554561 100644 --- a/src/events.cr +++ b/src/events.cr @@ -7,7 +7,7 @@ module Office365::Events period_end : Time? = nil, ical_uid : String? = nil, top : Int32? = 10000, - filter : String? = nil + filter : String? = nil, ) path, params = calendar_view_path(mailbox, calendar_group_id, calendar_id, period_start, period_end, ical_uid, top, filter) @@ -31,7 +31,7 @@ module Office365::Events ends_at : Time?, calendar_group_id : String? = nil, calendar_id : String? = nil, - **opts + **opts, ) event = Event.new(**opts.merge(starts_at: starts_at, ends_at: ends_at)) endpoint = calendar_event_path(mailbox, calendar_group_id, calendar_id) @@ -54,7 +54,7 @@ module Office365::Events id : String, mailbox : String, calendar_group_id : String? = nil, - calendar_id : String? = nil + calendar_id : String? = nil, ) endpoint = "#{calendar_event_path(mailbox, calendar_group_id, calendar_id)}/#{id}" graph_http_request(request_method: "GET", path: endpoint) @@ -75,7 +75,7 @@ module Office365::Events event : Event, mailbox : String, calendar_group_id : String? = nil, - calendar_id : String? = nil + calendar_id : String? = nil, ) endpoint = "#{calendar_event_path(mailbox, calendar_group_id, calendar_id)}/#{event.id}" @@ -97,7 +97,7 @@ module Office365::Events id : String, mailbox : String, calendar_group_id : String? = nil, - calendar_id : String? = nil + calendar_id : String? = nil, ) endpoint = "#{calendar_event_path(mailbox, calendar_group_id, calendar_id)}/#{id}" @@ -121,7 +121,7 @@ module Office365::Events calendar_group_id : String? = nil, calendar_id : String? = nil, notify : Bool = true, - comment : String? = nil + comment : String? = nil, ) endpoint = "#{calendar_event_path(mailbox, calendar_group_id, calendar_id)}/#{id}/decline" @@ -147,7 +147,7 @@ module Office365::Events mailbox : String, calendar_group_id : String? = nil, calendar_id : String? = nil, - comment : String? = nil + comment : String? = nil, ) endpoint = "#{calendar_event_path(mailbox, calendar_group_id, calendar_id)}/#{id}/cancel" @@ -175,7 +175,7 @@ module Office365::Events calendar_group_id : String? = nil, calendar_id : String? = nil, notify : Bool = true, - comment : String? = nil + comment : String? = nil, ) endpoint = "#{calendar_event_path(mailbox, calendar_group_id, calendar_id)}/#{id}/accept" @@ -199,7 +199,7 @@ module Office365::Events private def calendar_event_path( mailbox : String, calendar_group_id : String? = nil, - calendar_id : String? = nil + calendar_id : String? = nil, ) # we assume we are actually after a mailbox as calendar_ids are not emails if calendar_id.try &.includes?('@') @@ -229,7 +229,7 @@ module Office365::Events period_end : Time? = nil, ical_uid : String? = nil, top : Int32? = 10000, - filter : String? = nil + filter : String? = nil, ) end_period = period_end || period_start + 6.months diff --git a/src/models/channel_identity.cr b/src/models/channel_identity.cr new file mode 100644 index 0000000..8ff9f50 --- /dev/null +++ b/src/models/channel_identity.cr @@ -0,0 +1,11 @@ +module Office365 + class ChannelIdentity + include JSON::Serializable + + @[JSON::Field(key: "channelId")] + property channel_id : String + + @[JSON::Field(key: "teamId")] + property team_id : String + end +end diff --git a/src/models/chat_message.cr b/src/models/chat_message.cr new file mode 100644 index 0000000..1d894d4 --- /dev/null +++ b/src/models/chat_message.cr @@ -0,0 +1,191 @@ +module Office365 + enum ChatMessageType + Message + ChatEvent + Typing + UnknownFutureValue + SystemEventMessage + + def to_json(json : JSON::Builder) + val = to_s + val = val[0].downcase + val[1..] + json.string(val) + end + end + + enum ChatMessageActions + ReactionAdded + ReactionRemoved + ActionUndefined + UnknownFutureValue + + def to_json(json : JSON::Builder) + val = to_s + val = val[0].downcase + val[1..] + json.string(val) + end + end + + enum ChatMessagePolicyViolationDlpActionType + None + NotifySender + BlockAccess + BlockAccessExternal + end + + class ChatMessageMention + include JSON::Serializable + + property id : Int32? + property mentioned : ChatMessageMentionedIdentitySet? + + @[JSON::Field(key: "mentionText")] + property mention_text : String? + end + + class ChatMessageReaction + include JSON::Serializable + + @[JSON::Field(key: "createdDateTime")] + property created_date_time : String? + + @[JSON::Field(key: "displayName")] + property display_name : String? + + @[JSON::Field(key: "reactionContentUrl")] + property reaction_content_url : String? + + @[JSON::Field(key: "reactionType")] + property reaction_type : String? + + property user : ChatMessageReactionIdentitySet? + end + + class ChatMessageHistoryItem + include JSON::Serializable + + property actions : ChatMessageActions + + @[JSON::Field(key: "modifiedDateTime")] + property modified_date_time : Time? + + property reaction : ChatMessageReaction? + end + + class ChatMessagePolicyTip + include JSON::Serializable + + @[JSON::Field(key: "complianceUrl")] + property compliance_url : String? + + @[JSON::Field(key: "generalText")] + property general_text : String? + + @[JSON::Field(key: "matchedConditionDescriptions")] + property matched_condition_descriptions : Array(String)? + end + + class ChatMessagePolicyViolation + include JSON::Serializable + + @[JSON::Field(key: "dlpAction")] + property dlp_action : ChatMessagePolicyViolationDlpActionType? + + @[JSON::Field(key: "justificationText")] + property justification_text : String? + + @[JSON::Field(key: "policyTip")] + property policy_tip : ChatMessagePolicyTip? + + @[JSON::Field(key: "userAction")] + property user_action : ChatMessagePolicyViolationDlpActionType? + + @[JSON::Field(key: "verdictDetails")] + property verdict_details : ChatMessagePolicyViolationDlpActionType? + end + + class ChatMessage + include JSON::Serializable + include JSON::Serializable::Unmapped + + property attachments : Array(ChatMessageAttachment)? + property body : ItemBody + + @[JSON::Field(key: "chatId")] + property chat_id : String? + + @[JSON::Field(key: "channelIdentity")] + property channel_identity : ChannelIdentity? + + @[JSON::Field(key: "createdDateTime")] + property created_date_time : Time? + + @[JSON::Field(key: "deletedDateTime")] + property deleted_date_time : Time? + + property etag : String? + + # @[JSON::Field(key: "eventDetail")] + # property event_detail : EventMessageDetail? + + property from : ChatMessageFromIdentitySet? + property id : String? + property importance : String? + + @[JSON::Field(key: "lastModifiedDateTime")] + property last_modified_date_time : Time? + + @[JSON::Field(key: "lastEditedDateTime")] + property last_edited_date_time : Time? + + property locale : String? + property mentions : Array(ChatMessageMention)? + + @[JSON::Field(key: "messageHistory")] + property message_history : Array(ChatMessageHistoryItem)? + + @[JSON::Field(key: "messageType")] + property message_type : ChatMessageType? + + @[JSON::Field(key: "policyViolation")] + property policy_violation : ChatMessagePolicyViolation? + + property reactions : Array(ChatMessageReaction)? + + @[JSON::Field(key: "replyToId")] + property reply_to_id : String? + + property subject : String? + property summary : String? + + @[JSON::Field(key: "webUrl")] + property web_url : String? + + def initialize(@body, @attachments = nil, @chat_id = nil, @channel_identity = nil, @created_date_time = nil, @deleted_date_time = nil, @etag = nil, @from = nil, @id = nil, @importance = nil, @last_modified_date_time = nil, + @last_edited_date_time = nil, @locale = nil, @mentions = nil, @message_history = nil, @message_type = nil, @policy_violation = nil, @reactions = nil, @subject = nil, @summary = nil, @web_url = nil) + end + + def self.new(content : String, content_type : String) + new(body: ItemBody.new(content: content, content_type: content_type)) + end + + def self.new(body : String) + new(content: body, content_type: "TEXT") + end + end + + class ChatMessageList + include JSON::Serializable + + @[JSON::Field(key: "@odata.context")] + property context : String + + @[JSON::Field(key: "@odata.count")] + property count : Int32 + + @[JSON::Field(key: "@odata.nextLink")] + property next_link : String? + + property value : Array(ChatMessage) + end +end diff --git a/src/models/chat_msg_attachment.cr b/src/models/chat_msg_attachment.cr new file mode 100644 index 0000000..c8aea22 --- /dev/null +++ b/src/models/chat_msg_attachment.cr @@ -0,0 +1,21 @@ +module Office365 + class ChatMessageAttachment + include JSON::Serializable + + property id : String + property name : String? + property content : String? + + @[JSON::Field(key: "contentType")] + property content_type : String? + + @[JSON::Field(key: "contentUrl")] + property content_url : String? + + @[JSON::Field(key: "teamsAppId")] + property teams_app_id : String? + + @[JSON::Field(key: "thumbnailUrl")] + property thumbnail_url : String? + end +end diff --git a/src/models/event.cr b/src/models/event.cr index 2bd69a2..0e9d7c4 100644 --- a/src/models/event.cr +++ b/src/models/event.cr @@ -129,7 +129,7 @@ module Office365 @id = nil, @series_master_id = nil, @online_meeting_provider = nil, - @hide_attendees = false + @hide_attendees = false, ) @body = ItemBody.new(description) @is_online_meeting = @online_meeting_provider ? true : nil diff --git a/src/models/event_msg_detail.cr b/src/models/event_msg_detail.cr new file mode 100644 index 0000000..33f9f6a --- /dev/null +++ b/src/models/event_msg_detail.cr @@ -0,0 +1,38 @@ +module Office365 + abstract class EventMessageDetail + include JSON::Serializable + + @[JSON::Field(key: "@odata.type")] + property type : String + + use_json_discriminator "@odata.type", { + "#microsoft.graph.callEndedEventMessageDetail" => CallEndedEvent, + "#microsoft.graph.channelAddedEventMessageDetail" => ChannelAddedEvent, + } + end + + class CallEndedEvent < EventMessageDetail + include JSON::Serializable + include JSON::Serializable::Unmapped + + @[JSON::Field(key: "callDuration")] + property call_duration : String? + + @[JSON::Field(key: "callEventType")] + property call_event_type : String? + + @[JSON::Field(key: "callId")] + property call_id : String? + end + + class ChannelAddedEvent < EventMessageDetail + include JSON::Serializable + include JSON::Serializable::Unmapped + + @[JSON::Field(key: "channelDisplayName")] + property channel_display_name : String? + + @[JSON::Field(key: "channelId")] + property channel_id : String? + end +end diff --git a/src/models/identity.cr b/src/models/identity.cr new file mode 100644 index 0000000..ba376ed --- /dev/null +++ b/src/models/identity.cr @@ -0,0 +1,67 @@ +module Office365 + class Identity + include JSON::Serializable + + property id : String + + @[JSON::Field(key: "displayName")] + property display_name : String? + + @[JSON::Field(key: "tenantId")] + property tenant_id : String? + + property thumbnails : ThumbnailSet? + end + + class TeamworkUserIdentity + include JSON::Serializable + + property id : String + + @[JSON::Field(key: "displayName")] + property display_name : String? + + @[JSON::Field(key: "tenantId")] + property tenant_id : String? + + @[JSON::Field(key: "userIdentityType")] + property user_identity_type : String? + end + + class ChatMessageFromIdentitySet + include JSON::Serializable + + property application : Identity? + property device : Identity? + property user : TeamworkUserIdentity? + end + + class TeamworkConversationIdentity + include JSON::Serializable + + property id : String + + @[JSON::Field(key: "displayName")] + property display_name : String? + + @[JSON::Field(key: "conversationIdentityType")] + property conversation_identity_type : String? + end + + class ChatMessageMentionedIdentitySet + include JSON::Serializable + + property application : Identity? + property conversation : TeamworkConversationIdentity? + property device : Identity? + property user : Identity? + end + + class ChatMessageReactionIdentitySet + include JSON::Serializable + + property application : Identity? + property device : Identity? + property user : Identity? + end +end diff --git a/src/models/message.cr b/src/models/message.cr index b780812..6014b24 100644 --- a/src/models/message.cr +++ b/src/models/message.cr @@ -55,7 +55,7 @@ module Office365 cc : Array(String) | Array(EmailAddress) | Nil = nil, bcc : Array(String) | Array(EmailAddress) | Nil = nil, @body_preview = nil, - @attachments = nil + @attachments = nil, ) @body = Body.new(content, content_type) @to = to_recipient(to) diff --git a/src/models/thumbnail.cr b/src/models/thumbnail.cr new file mode 100644 index 0000000..5ac75e8 --- /dev/null +++ b/src/models/thumbnail.cr @@ -0,0 +1,23 @@ +module Office365 + class Thumbnail + include JSON::Serializable + + property height : Int32? + property width : Int32? + property content : String? + property url : String? + + @[JSON::Field(key: "sourceItemId")] + property source_item_id : String? + end + + class ThumbnailSet + include JSON::Serializable + + property id : String? + property large : Thumbnail? + property medium : Thumbnail? + property small : Thumbnail? + property source : Thumbnail? + end +end diff --git a/src/subscriptions.cr b/src/subscriptions.cr index b10c974..2b6bc44 100644 --- a/src/subscriptions.cr +++ b/src/subscriptions.cr @@ -6,7 +6,7 @@ module Office365::Subscriptions expiration_date_time : Time, client_state : String? = nil, lifecycle_notification_url : String? = nil, - **opts + **opts, ) sub = Subscription.new(resource, change_types, notification_url, expiration_date_time, client_state, lifecycle_notification_url) graph_http_request(request_method: "POST", path: "/v1.0/subscriptions", data: sub.to_json) @@ -25,7 +25,7 @@ module Office365::Subscriptions # renew a subscription def renew_subscription_request( subscription_id : String, - expiration_date_time : Time + expiration_date_time : Time, ) graph_http_request( request_method: "PATCH",