agentTriggerers method
- String agentId
The I1 trigger set of agentId (10 5.2 and 5.3, simplified): the active people who may
trigger it, in the order of people.
Targets are the channels whose operator.effective_agent_id is the agent and every
channel of a space whose default operator it is; their spaces count for space grants.
Triggerers are the active owners, the people with trigger in the access list of a target
channel, and the active members (membership not expired) of groups and the people that
hold a valid grant (not revoked, not expired) with trigger on a target channel, its
space or the instance. The fake has no thread operators (10 5.2 point 2).
Implementation
List<String> agentTriggerers(String agentId) {
final targets = [
for (final c in channels.values)
if ((c.json['operator'] as JsonMap?)?['effective_agent_id'] ==
agentId ||
spaces[c.spaceId]?['default_operator_agent_id'] == agentId)
c,
];
final targetIds = {for (final c in targets) c.id};
final targetSpaces = {
for (final c in targets) ?c.spaceId,
for (final s in spaces.values)
if (s['default_operator_agent_id'] == agentId) s['id']! as String,
};
final t = now();
bool valid(Object? expiresAt) =>
expiresAt == null || DateTime.parse(expiresAt as String).isAfter(t);
final found = <String>{
for (final p in people.values)
if (p.isOwner) p.id,
for (final c in targets)
for (final MapEntry(:key, :value) in c.access.entries)
if (value == 'trigger') key,
};
for (final g in grants.values) {
final target = g['target_id'];
final onTarget = switch (g['target_kind']) {
'instance' => true,
'space' => targetSpaces.contains(target),
'channel' => targetIds.contains(target),
_ => false,
};
if (g['revoked_at'] != null ||
!valid(g['expires_at']) ||
g['level'] != 'trigger' ||
!onTarget) {
continue;
}
final subject = g['subject_id']! as String;
if (g['subject_kind'] == 'user') found.add(subject);
if (g['subject_kind'] == 'group') {
for (final MapEntry(:key, :value)
in (groupMembers[subject] ?? {}).entries) {
if (valid(value['expires_at'])) found.add(key);
}
}
}
return [
for (final p in people.values)
if (found.contains(p.id) && p.kind == 'user' && p.status == 'active')
p.id,
];
}