lex-microsoft_teams 0.6.31 → 0.6.33
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/CHANGELOG.md +17 -0
- data/lib/legion/extensions/microsoft_teams/absorbers/meeting.rb +39 -5
- data/lib/legion/extensions/microsoft_teams/actors/api_ingest.rb +2 -2
- data/lib/legion/extensions/microsoft_teams/actors/cache_bulk_ingest.rb +2 -3
- data/lib/legion/extensions/microsoft_teams/actors/channel_poller.rb +1 -0
- data/lib/legion/extensions/microsoft_teams/actors/direct_chat_poller.rb +2 -1
- data/lib/legion/extensions/microsoft_teams/actors/incremental_sync.rb +4 -3
- data/lib/legion/extensions/microsoft_teams/actors/observed_chat_poller.rb +1 -0
- data/lib/legion/extensions/microsoft_teams/version.rb +1 -1
- data/lib/legion/extensions/microsoft_teams.rb +4 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 723db14b8f62ab569c8f93b935fbc4717260a584c6673ca75e2f2e72c81c38ea
|
|
4
|
+
data.tar.gz: 300dc06002ffcf6dfd3a786d3ce98be24e5853492b43f15402ecb0517eb176db
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dc20c2e5ad9536e53245d2fce484f9ee29b94a4ef4e208a184618eff57ba2830633097f1d578bb3980c453725a651485c3492b74b6001026b64dda2db252c6d7
|
|
7
|
+
data.tar.gz: 23dfc8be910133b1d6462094d6abe0a0c67b4c3d769a9dbe36d0cbb4535423efbd0bf96c8103b0967c7117f5956c9a506509d421df5f93aafd0f9ed37d813736
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.6.33] - 2026-04-03
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- Set `remote_invocable? false` — eliminates 19 auto-generated AMQP subscription actors on boot
|
|
9
|
+
- Add initial delays to Every actors: DirectChatPoller (60s), ObservedChatPoller (180s), ChannelPoller (300s), IncrementalSync (60s), ApiIngest (max of auth_delay+5 or 30s)
|
|
10
|
+
- Disable CacheBulkIngest until run-once-ever logic is implemented
|
|
11
|
+
|
|
12
|
+
## [0.6.32] - 2026-03-31
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- `IncrementalSync` actor: renamed `delay` to `time` so `Concurrent::TimerTask` actually uses the configured interval — was firing every 1s instead of every 120s
|
|
16
|
+
- `DirectChatPoller` default interval increased from 5s to 15s to reduce Graph API pressure
|
|
17
|
+
- `Meeting` absorber: renamed `handle` to `absorb` to match `Absorbers::Base` contract — `handle` was never called by the dispatch framework
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- `Meeting` absorber: URL pattern for meeting chat links (`teams.microsoft.com/l/chat/19:meeting_**`) with chat thread resolution — extracts thread ID, fetches `onlineMeetingInfo.joinWebUrl` from the chat, then resolves the full meeting object
|
|
21
|
+
|
|
5
22
|
## [0.6.31] - 2026-03-31
|
|
6
23
|
|
|
7
24
|
### Fixed
|
|
@@ -4,12 +4,13 @@ module Legion
|
|
|
4
4
|
module Extensions
|
|
5
5
|
module MicrosoftTeams
|
|
6
6
|
module Absorbers
|
|
7
|
-
class Meeting < Legion::Extensions::Absorbers::Base
|
|
7
|
+
class Meeting < Legion::Extensions::Absorbers::Base
|
|
8
8
|
pattern :url, 'teams.microsoft.com/l/meetup-join/*'
|
|
9
9
|
pattern :url, '*.teams.microsoft.com/meet/*'
|
|
10
|
+
pattern :url, 'teams.microsoft.com/l/chat/19:meeting_**'
|
|
10
11
|
description 'Absorbs Teams meeting transcripts, AI insights, and participants into Apollo'
|
|
11
12
|
|
|
12
|
-
def
|
|
13
|
+
def absorb(url: nil, content: nil, metadata: {}, context: {}) # rubocop:disable Lint/UnusedMethodArgument
|
|
13
14
|
report_progress(message: 'resolving meeting from link')
|
|
14
15
|
meeting = resolve_meeting(url)
|
|
15
16
|
return { success: false, error: 'could not resolve meeting' } unless meeting
|
|
@@ -57,7 +58,43 @@ module Legion
|
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
def resolve_meeting(url)
|
|
61
|
+
thread_id = extract_meeting_thread_id(url)
|
|
62
|
+
if thread_id
|
|
63
|
+
report_progress(message: 'resolving meeting from chat thread', percent: 5)
|
|
64
|
+
return resolve_meeting_from_chat(thread_id)
|
|
65
|
+
end
|
|
66
|
+
|
|
60
67
|
report_progress(message: 'looking up meeting by join URL', percent: 5)
|
|
68
|
+
resolve_meeting_by_join_url(url)
|
|
69
|
+
rescue StandardError => e
|
|
70
|
+
log.warn("Could not resolve meeting: #{e.message}")
|
|
71
|
+
nil
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def extract_meeting_thread_id(url)
|
|
75
|
+
uri = URI.parse(url)
|
|
76
|
+
match = uri.path.match(%r{/l/chat/(19:meeting_[^/]+)})
|
|
77
|
+
match&.[](1)
|
|
78
|
+
rescue URI::InvalidURIError => e
|
|
79
|
+
log.debug("extract_meeting_thread_id: #{e.message}")
|
|
80
|
+
nil
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def resolve_meeting_from_chat(thread_id)
|
|
84
|
+
chats_runner = Object.new.extend(Runners::Chats)
|
|
85
|
+
response = chats_runner.get_chat(chat_id: thread_id, token: graph_token)
|
|
86
|
+
body = response.is_a?(Hash) ? response[:result] : nil
|
|
87
|
+
return nil unless body.is_a?(Hash)
|
|
88
|
+
|
|
89
|
+
join_url = body.dig('onlineMeetingInfo', 'joinWebUrl') ||
|
|
90
|
+
body.dig(:onlineMeetingInfo, :joinWebUrl)
|
|
91
|
+
return resolve_meeting_by_join_url(join_url) if join_url
|
|
92
|
+
|
|
93
|
+
log.debug("Chat #{thread_id} has no onlineMeetingInfo, using chat metadata")
|
|
94
|
+
{ 'id' => thread_id, 'subject' => body['topic'] || body[:topic] || 'meeting chat' }
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def resolve_meeting_by_join_url(url)
|
|
61
98
|
response = meetings_runner.get_meeting_by_join_url(join_url: url, token: graph_token)
|
|
62
99
|
return nil unless response.is_a?(Hash)
|
|
63
100
|
|
|
@@ -68,9 +105,6 @@ module Legion
|
|
|
68
105
|
return nil unless items.is_a?(Array) && !items.empty?
|
|
69
106
|
|
|
70
107
|
items.first
|
|
71
|
-
rescue StandardError => e
|
|
72
|
-
log.warn("Could not resolve meeting: #{e.message}")
|
|
73
|
-
nil
|
|
74
108
|
end
|
|
75
109
|
|
|
76
110
|
def ingest_transcript(meeting_id, subject, results)
|
|
@@ -21,9 +21,9 @@ module Legion
|
|
|
21
21
|
if defined?(Legion::Extensions::MicrosoftTeams::Actor::AuthValidator)
|
|
22
22
|
auth_validator = Legion::Extensions::MicrosoftTeams::Actor::AuthValidator.allocate
|
|
23
23
|
base_delay = auth_validator.respond_to?(:delay) ? auth_validator.delay.to_f : 90.0
|
|
24
|
-
base_delay + 5.0
|
|
24
|
+
[base_delay + 5.0, 30].max
|
|
25
25
|
else
|
|
26
|
-
|
|
26
|
+
30
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
@@ -16,9 +16,8 @@ module Legion
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def enabled?
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
log.debug("CacheBulkIngest#enabled?: #{e.message}")
|
|
19
|
+
# TODO: implement run-once-ever via Data::Local flag so bulk ingest
|
|
20
|
+
# doesn't re-run on every restart
|
|
22
21
|
false
|
|
23
22
|
end
|
|
24
23
|
|
|
@@ -8,7 +8,7 @@ module Legion
|
|
|
8
8
|
include Legion::Extensions::MicrosoftTeams::Helpers::Client
|
|
9
9
|
include Legion::Extensions::MicrosoftTeams::Helpers::HighWaterMark
|
|
10
10
|
|
|
11
|
-
POLL_INTERVAL =
|
|
11
|
+
POLL_INTERVAL = 15
|
|
12
12
|
|
|
13
13
|
def initialize(**opts)
|
|
14
14
|
return unless enabled?
|
|
@@ -20,6 +20,7 @@ module Legion
|
|
|
20
20
|
def runner_class = Legion::Extensions::MicrosoftTeams::Runners::Bot
|
|
21
21
|
def runner_function = 'handle_message'
|
|
22
22
|
def time = settings_interval(:direct_poll_interval, POLL_INTERVAL)
|
|
23
|
+
def delay = 60
|
|
23
24
|
def run_now? = false
|
|
24
25
|
def use_runner? = false
|
|
25
26
|
def check_subtask? = false
|
|
@@ -11,15 +11,16 @@ module Legion
|
|
|
11
11
|
def check_subtask? = false
|
|
12
12
|
def generate_task? = false
|
|
13
13
|
def run_now? = false
|
|
14
|
+
def delay = 60
|
|
14
15
|
|
|
15
|
-
def
|
|
16
|
+
def time
|
|
16
17
|
settings = begin
|
|
17
18
|
Legion::Settings[:microsoft_teams] || {}
|
|
18
19
|
rescue StandardError => e
|
|
19
|
-
log.debug("IncrementalSync#
|
|
20
|
+
log.debug("IncrementalSync#time: #{e.message}")
|
|
20
21
|
{}
|
|
21
22
|
end
|
|
22
|
-
settings.dig(:ingest, :incremental_interval) ||
|
|
23
|
+
settings.dig(:ingest, :incremental_interval) || 120
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def enabled?
|
|
@@ -19,6 +19,7 @@ module Legion
|
|
|
19
19
|
def runner_class = Legion::Extensions::MicrosoftTeams::Runners::Bot
|
|
20
20
|
def runner_function = 'observe_message'
|
|
21
21
|
def time = settings_interval(:observe_poll_interval, POLL_INTERVAL)
|
|
22
|
+
def delay = 180
|
|
22
23
|
def run_now? = false
|
|
23
24
|
def use_runner? = false
|
|
24
25
|
def check_subtask? = false
|