@burgan-tech/morph-touch-runtime 0.0.6 → 0.0.8
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.
- package/burgan-tech-morph-touch-runtime-0.0.8.tgz +0 -0
- package/morph-touch/Functions/get-absence-entry.1.0.0.json +1 -1
- package/morph-touch/Functions/get-advisor-stats.1.0.0.json +1 -1
- package/morph-touch/Functions/get-available-slots.1.0.0.json +1 -1
- package/morph-touch/Functions/get-rezervations.1.0.0.json +1 -1
- package/morph-touch/Functions/src/GetAbsenceEntryMapping.csx +18 -4
- package/morph-touch/Functions/src/GetAdvisorStatsMapping.csx +22 -8
- package/morph-touch/Functions/src/GetAvailableSlotsMapping.csx +22 -14
- package/morph-touch/Functions/src/GetRezervationsMapping.csx +46 -9
- package/morph-touch/Functions/src/SendCancelNotificationMapping.csx +27 -2
- package/morph-touch/Tasks/login-for-chat.1.0.0.json +27 -0
- package/morph-touch/Tasks/register-for-chat.1.0.0.json +27 -0
- package/morph-touch/Workflows/chat-room.json +273 -14
- package/morph-touch/Workflows/notification-sender.json +2 -2
- package/morph-touch/Workflows/rezervation-start.json +39 -2
- package/morph-touch/Workflows/rezervation-transfer.json +44 -7
- package/morph-touch/Workflows/rezervation-update.json +4 -4
- package/morph-touch/Workflows/rezervation.json +135 -45
- package/morph-touch/Workflows/src/CanStartRezervationTimerMapping.csx +18 -3
- package/morph-touch/Workflows/src/ChatRoomRemoveMapping.csx +10 -1
- package/morph-touch/Workflows/src/ChatRoomTransferInviteMapping.csx +10 -1
- package/morph-touch/Workflows/src/ChatRoomTransferRemoveMapping.csx +9 -1
- package/morph-touch/Workflows/src/ChatRoomUpdateMapping.csx +10 -1
- package/morph-touch/Workflows/src/CheckDuplicateRezervationMapping.csx +17 -3
- package/morph-touch/Workflows/src/CheckRandevuTimeMapping.csx +16 -2
- package/morph-touch/Workflows/src/CreateChatRoomForRezervationMapping.csx +12 -2
- package/morph-touch/Workflows/src/CreatePermanentChatRoomMapping.csx +11 -1
- package/morph-touch/Workflows/src/EnrichRezervationsForTransferMapping.csx +18 -4
- package/morph-touch/Workflows/src/FetchRoomMessagesForSummaryMapping.csx +10 -2
- package/morph-touch/Workflows/src/InviteAdvisorForRandevuUpdateMapping.csx +10 -1
- package/morph-touch/Workflows/src/InviteNewAdvisorToRezervationRoomMapping.csx +11 -2
- package/morph-touch/Workflows/src/InviteNewParticipantToRandevuRoomMapping.csx +10 -1
- package/morph-touch/Workflows/src/JoinChatRoomForAddParticipantMapping.csx +5 -1
- package/morph-touch/Workflows/src/JoinChatRoomForRandevuStartMapping.csx +5 -1
- package/morph-touch/Workflows/src/JoinChatRoomForRezervationMapping.csx +4 -0
- package/morph-touch/Workflows/src/JoinMatrixRoomMapping.csx +11 -1
- package/morph-touch/Workflows/src/JoinUserToRoomMapping.csx +6 -0
- package/morph-touch/Workflows/src/LoginForAddParticipantChatMapping.csx +35 -6
- package/morph-touch/Workflows/src/LoginForChatRoomMapping.csx +121 -0
- package/morph-touch/Workflows/src/LoginForJoinUserToRoomMapping.csx +142 -0
- package/morph-touch/Workflows/src/LoginForRandevuStartChatMapping.csx +35 -10
- package/morph-touch/Workflows/src/LoginForTransferChatMapping.csx +153 -0
- package/morph-touch/Workflows/src/RegisterForAddParticipantChatMapping.csx +74 -0
- package/morph-touch/Workflows/src/RegisterForChatRoomMapping.csx +74 -0
- package/morph-touch/Workflows/src/RegisterForJoinUserToRoomMapping.csx +87 -0
- package/morph-touch/Workflows/src/RegisterForRandevuStartChatMapping.csx +80 -0
- package/morph-touch/Workflows/src/RegisterForTransferChatMapping.csx +113 -0
- package/morph-touch/Workflows/src/SendPushNotificationMapping.csx +25 -4
- package/morph-touch/Workflows/src/SendSmsNotificationMapping.csx +25 -4
- package/morph-touch/Workflows/src/SendSummaryToNewRoomMapping.csx +10 -2
- package/morph-touch/Workflows/src/SetRoomHistoryVisibilityMapping.csx +12 -4
- package/morph-touch/Workflows/src/ValidateDateForRezervationMapping.csx +16 -2
- package/morph-touch/Workflows/src/ValidateSlotForRandevuUpdateMapping.csx +22 -15
- package/morph-touch/Workflows/src/ValidateSlotForRezervationMapping.csx +23 -16
- package/morph-touch/Workflows/src/ValidateTransferMapping.csx +16 -2
- package/morph-touch/doc/morph-touch-domain.en.md +420 -6
- package/morph-touch/doc/morph-touch-domain.md +423 -6
- package/package.json +1 -1
- package/vnext.config.json +1 -1
- package/burgan-tech-morph-touch-runtime-0.0.6.tgz +0 -0
|
@@ -84,7 +84,7 @@ public class CheckDuplicateRezervationMapping : ScriptBase, IMapping
|
|
|
84
84
|
if (!string.IsNullOrEmpty(newStartStr) && !string.IsNullOrEmpty(newEndStr))
|
|
85
85
|
{
|
|
86
86
|
DateTime newStart = default, newEnd = default;
|
|
87
|
-
if (
|
|
87
|
+
if (TryParseToUtc(newStartStr, out newStart) && TryParseToUtc(newEndStr, out newEnd))
|
|
88
88
|
{
|
|
89
89
|
foreach (var item in items)
|
|
90
90
|
{
|
|
@@ -97,8 +97,8 @@ public class CheckDuplicateRezervationMapping : ScriptBase, IMapping
|
|
|
97
97
|
continue;
|
|
98
98
|
|
|
99
99
|
DateTime existingStart = default, existingEnd = default;
|
|
100
|
-
if (!
|
|
101
|
-
!
|
|
100
|
+
if (!TryParseToUtc(existingStartStr, out existingStart) ||
|
|
101
|
+
!TryParseToUtc(existingEndStr, out existingEnd))
|
|
102
102
|
continue;
|
|
103
103
|
|
|
104
104
|
if (existingStart < newEnd && existingEnd > newStart)
|
|
@@ -114,6 +114,20 @@ public class CheckDuplicateRezervationMapping : ScriptBase, IMapping
|
|
|
114
114
|
return Task.FromResult(new ScriptResponse());
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
private bool TryParseToUtc(string dateStr, out DateTime utcDateTime)
|
|
118
|
+
{
|
|
119
|
+
utcDateTime = default;
|
|
120
|
+
if (string.IsNullOrEmpty(dateStr)) return false;
|
|
121
|
+
if (DateTimeOffset.TryParse(dateStr,
|
|
122
|
+
System.Globalization.CultureInfo.InvariantCulture,
|
|
123
|
+
System.Globalization.DateTimeStyles.None, out var dto))
|
|
124
|
+
{
|
|
125
|
+
utcDateTime = dto.UtcDateTime;
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
|
|
117
131
|
private string GetString(dynamic obj, string name)
|
|
118
132
|
{
|
|
119
133
|
if (obj == null) return null;
|
|
@@ -32,10 +32,10 @@ public class CheckRandevuTimeMapping : ScriptBase, IMapping
|
|
|
32
32
|
throw new InvalidOperationException("MEET_NOT_STARTED: startDateTime is required");
|
|
33
33
|
|
|
34
34
|
DateTime startDateTime;
|
|
35
|
-
if (!
|
|
35
|
+
if (!TryParseToUtc(startDateTimeStr, out startDateTime))
|
|
36
36
|
throw new InvalidOperationException("MEET_NOT_STARTED: Invalid startDateTime format");
|
|
37
37
|
|
|
38
|
-
var now = DateTime.UtcNow
|
|
38
|
+
var now = DateTime.UtcNow;
|
|
39
39
|
var diff = startDateTime - now;
|
|
40
40
|
|
|
41
41
|
if (diff.TotalMinutes > MaxMinutesBeforeStart)
|
|
@@ -50,6 +50,20 @@ public class CheckRandevuTimeMapping : ScriptBase, IMapping
|
|
|
50
50
|
return Task.FromResult(new ScriptResponse { Data = result });
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
private bool TryParseToUtc(string dateStr, out DateTime utcDateTime)
|
|
54
|
+
{
|
|
55
|
+
utcDateTime = default;
|
|
56
|
+
if (string.IsNullOrEmpty(dateStr)) return false;
|
|
57
|
+
if (DateTimeOffset.TryParse(dateStr,
|
|
58
|
+
System.Globalization.CultureInfo.InvariantCulture,
|
|
59
|
+
System.Globalization.DateTimeStyles.None, out var dto))
|
|
60
|
+
{
|
|
61
|
+
utcDateTime = dto.UtcDateTime;
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
53
67
|
private string GetString(dynamic obj, string name)
|
|
54
68
|
{
|
|
55
69
|
if (obj == null) return null;
|
|
@@ -25,6 +25,11 @@ public class CreateChatRoomForRezervationMapping : ScriptBase, IMapping
|
|
|
25
25
|
var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
|
|
26
26
|
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
27
27
|
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
28
|
+
|
|
29
|
+
var SynapseServer = await GetSecretAsync(secretName, "workflow-secret", "SynapseServer");
|
|
30
|
+
if (string.IsNullOrWhiteSpace(SynapseServer))
|
|
31
|
+
throw new InvalidOperationException("SynapseServer secret is required");
|
|
32
|
+
|
|
28
33
|
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/createRoom";
|
|
29
34
|
httpTask.SetUrl(fullUrl);
|
|
30
35
|
|
|
@@ -40,15 +45,20 @@ public class CreateChatRoomForRezervationMapping : ScriptBase, IMapping
|
|
|
40
45
|
|
|
41
46
|
var inviteList = new List<string>();
|
|
42
47
|
if (!string.IsNullOrWhiteSpace(advisorId))
|
|
43
|
-
inviteList.Add(advisorId.StartsWith("@") ? advisorId : $"@{advisorId}:
|
|
48
|
+
inviteList.Add(advisorId.StartsWith("@") ? advisorId : $"@{advisorId}:{SynapseServer}");
|
|
49
|
+
|
|
50
|
+
var chatIntegration = data?.chatIntegration;
|
|
51
|
+
var sessionId = chatIntegration != null ? GetString(chatIntegration, "sessionId") : null;
|
|
44
52
|
|
|
45
53
|
var headers = new Dictionary<string, string>
|
|
46
54
|
{
|
|
47
55
|
["Content-Type"] = "application/json",
|
|
48
56
|
["Accept"] = "application/json",
|
|
49
57
|
["X-Matrix-User"] = user,
|
|
50
|
-
|
|
58
|
+
["x-matrix-user"] = user
|
|
51
59
|
};
|
|
60
|
+
if (!string.IsNullOrWhiteSpace(sessionId))
|
|
61
|
+
headers["Authorization"] = "Bearer " + sessionId;
|
|
52
62
|
httpTask.SetHeaders(headers);
|
|
53
63
|
|
|
54
64
|
var body = new
|
|
@@ -30,6 +30,11 @@ public class CreatePermanentChatRoomMapping : ScriptBase, IMapping
|
|
|
30
30
|
var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
|
|
31
31
|
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
32
32
|
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
33
|
+
|
|
34
|
+
var SynapseServer = await GetSecretAsync(secretName, "workflow-secret", "SynapseServer");
|
|
35
|
+
if (string.IsNullOrWhiteSpace(SynapseServer))
|
|
36
|
+
throw new InvalidOperationException("SynapseServer secret is required");
|
|
37
|
+
|
|
33
38
|
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/createRoom";
|
|
34
39
|
httpTask.SetUrl(fullUrl);
|
|
35
40
|
|
|
@@ -53,7 +58,10 @@ public class CreatePermanentChatRoomMapping : ScriptBase, IMapping
|
|
|
53
58
|
|
|
54
59
|
var inviteList = new List<string>();
|
|
55
60
|
if (!string.IsNullOrWhiteSpace(advisorId))
|
|
56
|
-
inviteList.Add(advisorId.StartsWith("@") ? advisorId : $"@{advisorId}:
|
|
61
|
+
inviteList.Add(advisorId.StartsWith("@") ? advisorId : $"@{advisorId}:{SynapseServer}");
|
|
62
|
+
|
|
63
|
+
var chatIntegration = data?.chatIntegration;
|
|
64
|
+
var sessionId = GetString(chatIntegration, "sessionId");
|
|
57
65
|
|
|
58
66
|
var headers = new Dictionary<string, string>
|
|
59
67
|
{
|
|
@@ -61,6 +69,8 @@ public class CreatePermanentChatRoomMapping : ScriptBase, IMapping
|
|
|
61
69
|
["Accept"] = "application/json",
|
|
62
70
|
["X-Matrix-User"] = user
|
|
63
71
|
};
|
|
72
|
+
if (!string.IsNullOrWhiteSpace(sessionId))
|
|
73
|
+
headers["Authorization"] = "Bearer " + sessionId;
|
|
64
74
|
httpTask.SetHeaders(headers);
|
|
65
75
|
|
|
66
76
|
var body = new
|
|
@@ -148,7 +148,7 @@ public class EnrichRezervationsForTransferMapping : ScriptBase, IMapping
|
|
|
148
148
|
DateTime rezStart = DateTime.MinValue;
|
|
149
149
|
DateTime rezEnd = DateTime.MinValue;
|
|
150
150
|
if (!string.IsNullOrEmpty(rezStartStr) && !string.IsNullOrEmpty(rezEndStr) &&
|
|
151
|
-
|
|
151
|
+
TryParseToUtc(rezStartStr, out rezStart) && TryParseToUtc(rezEndStr, out rezEnd) &&
|
|
152
152
|
allItems != null)
|
|
153
153
|
{
|
|
154
154
|
foreach (var item in allItems)
|
|
@@ -166,7 +166,7 @@ public class EnrichRezervationsForTransferMapping : ScriptBase, IMapping
|
|
|
166
166
|
|
|
167
167
|
DateTime itemStart = DateTime.MinValue;
|
|
168
168
|
DateTime itemEnd = DateTime.MinValue;
|
|
169
|
-
if (
|
|
169
|
+
if (TryParseToUtc(itemStartStr, out itemStart) && TryParseToUtc(itemEndStr, out itemEnd))
|
|
170
170
|
{
|
|
171
171
|
if (itemStart < rezEnd && itemEnd > rezStart)
|
|
172
172
|
{
|
|
@@ -351,7 +351,7 @@ public class EnrichRezervationsForTransferMapping : ScriptBase, IMapping
|
|
|
351
351
|
|
|
352
352
|
DateTime startDateTime = DateTime.MinValue;
|
|
353
353
|
DateTime endDateTime = DateTime.MinValue;
|
|
354
|
-
if (!
|
|
354
|
+
if (!TryParseToUtc(startDateTimeStr, out startDateTime) || !TryParseToUtc(endDateTimeStr, out endDateTime))
|
|
355
355
|
continue;
|
|
356
356
|
|
|
357
357
|
if (date.Date < startDateTime.Date || date.Date > endDateTime.Date)
|
|
@@ -442,7 +442,7 @@ public class EnrichRezervationsForTransferMapping : ScriptBase, IMapping
|
|
|
442
442
|
|
|
443
443
|
DateTime startDateTime = DateTime.MinValue;
|
|
444
444
|
DateTime endDateTime = DateTime.MinValue;
|
|
445
|
-
if (!
|
|
445
|
+
if (!TryParseToUtc(startDateTimeStr, out startDateTime) || !TryParseToUtc(endDateTimeStr, out endDateTime))
|
|
446
446
|
continue;
|
|
447
447
|
|
|
448
448
|
if (date.Date < startDateTime.Date || date.Date > endDateTime.Date)
|
|
@@ -470,6 +470,20 @@ public class EnrichRezervationsForTransferMapping : ScriptBase, IMapping
|
|
|
470
470
|
|
|
471
471
|
#region Helpers
|
|
472
472
|
|
|
473
|
+
private bool TryParseToUtc(string dateStr, out DateTime utcDateTime)
|
|
474
|
+
{
|
|
475
|
+
utcDateTime = default;
|
|
476
|
+
if (string.IsNullOrEmpty(dateStr)) return false;
|
|
477
|
+
if (DateTimeOffset.TryParse(dateStr,
|
|
478
|
+
System.Globalization.CultureInfo.InvariantCulture,
|
|
479
|
+
System.Globalization.DateTimeStyles.None, out var dto))
|
|
480
|
+
{
|
|
481
|
+
utcDateTime = dto.UtcDateTime;
|
|
482
|
+
return true;
|
|
483
|
+
}
|
|
484
|
+
return false;
|
|
485
|
+
}
|
|
486
|
+
|
|
473
487
|
private string GetString(dynamic obj, string name)
|
|
474
488
|
{
|
|
475
489
|
if (obj == null) return null;
|
|
@@ -64,11 +64,19 @@ public class FetchRoomMessagesForSummaryMapping : ScriptBase, IMapping
|
|
|
64
64
|
"/messages?dir=b&limit=100";
|
|
65
65
|
|
|
66
66
|
httpTask.SetUrl(fullUrl);
|
|
67
|
-
|
|
67
|
+
|
|
68
|
+
string sessionId = null;
|
|
69
|
+
if (HasProperty(data, "chatIntegration") && data.chatIntegration != null)
|
|
70
|
+
sessionId = GetString(data.chatIntegration, "sessionId");
|
|
71
|
+
|
|
72
|
+
var headers = new Dictionary<string, string>
|
|
68
73
|
{
|
|
69
74
|
["Accept"] = "application/json",
|
|
70
75
|
["X-Matrix-User"] = user
|
|
71
|
-
}
|
|
76
|
+
};
|
|
77
|
+
if (!string.IsNullOrWhiteSpace(sessionId))
|
|
78
|
+
headers["Authorization"] = "Bearer " + sessionId;
|
|
79
|
+
httpTask.SetHeaders(headers);
|
|
72
80
|
|
|
73
81
|
return new ScriptResponse();
|
|
74
82
|
}
|
|
@@ -40,17 +40,26 @@ public class InviteAdvisorForRandevuUpdateMapping : ScriptBase, IMapping
|
|
|
40
40
|
var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
|
|
41
41
|
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
42
42
|
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
43
|
+
|
|
44
|
+
var SynapseServer = await GetSecretAsync(secretName, "workflow-secret", "SynapseServer");
|
|
45
|
+
if (string.IsNullOrWhiteSpace(SynapseServer))
|
|
46
|
+
throw new InvalidOperationException("SynapseServer secret is required");
|
|
47
|
+
|
|
43
48
|
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/rooms/" + Uri.EscapeDataString(roomId ?? "") + "/invite";
|
|
44
49
|
httpTask.SetUrl(fullUrl);
|
|
45
50
|
|
|
51
|
+
var sessionId = GetString(chatIntegration, "sessionId");
|
|
52
|
+
|
|
46
53
|
var headers = new Dictionary<string, string>
|
|
47
54
|
{
|
|
48
55
|
["Content-Type"] = "application/json",
|
|
49
56
|
["Accept"] = "application/json",
|
|
50
57
|
["x-matrix-user"] = user.Trim()
|
|
51
58
|
};
|
|
59
|
+
if (!string.IsNullOrWhiteSpace(sessionId))
|
|
60
|
+
headers["Authorization"] = "Bearer " + sessionId;
|
|
52
61
|
httpTask.SetHeaders(headers);
|
|
53
|
-
var userId = (advisor?.Trim() ?? "").StartsWith("@") ? advisor.Trim() : $"@{advisor?.Trim()}:
|
|
62
|
+
var userId = (advisor?.Trim() ?? "").StartsWith("@") ? advisor.Trim() : $"@{advisor?.Trim()}:{SynapseServer}";
|
|
54
63
|
httpTask.SetBody(new { user_id = userId });
|
|
55
64
|
|
|
56
65
|
return new ScriptResponse();
|
|
@@ -8,7 +8,7 @@ using BBT.Workflow.Definitions;
|
|
|
8
8
|
/// Mapping for invite-user-to-rezervation-room HttpTask (Type 6).
|
|
9
9
|
/// Invites new advisor to existing Matrix room via native /_matrix/client/v3/rooms/{roomId}/invite.
|
|
10
10
|
/// APISIX converts X-Matrix-User header to Bearer token automatically.
|
|
11
|
-
/// Formats target user ID as @{user}:
|
|
11
|
+
/// Formats target user ID as @{user}:{SynapseServer} per Matrix spec.
|
|
12
12
|
/// </summary>
|
|
13
13
|
public class InviteNewAdvisorToRezervationRoomMapping : ScriptBase, IMapping
|
|
14
14
|
{
|
|
@@ -42,10 +42,17 @@ public class InviteNewAdvisorToRezervationRoomMapping : ScriptBase, IMapping
|
|
|
42
42
|
var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
|
|
43
43
|
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
44
44
|
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
45
|
+
|
|
46
|
+
var SynapseServer = await GetSecretAsync(secretName, "workflow-secret", "SynapseServer");
|
|
47
|
+
if (string.IsNullOrWhiteSpace(SynapseServer))
|
|
48
|
+
throw new InvalidOperationException("SynapseServer secret is required");
|
|
49
|
+
|
|
45
50
|
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/rooms/" + Uri.EscapeDataString(roomId) + "/invite";
|
|
46
51
|
httpTask.SetUrl(fullUrl);
|
|
47
52
|
|
|
48
|
-
var matrixUserId = advisor.Trim().StartsWith("@") ? advisor.Trim() : $"@{advisor.Trim()}:
|
|
53
|
+
var matrixUserId = advisor.Trim().StartsWith("@") ? advisor.Trim() : $"@{advisor.Trim()}:{SynapseServer}";
|
|
54
|
+
|
|
55
|
+
var sessionId = GetString(chatIntegration, "sessionId");
|
|
49
56
|
|
|
50
57
|
var headers = new Dictionary<string, string>
|
|
51
58
|
{
|
|
@@ -53,6 +60,8 @@ public class InviteNewAdvisorToRezervationRoomMapping : ScriptBase, IMapping
|
|
|
53
60
|
["Accept"] = "application/json",
|
|
54
61
|
["X-Matrix-User"] = user
|
|
55
62
|
};
|
|
63
|
+
if (!string.IsNullOrWhiteSpace(sessionId))
|
|
64
|
+
headers["Authorization"] = "Bearer " + sessionId;
|
|
56
65
|
httpTask.SetHeaders(headers);
|
|
57
66
|
|
|
58
67
|
httpTask.SetBody(new { user_id = matrixUserId });
|
|
@@ -38,9 +38,16 @@ public class InviteNewParticipantToRandevuRoomMapping : ScriptBase, IMapping
|
|
|
38
38
|
var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
|
|
39
39
|
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
40
40
|
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
41
|
+
|
|
42
|
+
var SynapseServer = await GetSecretAsync(secretName, "workflow-secret", "SynapseServer");
|
|
43
|
+
if (string.IsNullOrWhiteSpace(SynapseServer))
|
|
44
|
+
throw new InvalidOperationException("SynapseServer secret is required");
|
|
45
|
+
|
|
41
46
|
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/rooms/" + Uri.EscapeDataString(roomId ?? "") + "/invite";
|
|
42
47
|
httpTask.SetUrl(fullUrl);
|
|
43
48
|
|
|
49
|
+
var sessionId = GetString(chatIntegration, "sessionId");
|
|
50
|
+
|
|
44
51
|
var headers = new Dictionary<string, string>
|
|
45
52
|
{
|
|
46
53
|
["Content-Type"] = "application/json",
|
|
@@ -48,9 +55,11 @@ public class InviteNewParticipantToRandevuRoomMapping : ScriptBase, IMapping
|
|
|
48
55
|
};
|
|
49
56
|
if (!string.IsNullOrWhiteSpace(inviter))
|
|
50
57
|
headers["x-matrix-user"] = inviter.Trim();
|
|
58
|
+
if (!string.IsNullOrWhiteSpace(sessionId))
|
|
59
|
+
headers["Authorization"] = "Bearer " + sessionId;
|
|
51
60
|
|
|
52
61
|
httpTask.SetHeaders(headers);
|
|
53
|
-
var userId = newUserId.Trim().StartsWith("@") ? newUserId.Trim() : $"@{newUserId.Trim()}:
|
|
62
|
+
var userId = newUserId.Trim().StartsWith("@") ? newUserId.Trim() : $"@{newUserId.Trim()}:{SynapseServer}";
|
|
54
63
|
httpTask.SetBody(new { user_id = userId });
|
|
55
64
|
|
|
56
65
|
return new ScriptResponse();
|
|
@@ -6,7 +6,7 @@ using BBT.Workflow.Definitions;
|
|
|
6
6
|
|
|
7
7
|
/// <summary>
|
|
8
8
|
/// Mapping for join-chat-room-for-rezervation when used in add-participant-to-rezervation flow.
|
|
9
|
-
/// Uses x-matrix-user = newUserId (the invited participant joining).
|
|
9
|
+
/// Uses x-matrix-user = newUserId (the invited participant joining). Uses sessionId from preceding login task.
|
|
10
10
|
/// </summary>
|
|
11
11
|
public class JoinChatRoomForAddParticipantMapping : ScriptBase, IMapping
|
|
12
12
|
{
|
|
@@ -37,12 +37,16 @@ public class JoinChatRoomForAddParticipantMapping : ScriptBase, IMapping
|
|
|
37
37
|
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/join/" + Uri.EscapeDataString(roomId ?? "");
|
|
38
38
|
httpTask.SetUrl(fullUrl);
|
|
39
39
|
|
|
40
|
+
var sessionId = GetString(chatIntegration, "sessionId");
|
|
41
|
+
|
|
40
42
|
var headers = new Dictionary<string, string>
|
|
41
43
|
{
|
|
42
44
|
["Content-Type"] = "application/json",
|
|
43
45
|
["Accept"] = "application/json",
|
|
44
46
|
["x-matrix-user"] = newUserId.Trim()
|
|
45
47
|
};
|
|
48
|
+
if (!string.IsNullOrWhiteSpace(sessionId))
|
|
49
|
+
headers["Authorization"] = "Bearer " + sessionId;
|
|
46
50
|
|
|
47
51
|
httpTask.SetHeaders(headers);
|
|
48
52
|
httpTask.SetBody(new { });
|
|
@@ -6,7 +6,7 @@ using BBT.Workflow.Definitions;
|
|
|
6
6
|
|
|
7
7
|
/// <summary>
|
|
8
8
|
/// Mapping for join-chat-room-for-rezervation when used in rezervation-start flow.
|
|
9
|
-
/// Uses chatIntegration.roomId
|
|
9
|
+
/// Uses chatIntegration.roomId and sessionId (from preceding login task) for authentication.
|
|
10
10
|
/// </summary>
|
|
11
11
|
public class JoinChatRoomForRandevuStartMapping : ScriptBase, IMapping
|
|
12
12
|
{
|
|
@@ -44,12 +44,16 @@ public class JoinChatRoomForRandevuStartMapping : ScriptBase, IMapping
|
|
|
44
44
|
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/join/" + Uri.EscapeDataString(roomId ?? "");
|
|
45
45
|
httpTask.SetUrl(fullUrl);
|
|
46
46
|
|
|
47
|
+
var sessionId = GetString(chatIntegration, "sessionId");
|
|
48
|
+
|
|
47
49
|
var headers = new Dictionary<string, string>
|
|
48
50
|
{
|
|
49
51
|
["Content-Type"] = "application/json",
|
|
50
52
|
["Accept"] = "application/json",
|
|
51
53
|
["x-matrix-user"] = xMatrixUser.Trim()
|
|
52
54
|
};
|
|
55
|
+
if (!string.IsNullOrWhiteSpace(sessionId))
|
|
56
|
+
headers["Authorization"] = "Bearer " + sessionId;
|
|
53
57
|
|
|
54
58
|
httpTask.SetHeaders(headers);
|
|
55
59
|
httpTask.SetBody(new { });
|
|
@@ -39,12 +39,16 @@ public class JoinChatRoomForRezervationMapping : ScriptBase, IMapping
|
|
|
39
39
|
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/join/" + Uri.EscapeDataString(roomId ?? "");
|
|
40
40
|
httpTask.SetUrl(fullUrl);
|
|
41
41
|
|
|
42
|
+
var sessionId = GetString(chatIntegration, "sessionId");
|
|
43
|
+
|
|
42
44
|
var headers = new Dictionary<string, string>
|
|
43
45
|
{
|
|
44
46
|
["Content-Type"] = "application/json",
|
|
45
47
|
["Accept"] = "application/json",
|
|
46
48
|
["x-matrix-user"] = xMatrixUser.Trim()
|
|
47
49
|
};
|
|
50
|
+
if (!string.IsNullOrWhiteSpace(sessionId))
|
|
51
|
+
headers["Authorization"] = "Bearer " + sessionId;
|
|
48
52
|
|
|
49
53
|
httpTask.SetHeaders(headers);
|
|
50
54
|
httpTask.SetBody(new { });
|
|
@@ -27,23 +27,33 @@ public class JoinMatrixRoomMapping : ScriptBase, IMapping
|
|
|
27
27
|
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
28
28
|
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
29
29
|
|
|
30
|
+
var SynapseServer = await GetSecretAsync(secretName, "workflow-secret", "SynapseServer");
|
|
31
|
+
if (string.IsNullOrWhiteSpace(SynapseServer))
|
|
32
|
+
throw new InvalidOperationException("SynapseServer secret is required");
|
|
33
|
+
|
|
30
34
|
var data = context.Instance?.Data;
|
|
31
35
|
var user = data?.user?.ToString();
|
|
32
36
|
var instanceKey = context.Instance?.Key;
|
|
33
37
|
|
|
34
38
|
var prefixedName = $"{user}_{instanceKey}";
|
|
35
39
|
var aliasName = Regex.Replace(prefixedName.ToLower(), @"[^a-z0-9_]", "-");
|
|
36
|
-
var alias = $"#{aliasName}:
|
|
40
|
+
var alias = $"#{aliasName}:{SynapseServer}";
|
|
37
41
|
var encodedAlias = Uri.EscapeDataString(alias);
|
|
38
42
|
|
|
39
43
|
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/join/" + encodedAlias;
|
|
40
44
|
httpTask.SetUrl(fullUrl);
|
|
41
45
|
|
|
46
|
+
string sessionId = null;
|
|
47
|
+
if (data != null && HasProperty(data, "chatIntegration") && data.chatIntegration != null)
|
|
48
|
+
sessionId = GetString(data.chatIntegration, "sessionId");
|
|
49
|
+
|
|
42
50
|
var headers = new Dictionary<string, string>
|
|
43
51
|
{
|
|
44
52
|
["Content-Type"] = "application/json",
|
|
45
53
|
["X-Matrix-User"] = user
|
|
46
54
|
};
|
|
55
|
+
if (!string.IsNullOrWhiteSpace(sessionId))
|
|
56
|
+
headers["Authorization"] = "Bearer " + sessionId;
|
|
47
57
|
httpTask.SetHeaders(headers);
|
|
48
58
|
httpTask.SetBody(new { });
|
|
49
59
|
|
|
@@ -50,12 +50,18 @@ public class JoinUserToRoomMapping : ScriptBase, IMapping
|
|
|
50
50
|
xMatrixUser = colonIdx > 0 ? xMatrixUser.Substring(1, colonIdx - 1) : xMatrixUser.Substring(1);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
string joinSessionId = null;
|
|
54
|
+
if (HasProperty(data, "chatIntegration") && data.chatIntegration != null)
|
|
55
|
+
joinSessionId = GetString(data.chatIntegration, "joinSessionId");
|
|
56
|
+
|
|
53
57
|
var headers = new Dictionary<string, string>
|
|
54
58
|
{
|
|
55
59
|
["Content-Type"] = "application/json",
|
|
56
60
|
["Accept"] = "application/json",
|
|
57
61
|
["X-Matrix-User"] = xMatrixUser
|
|
58
62
|
};
|
|
63
|
+
if (!string.IsNullOrWhiteSpace(joinSessionId))
|
|
64
|
+
headers["Authorization"] = "Bearer " + joinSessionId;
|
|
59
65
|
httpTask.SetHeaders(headers);
|
|
60
66
|
|
|
61
67
|
httpTask.SetBody(new { });
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
2
3
|
using System.Threading.Tasks;
|
|
3
4
|
using BBT.Workflow.Scripting;
|
|
4
5
|
using BBT.Workflow.Definitions;
|
|
5
6
|
|
|
6
7
|
/// <summary>
|
|
7
8
|
/// Mapping for login-for-rezervation-chat when used in add-participant-to-rezervation flow.
|
|
9
|
+
/// Calls POST /_matrix/client/v3/login on Synapse.
|
|
8
10
|
/// Logs in as newUserId. Output merges session with existing chatIntegration (preserves roomId).
|
|
11
|
+
/// Stores access_token as sessionId for subsequent Matrix API calls.
|
|
9
12
|
/// </summary>
|
|
10
13
|
public class LoginForAddParticipantChatMapping : ScriptBase, IMapping
|
|
11
14
|
{
|
|
12
|
-
public Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
15
|
+
public async Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
13
16
|
{
|
|
14
17
|
var httpTask = task as HttpTask;
|
|
15
18
|
if (httpTask == null)
|
|
@@ -18,10 +21,36 @@ public class LoginForAddParticipantChatMapping : ScriptBase, IMapping
|
|
|
18
21
|
var data = context.Instance?.Data;
|
|
19
22
|
var newUserId = GetString(data, "newUserId");
|
|
20
23
|
if (string.IsNullOrWhiteSpace(newUserId))
|
|
21
|
-
return
|
|
24
|
+
return new ScriptResponse();
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
var secretName = GetConfigValue("DAPR_SECRET_STORE_NAME");
|
|
27
|
+
if (string.IsNullOrWhiteSpace(secretName))
|
|
28
|
+
throw new InvalidOperationException("DAPR_SECRET_STORE_NAME configuration is required");
|
|
29
|
+
|
|
30
|
+
var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
|
|
31
|
+
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
32
|
+
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
33
|
+
|
|
34
|
+
var synapsePassword = await GetSecretAsync(secretName, "workflow-secret", "SynapsePassword");
|
|
35
|
+
if (string.IsNullOrWhiteSpace(synapsePassword))
|
|
36
|
+
throw new InvalidOperationException("SynapsePassword secret is required");
|
|
37
|
+
|
|
38
|
+
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/login";
|
|
39
|
+
httpTask.SetUrl(fullUrl);
|
|
40
|
+
|
|
41
|
+
httpTask.SetHeaders(new Dictionary<string, string>
|
|
42
|
+
{
|
|
43
|
+
["Content-Type"] = "application/json",
|
|
44
|
+
["Accept"] = "application/json"
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
httpTask.SetBody(new
|
|
48
|
+
{
|
|
49
|
+
type = "m.login.password",
|
|
50
|
+
identifier = new { type = "m.id.user", user = newUserId.Trim() },
|
|
51
|
+
password = synapsePassword
|
|
52
|
+
});
|
|
53
|
+
return new ScriptResponse();
|
|
25
54
|
}
|
|
26
55
|
|
|
27
56
|
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
@@ -35,8 +64,8 @@ public class LoginForAddParticipantChatMapping : ScriptBase, IMapping
|
|
|
35
64
|
if (response?.isSuccess == true)
|
|
36
65
|
{
|
|
37
66
|
dynamic data = response.data;
|
|
38
|
-
string sessionId = GetString(data, "
|
|
39
|
-
string userId = GetString(data, "
|
|
67
|
+
string sessionId = GetString(data, "access_token");
|
|
68
|
+
string userId = GetString(data, "user_id");
|
|
40
69
|
string username = GetString(data, "username");
|
|
41
70
|
|
|
42
71
|
result.Data = new
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Threading.Tasks;
|
|
4
|
+
using BBT.Workflow.Scripting;
|
|
5
|
+
using BBT.Workflow.Definitions;
|
|
6
|
+
|
|
7
|
+
/// <summary>
|
|
8
|
+
/// Mapping for login-for-chat when used in chat-room workflow.
|
|
9
|
+
/// Calls POST /_matrix/client/v3/login on Synapse.
|
|
10
|
+
/// Logs in as data.user (the customer/room owner).
|
|
11
|
+
/// Stores access_token as sessionId in chatIntegration for subsequent Matrix API calls.
|
|
12
|
+
/// </summary>
|
|
13
|
+
public class LoginForChatRoomMapping : ScriptBase, IMapping
|
|
14
|
+
{
|
|
15
|
+
public async Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
|
|
16
|
+
{
|
|
17
|
+
var httpTask = task as HttpTask;
|
|
18
|
+
if (httpTask == null)
|
|
19
|
+
throw new InvalidOperationException("Task must be an HttpTask");
|
|
20
|
+
|
|
21
|
+
var secretName = GetConfigValue("DAPR_SECRET_STORE_NAME");
|
|
22
|
+
if (string.IsNullOrWhiteSpace(secretName))
|
|
23
|
+
throw new InvalidOperationException("DAPR_SECRET_STORE_NAME configuration is required");
|
|
24
|
+
|
|
25
|
+
var matrixBaseUrl = await GetSecretAsync(secretName, "workflow-secret", "MatrixBaseUrl");
|
|
26
|
+
if (string.IsNullOrWhiteSpace(matrixBaseUrl))
|
|
27
|
+
throw new InvalidOperationException("MatrixBaseUrl secret is required");
|
|
28
|
+
|
|
29
|
+
var synapsePassword = await GetSecretAsync(secretName, "workflow-secret", "SynapsePassword");
|
|
30
|
+
if (string.IsNullOrWhiteSpace(synapsePassword))
|
|
31
|
+
throw new InvalidOperationException("SynapsePassword secret is required");
|
|
32
|
+
|
|
33
|
+
var data = context.Instance?.Data;
|
|
34
|
+
var loginUsername = GetString(data, "user");
|
|
35
|
+
if (string.IsNullOrWhiteSpace(loginUsername))
|
|
36
|
+
throw new InvalidOperationException("Cannot determine login user: data.user is missing");
|
|
37
|
+
|
|
38
|
+
var fullUrl = matrixBaseUrl.TrimEnd('/') + "/_matrix/client/v3/login";
|
|
39
|
+
httpTask.SetUrl(fullUrl);
|
|
40
|
+
|
|
41
|
+
httpTask.SetHeaders(new Dictionary<string, string>
|
|
42
|
+
{
|
|
43
|
+
["Content-Type"] = "application/json",
|
|
44
|
+
["Accept"] = "application/json"
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
httpTask.SetBody(new
|
|
48
|
+
{
|
|
49
|
+
type = "m.login.password",
|
|
50
|
+
identifier = new { type = "m.id.user", user = "u" + loginUsername },
|
|
51
|
+
password = synapsePassword
|
|
52
|
+
});
|
|
53
|
+
return new ScriptResponse();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public Task<ScriptResponse> OutputHandler(ScriptContext context)
|
|
57
|
+
{
|
|
58
|
+
var result = new ScriptResponse();
|
|
59
|
+
var response = context.Body;
|
|
60
|
+
var instanceData = context.Instance?.Data;
|
|
61
|
+
|
|
62
|
+
string existingRoomId = null;
|
|
63
|
+
if (instanceData != null && HasProperty(instanceData, "chatIntegration") && instanceData.chatIntegration != null)
|
|
64
|
+
existingRoomId = GetString(instanceData.chatIntegration, "roomId");
|
|
65
|
+
|
|
66
|
+
if (response?.isSuccess == true)
|
|
67
|
+
{
|
|
68
|
+
dynamic data = response.data;
|
|
69
|
+
string sessionId = GetString(data, "access_token");
|
|
70
|
+
string userId = GetString(data, "user_id");
|
|
71
|
+
string username = GetString(data, "username");
|
|
72
|
+
|
|
73
|
+
result.Data = new
|
|
74
|
+
{
|
|
75
|
+
chatIntegration = new
|
|
76
|
+
{
|
|
77
|
+
sessionId,
|
|
78
|
+
userId,
|
|
79
|
+
username,
|
|
80
|
+
roomId = existingRoomId,
|
|
81
|
+
error = (string)null,
|
|
82
|
+
errorCode = (string)null
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
else
|
|
87
|
+
{
|
|
88
|
+
string errorMessage = response?.errorMessage?.ToString() ?? "Chat login failed";
|
|
89
|
+
string statusCode = response?.statusCode != null ? response.statusCode.ToString() : null;
|
|
90
|
+
result.Data = new
|
|
91
|
+
{
|
|
92
|
+
chatIntegration = new
|
|
93
|
+
{
|
|
94
|
+
sessionId = (string)null,
|
|
95
|
+
userId = (string)null,
|
|
96
|
+
username = (string)null,
|
|
97
|
+
roomId = existingRoomId,
|
|
98
|
+
error = errorMessage,
|
|
99
|
+
errorCode = statusCode
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return Task.FromResult(result);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private string GetString(dynamic obj, string name)
|
|
108
|
+
{
|
|
109
|
+
if (obj == null) return null;
|
|
110
|
+
try
|
|
111
|
+
{
|
|
112
|
+
if (HasProperty(obj, name))
|
|
113
|
+
{
|
|
114
|
+
var v = GetPropertyValue(obj, name);
|
|
115
|
+
return v?.ToString();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch { }
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|