lex-microsoft_teams 0.5.2 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -2
- data/CHANGELOG.md +34 -0
- data/CLAUDE.md +2 -2
- data/docs/plans/2026-03-19-teams-token-lifecycle-design.md +120 -0
- data/docs/plans/2026-03-19-teams-token-lifecycle-implementation.md +679 -0
- data/lib/legion/extensions/microsoft_teams/actors/auth_validator.rb +105 -0
- data/lib/legion/extensions/microsoft_teams/actors/cache_sync.rb +1 -5
- data/lib/legion/extensions/microsoft_teams/actors/direct_chat_poller.rb +2 -2
- data/lib/legion/extensions/microsoft_teams/actors/message_processor.rb +1 -1
- data/lib/legion/extensions/microsoft_teams/actors/observed_chat_poller.rb +1 -1
- data/lib/legion/extensions/microsoft_teams/actors/token_refresher.rb +103 -0
- data/lib/legion/extensions/microsoft_teams/client.rb +5 -2
- data/lib/legion/extensions/microsoft_teams/helpers/browser_auth.rb +1 -1
- data/lib/legion/extensions/microsoft_teams/helpers/callback_server.rb +7 -2
- data/lib/legion/extensions/microsoft_teams/helpers/client.rb +4 -0
- data/lib/legion/extensions/microsoft_teams/helpers/prompt_resolver.rb +2 -5
- data/lib/legion/extensions/microsoft_teams/helpers/subscription_registry.rb +1 -0
- data/lib/legion/extensions/microsoft_teams/helpers/token_cache.rb +66 -3
- data/lib/legion/extensions/microsoft_teams/local_cache/extractor.rb +1 -1
- data/lib/legion/extensions/microsoft_teams/local_cache/record_parser.rb +1 -1
- data/lib/legion/extensions/microsoft_teams/runners/bot.rb +4 -4
- data/lib/legion/extensions/microsoft_teams/runners/cache_ingest.rb +8 -9
- data/lib/legion/extensions/microsoft_teams/runners/channel_messages.rb +5 -5
- data/lib/legion/extensions/microsoft_teams/runners/channels.rb +6 -6
- data/lib/legion/extensions/microsoft_teams/runners/chats.rb +5 -5
- data/lib/legion/extensions/microsoft_teams/runners/meetings.rb +16 -16
- data/lib/legion/extensions/microsoft_teams/runners/messages.rb +5 -5
- data/lib/legion/extensions/microsoft_teams/runners/presence.rb +2 -2
- data/lib/legion/extensions/microsoft_teams/runners/subscriptions.rb +5 -5
- data/lib/legion/extensions/microsoft_teams/runners/teams.rb +3 -3
- data/lib/legion/extensions/microsoft_teams/runners/transcripts.rb +6 -6
- data/lib/legion/extensions/microsoft_teams/version.rb +1 -1
- metadata +5 -2
- data/lib/legion/extensions/microsoft_teams/transport.rb +0 -11
|
@@ -9,53 +9,53 @@ module Legion
|
|
|
9
9
|
module Meetings
|
|
10
10
|
include Legion::Extensions::MicrosoftTeams::Helpers::Client
|
|
11
11
|
|
|
12
|
-
def list_meetings(user_id
|
|
13
|
-
response = graph_connection(**).get("
|
|
12
|
+
def list_meetings(user_id: 'me', **)
|
|
13
|
+
response = graph_connection(**).get("#{user_path(user_id)}/onlineMeetings")
|
|
14
14
|
{ result: response.body }
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def get_meeting(
|
|
18
|
-
response = graph_connection(**).get("
|
|
17
|
+
def get_meeting(meeting_id:, user_id: 'me', **)
|
|
18
|
+
response = graph_connection(**).get("#{user_path(user_id)}/onlineMeetings/#{meeting_id}")
|
|
19
19
|
{ result: response.body }
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def create_meeting(
|
|
22
|
+
def create_meeting(subject:, start_time:, end_time:, user_id: 'me', **)
|
|
23
23
|
payload = {
|
|
24
24
|
subject: subject,
|
|
25
25
|
startDateTime: start_time,
|
|
26
26
|
endDateTime: end_time
|
|
27
27
|
}
|
|
28
|
-
response = graph_connection(**).post("
|
|
28
|
+
response = graph_connection(**).post("#{user_path(user_id)}/onlineMeetings", payload)
|
|
29
29
|
{ result: response.body }
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
def update_meeting(
|
|
32
|
+
def update_meeting(meeting_id:, user_id: 'me', subject: nil, start_time: nil, end_time: nil, **)
|
|
33
33
|
payload = {}
|
|
34
34
|
payload[:subject] = subject if subject
|
|
35
35
|
payload[:startDateTime] = start_time if start_time
|
|
36
36
|
payload[:endDateTime] = end_time if end_time
|
|
37
|
-
response = graph_connection(**).patch("
|
|
37
|
+
response = graph_connection(**).patch("#{user_path(user_id)}/onlineMeetings/#{meeting_id}", payload)
|
|
38
38
|
{ result: response.body }
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
def delete_meeting(
|
|
42
|
-
response = graph_connection(**).delete("
|
|
41
|
+
def delete_meeting(meeting_id:, user_id: 'me', **)
|
|
42
|
+
response = graph_connection(**).delete("#{user_path(user_id)}/onlineMeetings/#{meeting_id}")
|
|
43
43
|
{ result: response.body }
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
def get_meeting_by_join_url(
|
|
46
|
+
def get_meeting_by_join_url(join_url:, user_id: 'me', **)
|
|
47
47
|
params = { '$filter' => "joinWebUrl eq '#{join_url.gsub("'", "''")}'" }
|
|
48
|
-
response = graph_connection(**).get("
|
|
48
|
+
response = graph_connection(**).get("#{user_path(user_id)}/onlineMeetings", params)
|
|
49
49
|
{ result: response.body }
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
def list_attendance_reports(
|
|
53
|
-
response = graph_connection(**).get("
|
|
52
|
+
def list_attendance_reports(meeting_id:, user_id: 'me', **)
|
|
53
|
+
response = graph_connection(**).get("#{user_path(user_id)}/onlineMeetings/#{meeting_id}/attendanceReports")
|
|
54
54
|
{ result: response.body }
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
def get_attendance_report(
|
|
58
|
-
response = graph_connection(**).get("
|
|
57
|
+
def get_attendance_report(meeting_id:, report_id:, user_id: 'me', **)
|
|
58
|
+
response = graph_connection(**).get("#{user_path(user_id)}/onlineMeetings/#{meeting_id}/attendanceReports/#{report_id}")
|
|
59
59
|
{ result: response.body }
|
|
60
60
|
end
|
|
61
61
|
|
|
@@ -11,31 +11,31 @@ module Legion
|
|
|
11
11
|
|
|
12
12
|
def list_chat_messages(chat_id:, top: 50, **)
|
|
13
13
|
params = { '$top' => top }
|
|
14
|
-
response = graph_connection(**).get("
|
|
14
|
+
response = graph_connection(**).get("chats/#{chat_id}/messages", params)
|
|
15
15
|
{ result: response.body }
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def get_chat_message(chat_id:, message_id:, **)
|
|
19
|
-
response = graph_connection(**).get("
|
|
19
|
+
response = graph_connection(**).get("chats/#{chat_id}/messages/#{message_id}")
|
|
20
20
|
{ result: response.body }
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def send_chat_message(chat_id:, content:, content_type: 'text', attachments: [], **)
|
|
24
24
|
payload = { body: { contentType: content_type, content: content } }
|
|
25
25
|
payload[:attachments] = attachments unless attachments.empty?
|
|
26
|
-
response = graph_connection(**).post("
|
|
26
|
+
response = graph_connection(**).post("chats/#{chat_id}/messages", payload)
|
|
27
27
|
{ result: response.body }
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def reply_to_chat_message(chat_id:, message_id:, content:, content_type: 'text', **)
|
|
31
31
|
payload = { body: { contentType: content_type, content: content } }
|
|
32
|
-
response = graph_connection(**).post("
|
|
32
|
+
response = graph_connection(**).post("chats/#{chat_id}/messages/#{message_id}/replies", payload)
|
|
33
33
|
{ result: response.body }
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def list_message_replies(chat_id:, message_id:, top: 50, **)
|
|
37
37
|
params = { '$top' => top }
|
|
38
|
-
response = graph_connection(**).get("
|
|
38
|
+
response = graph_connection(**).get("chats/#{chat_id}/messages/#{message_id}/replies", params)
|
|
39
39
|
{ result: response.body }
|
|
40
40
|
end
|
|
41
41
|
|
|
@@ -9,9 +9,9 @@ module Legion
|
|
|
9
9
|
module Presence
|
|
10
10
|
include Legion::Extensions::MicrosoftTeams::Helpers::Client
|
|
11
11
|
|
|
12
|
-
def get_presence(user_id
|
|
12
|
+
def get_presence(user_id: 'me', **)
|
|
13
13
|
conn = graph_connection(**)
|
|
14
|
-
response = conn.get("
|
|
14
|
+
response = conn.get("#{user_path(user_id)}/presence")
|
|
15
15
|
body = response.body || {}
|
|
16
16
|
{
|
|
17
17
|
availability: body['availability'],
|
|
@@ -10,12 +10,12 @@ module Legion
|
|
|
10
10
|
include Legion::Extensions::MicrosoftTeams::Helpers::Client
|
|
11
11
|
|
|
12
12
|
def list_subscriptions(**)
|
|
13
|
-
response = graph_connection(**).get('
|
|
13
|
+
response = graph_connection(**).get('subscriptions')
|
|
14
14
|
{ result: response.body }
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def get_subscription(subscription_id:, **)
|
|
18
|
-
response = graph_connection(**).get("
|
|
18
|
+
response = graph_connection(**).get("subscriptions/#{subscription_id}")
|
|
19
19
|
{ result: response.body }
|
|
20
20
|
end
|
|
21
21
|
|
|
@@ -29,18 +29,18 @@ module Legion
|
|
|
29
29
|
includeResourceData: include_resource_data
|
|
30
30
|
}
|
|
31
31
|
payload[:clientState] = client_state if client_state
|
|
32
|
-
response = graph_connection(**).post('
|
|
32
|
+
response = graph_connection(**).post('subscriptions', payload)
|
|
33
33
|
{ result: response.body }
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def renew_subscription(subscription_id:, expiration:, **)
|
|
37
37
|
payload = { expirationDateTime: expiration }
|
|
38
|
-
response = graph_connection(**).patch("
|
|
38
|
+
response = graph_connection(**).patch("subscriptions/#{subscription_id}", payload)
|
|
39
39
|
{ result: response.body }
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def delete_subscription(subscription_id:, **)
|
|
43
|
-
response = graph_connection(**).delete("
|
|
43
|
+
response = graph_connection(**).delete("subscriptions/#{subscription_id}")
|
|
44
44
|
{ result: response.body }
|
|
45
45
|
end
|
|
46
46
|
|
|
@@ -10,17 +10,17 @@ module Legion
|
|
|
10
10
|
include Legion::Extensions::MicrosoftTeams::Helpers::Client
|
|
11
11
|
|
|
12
12
|
def list_joined_teams(user_id: 'me', **)
|
|
13
|
-
response = graph_connection(**).get("
|
|
13
|
+
response = graph_connection(**).get("#{user_path(user_id)}/joinedTeams")
|
|
14
14
|
{ result: response.body }
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def get_team(team_id:, **)
|
|
18
|
-
response = graph_connection(**).get("
|
|
18
|
+
response = graph_connection(**).get("teams/#{team_id}")
|
|
19
19
|
{ result: response.body }
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def list_team_members(team_id:, **)
|
|
23
|
-
response = graph_connection(**).get("
|
|
23
|
+
response = graph_connection(**).get("teams/#{team_id}/members")
|
|
24
24
|
{ result: response.body }
|
|
25
25
|
end
|
|
26
26
|
|
|
@@ -14,22 +14,22 @@ module Legion
|
|
|
14
14
|
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
|
|
15
15
|
}.freeze
|
|
16
16
|
|
|
17
|
-
def list_transcripts(
|
|
18
|
-
response = graph_connection(**).get("
|
|
17
|
+
def list_transcripts(meeting_id:, user_id: 'me', **)
|
|
18
|
+
response = graph_connection(**).get("#{user_path(user_id)}/onlineMeetings/#{meeting_id}/transcripts")
|
|
19
19
|
{ result: response.body }
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
def get_transcript(
|
|
22
|
+
def get_transcript(meeting_id:, transcript_id:, user_id: 'me', **)
|
|
23
23
|
response = graph_connection(**).get(
|
|
24
|
-
"
|
|
24
|
+
"#{user_path(user_id)}/onlineMeetings/#{meeting_id}/transcripts/#{transcript_id}"
|
|
25
25
|
)
|
|
26
26
|
{ result: response.body }
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
def get_transcript_content(
|
|
29
|
+
def get_transcript_content(meeting_id:, transcript_id:, user_id: 'me', format: :vtt, **)
|
|
30
30
|
accept = CONTENT_TYPES.fetch(format)
|
|
31
31
|
response = graph_connection(**).get(
|
|
32
|
-
"
|
|
32
|
+
"#{user_path(user_id)}/onlineMeetings/#{meeting_id}/transcripts/#{transcript_id}/content"
|
|
33
33
|
) do |req|
|
|
34
34
|
req.headers['Accept'] = accept
|
|
35
35
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lex-microsoft_teams
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -71,13 +71,17 @@ files:
|
|
|
71
71
|
- docs/plans/2026-03-15-meetings-transcripts-design.md
|
|
72
72
|
- docs/plans/2026-03-16-delegated-oauth-browser-flow-design.md
|
|
73
73
|
- docs/plans/2026-03-16-delegated-oauth-browser-flow-plan.md
|
|
74
|
+
- docs/plans/2026-03-19-teams-token-lifecycle-design.md
|
|
75
|
+
- docs/plans/2026-03-19-teams-token-lifecycle-implementation.md
|
|
74
76
|
- lex-microsoft_teams.gemspec
|
|
75
77
|
- lib/legion/extensions/microsoft_teams.rb
|
|
78
|
+
- lib/legion/extensions/microsoft_teams/actors/auth_validator.rb
|
|
76
79
|
- lib/legion/extensions/microsoft_teams/actors/cache_bulk_ingest.rb
|
|
77
80
|
- lib/legion/extensions/microsoft_teams/actors/cache_sync.rb
|
|
78
81
|
- lib/legion/extensions/microsoft_teams/actors/direct_chat_poller.rb
|
|
79
82
|
- lib/legion/extensions/microsoft_teams/actors/message_processor.rb
|
|
80
83
|
- lib/legion/extensions/microsoft_teams/actors/observed_chat_poller.rb
|
|
84
|
+
- lib/legion/extensions/microsoft_teams/actors/token_refresher.rb
|
|
81
85
|
- lib/legion/extensions/microsoft_teams/client.rb
|
|
82
86
|
- lib/legion/extensions/microsoft_teams/helpers/browser_auth.rb
|
|
83
87
|
- lib/legion/extensions/microsoft_teams/helpers/callback_server.rb
|
|
@@ -104,7 +108,6 @@ files:
|
|
|
104
108
|
- lib/legion/extensions/microsoft_teams/runners/subscriptions.rb
|
|
105
109
|
- lib/legion/extensions/microsoft_teams/runners/teams.rb
|
|
106
110
|
- lib/legion/extensions/microsoft_teams/runners/transcripts.rb
|
|
107
|
-
- lib/legion/extensions/microsoft_teams/transport.rb
|
|
108
111
|
- lib/legion/extensions/microsoft_teams/transport/exchanges/messages.rb
|
|
109
112
|
- lib/legion/extensions/microsoft_teams/transport/messages/teams_message.rb
|
|
110
113
|
- lib/legion/extensions/microsoft_teams/transport/queues/messages_process.rb
|