From 67a243037bd381e7c513c8e0289c9d0e6631f8b7 Mon Sep 17 00:00:00 2001 From: Ali Naqvi Date: Mon, 31 Mar 2025 18:44:51 +0800 Subject: [PATCH 1/2] feat(staff_api): Added MS Team Api --- drivers/place/staff_api.cr | 51 +++++++++++++++++++++++++---- drivers/place/staff_api_spec.cr | 58 +++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 7 deletions(-) diff --git a/drivers/place/staff_api.cr b/drivers/place/staff_api.cr index 9f19a1fec44..8e317093973 100644 --- a/drivers/place/staff_api.cr +++ b/drivers/place/staff_api.cr @@ -143,7 +143,7 @@ class Place::StaffAPI < PlaceOS::Driver bookable : Bool? = nil, features : String? = nil, limit : Int32 = 1000, - offset : Int32 = 0 + offset : Int32 = 0, ) placeos_client.systems.search( q: q, @@ -266,7 +266,7 @@ class Place::StaffAPI < PlaceOS::Driver limit : Int32 = 20, offset : Int32 = 0, authority_id : String? = nil, - include_deleted : Bool = false + include_deleted : Bool = false, ) placeos_client.users.search(q: q, limit: limit, offset: offset, authority_id: authority_id, include_deleted: include_deleted) end @@ -370,7 +370,7 @@ class Place::StaffAPI < PlaceOS::Driver capacity : Int32? = nil, features : String? = nil, bookable : Bool? = nil, - include_cancelled : Bool? = nil + include_cancelled : Bool? = nil, ) params = URI::Params.build do |form| form.add "period_start", period_start.to_s @@ -476,7 +476,7 @@ class Place::StaffAPI < PlaceOS::Driver field_name : String? = nil, value : String? = nil, system_id : String? = nil, - event_ref : Array(String)? = nil + event_ref : Array(String)? = nil, ) params = URI::Params.build do |form| form.add "period_start", period_start.to_s if period_start @@ -568,7 +568,7 @@ class Place::StaffAPI < PlaceOS::Driver recurrence_days : Int32? = nil, recurrence_nth_of_month : Int32? = nil, recurrence_interval : Int32? = nil, - recurrence_end : Int64? = nil + recurrence_end : Int64? = nil, ) now = time_zone ? Time.local(Time::Location.load(time_zone)) : Time.local booking_start ||= now.at_beginning_of_day.to_unix @@ -754,7 +754,7 @@ class Place::StaffAPI < PlaceOS::Driver extension_data : JSON::Any? = nil, deleted : Bool? = nil, asset_id : String? = nil, - limit : Int32? = nil + limit : Int32? = nil, ) default_end = @period_end_default_in_min || 30 @@ -913,7 +913,7 @@ class Place::StaffAPI < PlaceOS::Driver def update_survey_invite( token : String, email : String? = nil, - sent : Bool? = nil + sent : Bool? = nil, ) logger.debug { "updating survey invite #{token}" } response = patch("/api/staff/v1/surveys/invitations/#{token}", headers: authentication, body: { @@ -948,6 +948,43 @@ class Place::StaffAPI < PlaceOS::Driver headers["X-API-Key"] = @api_key.presence || "spec-test" headers end + + # =================================== + # MS Teams + # =================================== + + @[Security(Level::Support)] + def list_channel_messages(team_id : String, channel_id : String, top : Int32? = nil) + logger.debug { "listing teams #{team_id} channel #{channel_id} messages , top #{top}" } + params = URI::Params.new + params["top"] = top.to_s if top + response = get("/api/staff/v1/teams/#{team_id}/#{channel_id}", params, headers: authentication) + raise "issue getting teams channel messages (team #{team_id}, channel #{channel_id}): #{response.status_code}, body: #{response.body}" unless response.success? + JSON.parse(response.body) + end + + @[Security(Level::Support)] + def get_channel_message(team_id : String, channel_id : String, message_id : String) + logger.debug { "Getting teams #{team_id} channel #{channel_id} message id #{message_id}, note: graphAPI only" } + response = get("/api/staff/v1/teams/#{team_id}/#{channel_id}/#{message_id}", headers: authentication) + raise "issue getting teams channel message (team #{team_id}, channel #{channel_id}, message id #{message_id}): #{response.status_code}, body: #{response.body}" unless response.success? + JSON.parse(response.body) + end + + @[Security(Level::Support)] + def send_channel_message(team_id : String, channel_id : String, message : String, content_type : String? = nil) : Bool + logger.debug { "Sending teams #{team_id} channel #{channel_id} content_type #{content_type}, message #{message}, note: graphAPI only" } + params = URI::Params.new + params["type"] = content_type if content_type + query_params = params ? "?#{params}" : "" + response = post("/api/staff/v1/teams/#{team_id}/#{channel_id}#{query_params}", + body: message, + headers: authentication(HTTP::Headers{ + "Content-Type" => "text/plain", + }) + ) + response.status_code == 201 + end end # Deal with bad SSL certificate diff --git a/drivers/place/staff_api_spec.cr b/drivers/place/staff_api_spec.cr index 76ede5046fc..760f9948e36 100644 --- a/drivers/place/staff_api_spec.cr +++ b/drivers/place/staff_api_spec.cr @@ -89,4 +89,62 @@ DriverSpecs.mock_driver "Place::StaffAPI" do "email": "user@spec.test", "sent": false }]))) + + sleep 1 + channel_msgs_resp = exec(:list_channel_messages, team_id: "my_teams", channel_id: "my_channel") + + expect_http_request do |request, response| + headers = request.headers + if headers["X-API-Key"]? == "spec-test" && request.path == "/api/staff/v1/teams/my_teams/my_channel" + response.status_code = 200 + response << mock_get_channel_message.to_json + end + end + + channel_msgs_resp.get.should eq(JSON.parse(mock_get_channel_message.to_json)) +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 From d84ed8318241e6b19fd7c71bb0c93df120c1cfda Mon Sep 17 00:00:00 2001 From: Ali Naqvi Date: Mon, 14 Apr 2025 13:01:53 +0800 Subject: [PATCH 2/2] chore: shard.lock + detailed error message --- drivers/place/staff_api.cr | 9 +++++---- shard.lock | 18 +++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/place/staff_api.cr b/drivers/place/staff_api.cr index 8e317093973..6e4ffac3b50 100644 --- a/drivers/place/staff_api.cr +++ b/drivers/place/staff_api.cr @@ -959,7 +959,7 @@ class Place::StaffAPI < PlaceOS::Driver params = URI::Params.new params["top"] = top.to_s if top response = get("/api/staff/v1/teams/#{team_id}/#{channel_id}", params, headers: authentication) - raise "issue getting teams channel messages (team #{team_id}, channel #{channel_id}): #{response.status_code}, body: #{response.body}" unless response.success? + raise "error getting teams channel messages (team #{team_id}, channel #{channel_id}): #{response.status_code}, body: #{response.body}" unless response.success? JSON.parse(response.body) end @@ -967,12 +967,12 @@ class Place::StaffAPI < PlaceOS::Driver def get_channel_message(team_id : String, channel_id : String, message_id : String) logger.debug { "Getting teams #{team_id} channel #{channel_id} message id #{message_id}, note: graphAPI only" } response = get("/api/staff/v1/teams/#{team_id}/#{channel_id}/#{message_id}", headers: authentication) - raise "issue getting teams channel message (team #{team_id}, channel #{channel_id}, message id #{message_id}): #{response.status_code}, body: #{response.body}" unless response.success? + raise "error getting teams channel message (team #{team_id}, channel #{channel_id}, message id #{message_id}): #{response.status_code}, body: #{response.body}" unless response.success? JSON.parse(response.body) end @[Security(Level::Support)] - def send_channel_message(team_id : String, channel_id : String, message : String, content_type : String? = nil) : Bool + def send_channel_message(team_id : String, channel_id : String, message : String, content_type : String? = nil) logger.debug { "Sending teams #{team_id} channel #{channel_id} content_type #{content_type}, message #{message}, note: graphAPI only" } params = URI::Params.new params["type"] = content_type if content_type @@ -983,7 +983,8 @@ class Place::StaffAPI < PlaceOS::Driver "Content-Type" => "text/plain", }) ) - response.status_code == 201 + raise "error sending teams channel message (team #{team_id}, channel #{channel_id}, message id #{message_id}): #{response.status_code}, body: #{response.body}" unless response.success? + JSON.parse(response.body) end end diff --git a/shard.lock b/shard.lock index 7ed8fdd5677..3c7b917f905 100644 --- a/shard.lock +++ b/shard.lock @@ -7,7 +7,7 @@ shards: action-controller: git: https://github.com/spider-gazelle/action-controller.git - version: 7.5.3 + version: 7.6.0 active-model: git: https://github.com/spider-gazelle/active-model.git @@ -143,7 +143,7 @@ shards: json-schema: git: https://github.com/spider-gazelle/json-schema.git - version: 1.3.1 + version: 1.3.2 jwt: git: https://github.com/crystal-community/jwt.git @@ -179,7 +179,7 @@ shards: office365: git: https://github.com/placeos/office365.git - version: 1.25.5 + version: 1.25.6 openssl_ext: git: https://github.com/spider-gazelle/openssl_ext.git @@ -199,7 +199,7 @@ shards: perf_tools: git: https://github.com/crystal-lang/perf-tools.git - version: 0.1.0+git.commit.e2c905b0f77758584cbee761dfe8681cbaf0a79f + version: 0.1.0+git.commit.c4e3f13c92b301605e341c0489885a1ba2b75c98 pg: git: https://github.com/will/crystal-pg.git @@ -207,7 +207,7 @@ shards: pg-orm: git: https://github.com/spider-gazelle/pg-orm.git - version: 1.1.2+git.commit.f14936937ad0787a75d04d9fed23ffab11e4c42d + version: 2.0.0+git.commit.e48103b0d97ae29d787b74babab309ca9878a3d9 pinger: git: https://github.com/spider-gazelle/pinger.git @@ -219,7 +219,7 @@ shards: placeos: git: https://github.com/placeos/crystal-client.git - version: 2.11.9 + version: 2.11.10 placeos-compiler: git: https://github.com/placeos/compiler.git @@ -231,7 +231,7 @@ shards: placeos-driver: git: https://github.com/placeos/driver.git - version: 7.9.3 + version: 7.9.5 placeos-log-backend: git: https://github.com/place-labs/log-backend.git @@ -239,7 +239,7 @@ shards: placeos-models: git: https://github.com/placeos/models.git - version: 9.64.0 + version: 9.64.1 pool: git: https://github.com/ysbaddaden/pool.git @@ -307,7 +307,7 @@ shards: ssh2: git: https://github.com/spider-gazelle/ssh2.cr.git - version: 1.7.0 + version: 1.7.1 stomp: git: https://github.com/spider-gazelle/stomp.git