diff --git a/Elsa.sln b/Elsa.sln
index 34eb44ccf..d206732dd 100644
--- a/Elsa.sln
+++ b/Elsa.sln
@@ -76,8 +76,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Common", "src\modules\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.EntityFrameworkCore", "src\modules\Elsa.EntityFrameworkCore\Elsa.EntityFrameworkCore.csproj", "{7CC95512-7F44-45C3-A669-95B7048D4730}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Telnyx", "src\modules\Elsa.Telnyx\Elsa.Telnyx.csproj", "{F09B30F7-AF33-44D7-B835-099D1F72A37E}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Email", "src\modules\Elsa.Email\Elsa.Email.csproj", "{1E5BD8D9-55BE-41E2-B389-6AB9F26C22AF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{986E5482-0482-448C-B9E4-EC67A9474B85}"
@@ -511,10 +509,6 @@ Global
{7CC95512-7F44-45C3-A669-95B7048D4730}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7CC95512-7F44-45C3-A669-95B7048D4730}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7CC95512-7F44-45C3-A669-95B7048D4730}.Release|Any CPU.Build.0 = Release|Any CPU
- {F09B30F7-AF33-44D7-B835-099D1F72A37E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F09B30F7-AF33-44D7-B835-099D1F72A37E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F09B30F7-AF33-44D7-B835-099D1F72A37E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F09B30F7-AF33-44D7-B835-099D1F72A37E}.Release|Any CPU.Build.0 = Release|Any CPU
{1E5BD8D9-55BE-41E2-B389-6AB9F26C22AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E5BD8D9-55BE-41E2-B389-6AB9F26C22AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E5BD8D9-55BE-41E2-B389-6AB9F26C22AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -926,7 +920,6 @@ Global
{30B49E42-AE61-4F7C-981F-923F07BB3986} = {5948B0A5-7873-4DBB-BA03-EB283D6EA91B}
{D229105F-6879-4452-9189-75DE060C0F4C} = {5BA4A8FA-F7F4-45B3-AEC8-8886D35AAC79}
{7CC95512-7F44-45C3-A669-95B7048D4730} = {9B4F139F-7D26-435C-A561-89E65A67A8E5}
- {F09B30F7-AF33-44D7-B835-099D1F72A37E} = {EBD0CF78-C5D7-4B4B-94C9-C5D8C20B6F59}
{1E5BD8D9-55BE-41E2-B389-6AB9F26C22AF} = {EBD0CF78-C5D7-4B4B-94C9-C5D8C20B6F59}
{3246883E-2FA7-4B4A-BDC5-99039A2869BC} = {9B4F139F-7D26-435C-A561-89E65A67A8E5}
{2BBFDE36-28A7-4875-8EBE-CC25C76B97FF} = {EBD0CF78-C5D7-4B4B-94C9-C5D8C20B6F59}
diff --git a/src/modules/Elsa.Telnyx/Activities/AnswerCall.cs b/src/modules/Elsa.Telnyx/Activities/AnswerCall.cs
deleted file mode 100644
index f26970cc3..000000000
--- a/src/modules/Elsa.Telnyx/Activities/AnswerCall.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Workflows;
-using Elsa.Workflows.Attributes;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-public class AnswerCall : AnswerCallBase
-{
- ///
- public AnswerCall([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- /// The activity to schedule when the call was successfully answered.
- ///
- [Port]
- public IActivity? Connected { get; set; }
-
- ///
- /// The activity to schedule when the call was no longer active.
- ///
- [Port]
- public IActivity? Disconnected { get; set; }
-
- ///
- protected override async ValueTask HandleConnectedAsync(ActivityExecutionContext context) => await context.ScheduleActivityAsync(Connected);
-
- ///
- protected override async ValueTask HandleDisconnectedAsync(ActivityExecutionContext context) => await context.ScheduleActivityAsync(Disconnected);
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/AnswerCallBase.cs b/src/modules/Elsa.Telnyx/Activities/AnswerCallBase.cs
deleted file mode 100644
index 21b3d1892..000000000
--- a/src/modules/Elsa.Telnyx/Activities/AnswerCallBase.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using Elsa.Extensions;
-using Elsa.Telnyx.Bookmarks;
-using Elsa.Telnyx.Client.Models;
-using Elsa.Telnyx.Client.Services;
-using Elsa.Telnyx.Extensions;
-using Elsa.Telnyx.Payloads.Call;
-using Elsa.Workflows;
-using Elsa.Workflows.Attributes;
-using Elsa.Workflows.Models;
-using Refit;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-/// Answer an incoming call. You must issue this command before executing subsequent commands on an incoming call.
-///
-[Activity(Constants.Namespace, "Answer an incoming call. You must issue this command before executing subsequent commands on an incoming call.", Kind = ActivityKind.Task)]
-public abstract class AnswerCallBase : Activity
-{
- ///
- protected AnswerCallBase(string? source = default, int? line = default) : base(source, line)
- {
- }
-
- ///
- /// The call control ID to answer. Leave blank when the workflow is driven by an incoming call and you wish to pick up that one.
- ///
- [Input(DisplayName = "Call Control ID", Description = "The call control ID of the call to answer.", Category = "Advanced")]
- public Input CallControlId { get; set; } = default!;
-
- ///
- protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
- {
- var callControlId = CallControlId.Get(context);
-
- var request = new AnswerCallRequest
- {
- ClientState = context.CreateCorrelatingClientState(context.Id)
- };
-
- var telnyxClient = context.GetRequiredService();
-
- try
- {
- // Send a request to Telnyx to answer the call.
- await telnyxClient.Calls.AnswerCallAsync(callControlId, request, context.CancellationToken);
-
- // Create a bookmark so we can resume the workflow when the call is answered.
- context.CreateBookmark(new AnswerCallStimulus(callControlId), ResumeAsync, true);
- }
- catch (ApiException e)
- {
- if (!await e.CallIsNoLongerActiveAsync()) throw;
- await HandleDisconnectedAsync(context);
- }
- }
-
- ///
- /// Invoked when the call was successfully answered.
- ///
- protected abstract ValueTask HandleConnectedAsync(ActivityExecutionContext context);
-
- ///
- /// Invoked when the call was no longer active.
- ///
- protected abstract ValueTask HandleDisconnectedAsync(ActivityExecutionContext context);
-
- private async ValueTask ResumeAsync(ActivityExecutionContext context)
- {
- var payload = context.GetWorkflowInput();
- context.Set(Result, payload);
- await HandleConnectedAsync(context);
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/BridgeCalls.cs b/src/modules/Elsa.Telnyx/Activities/BridgeCalls.cs
deleted file mode 100644
index 573d4b84b..000000000
--- a/src/modules/Elsa.Telnyx/Activities/BridgeCalls.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Workflows;
-using Elsa.Workflows.Attributes;
-using JetBrains.Annotations;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-[PublicAPI]
-public class BridgeCalls : BridgeCallsBase
-{
- ///
- public BridgeCalls([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- /// The to execute when the source leg call is no longer active.
- ///
- [Port]
- public IActivity? Disconnected { get; set; }
-
- ///
- /// The to execute when the two calls are bridged.
- ///
- [Port]
- public IActivity? Bridged { get; set; }
-
- ///
- protected override async ValueTask HandleDisconnectedAsync(ActivityExecutionContext context) => await context.ScheduleActivityAsync(Disconnected, OnCompleted);
-
- ///
- protected override async ValueTask HandleBridgedAsync(ActivityExecutionContext context) => await context.ScheduleActivityAsync(Bridged, OnCompleted);
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/BridgeCallsBase.cs b/src/modules/Elsa.Telnyx/Activities/BridgeCallsBase.cs
deleted file mode 100644
index b5b6bb89f..000000000
--- a/src/modules/Elsa.Telnyx/Activities/BridgeCallsBase.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-using Elsa.Extensions;
-using Elsa.Telnyx.Bookmarks;
-using Elsa.Telnyx.Client.Models;
-using Elsa.Telnyx.Client.Services;
-using Elsa.Telnyx.Extensions;
-using Elsa.Telnyx.Models;
-using Elsa.Telnyx.Payloads.Call;
-using Elsa.Workflows;
-using Elsa.Workflows.Attributes;
-using Elsa.Workflows.Models;
-using JetBrains.Annotations;
-using Refit;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-/// Bridge two calls.
-///
-[Activity(Constants.Namespace, "Bridge two calls.", Kind = ActivityKind.Task)]
-[PublicAPI]
-public abstract class BridgeCallsBase : Activity
-{
- ///
- protected BridgeCallsBase(string? source = default, int? line = default) : base(source, line)
- {
- }
-
- ///
- /// The source call control ID of one of the call to bridge with. Leave empty to use the ambient inbound call control Id, if there is one.
- ///
- [Input(DisplayName = "Call Control ID A", Description = "The source call control ID of one of the call to bridge with. Leave empty to use the ambient inbound call control Id, if there is one.")]
- public Input CallControlIdA { get; set; } = default!;
-
- ///
- /// The destination call control ID of the call you want to bridge with.
- ///
- [Input(DisplayName = "Call Control ID B", Description = "The destination call control ID of the call you want to bridge with.")]
- public Input CallControlIdB { get; set; } = default!;
-
- ///
- protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
- {
- var callControlIdA = CallControlIdA.Get(context);
- var callControlIdB = CallControlIdB.Get(context);
- var request = new BridgeCallsRequest(callControlIdB, ClientState: context.CreateCorrelatingClientState(context.Id));
- var telnyxClient = context.GetRequiredService();
-
- try
- {
- await telnyxClient.Calls.BridgeCallsAsync(callControlIdA, request, context.CancellationToken);
-
- var bookmarkA = new WebhookEventStimulus(WebhookEventTypes.CallBridged, callControlIdA);
- var bookmarkB = new WebhookEventStimulus(WebhookEventTypes.CallBridged, callControlIdB);
- context.CreateBookmarks(new[] { bookmarkA, bookmarkB }, ResumeAsync, false);
- }
- catch (ApiException e)
- {
- if (!await e.CallIsNoLongerActiveAsync()) throw;
-
- await HandleDisconnectedAsync(context);
- }
- }
-
- ///
- /// Called when the call is disconnected.
- ///
- protected abstract ValueTask HandleDisconnectedAsync(ActivityExecutionContext context);
-
- ///
- /// Called when the call is bridged.
- ///
- ///
- protected abstract ValueTask HandleBridgedAsync(ActivityExecutionContext context);
-
- ///
- /// Called when the activity is completed.
- ///
- protected async ValueTask OnCompleted(ActivityCompletedContext context) => await context.TargetContext.CompleteActivityAsync();
-
- private async ValueTask ResumeAsync(ActivityExecutionContext context)
- {
- var payload = context.GetWorkflowInput()!;
- var callControlIdA = CallControlIdA.Get(context);
- var callControlIdB = CallControlIdB.Get(context);;
-
- if (payload.CallControlId == callControlIdA) context.SetProperty("CallBridgedPayloadA", payload);
- if (payload.CallControlId == callControlIdB) context.SetProperty("CallBridgedPayloadB", payload);
-
- var callBridgedPayloadA = context.GetProperty("CallBridgedPayloadA");
- var callBridgedPayloadB = context.GetProperty("CallBridgedPayloadB");
-
- if (callBridgedPayloadA != null && callBridgedPayloadB != null)
- {
- context.Set(Result, new BridgedCallsOutput(callBridgedPayloadA, callBridgedPayloadB));
- await HandleBridgedAsync(context);
- }
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/CallAnswered.cs b/src/modules/Elsa.Telnyx/Activities/CallAnswered.cs
deleted file mode 100644
index a1f5f9e20..000000000
--- a/src/modules/Elsa.Telnyx/Activities/CallAnswered.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Extensions;
-using Elsa.Telnyx.Bookmarks;
-using Elsa.Telnyx.Helpers;
-using Elsa.Telnyx.Payloads.Call;
-using Elsa.Workflows;
-using Elsa.Workflows.Attributes;
-using Elsa.Workflows.UIHints;
-using Elsa.Workflows.Models;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-/// Represents a Telnyx webhook event trigger.
-///
-[Activity("Telnyx", "Telnyx", "A Telnyx webhook event that executes when a call is answered.", Kind = ActivityKind.Trigger)]
-public class CallAnswered : Activity
-{
- ///
- public CallAnswered([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- /// A list of call control IDs to listen for.
- ///
- [Input(Description = "A list of call control IDs to listen for.", UIHint = InputUIHints.MultiText)]
- public Input> CallControlIds { get; set; } = default!;
-
- ///
- protected override void Execute(ActivityExecutionContext context)
- {
- var callControlIds = CallControlIds.Get(context);
-
- foreach (var callControlId in callControlIds)
- {
- var payload = new CallAnsweredStimulus(callControlId);
- context.CreateBookmark(new CreateBookmarkArgs
- {
- Stimulus = payload,
- Callback = Resume,
- BookmarkName = Type,
- IncludeActivityInstanceId = false
- });
- }
- }
-
- private async ValueTask Resume(ActivityExecutionContext context)
- {
- var input = context.GetWorkflowInput(WebhookSerializerOptions.Create());
- context.Set(Result, input);
- await context.CompleteActivityAsync();
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/CallHangup.cs b/src/modules/Elsa.Telnyx/Activities/CallHangup.cs
deleted file mode 100644
index cb77dd131..000000000
--- a/src/modules/Elsa.Telnyx/Activities/CallHangup.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Extensions;
-using Elsa.Telnyx.Bookmarks;
-using Elsa.Telnyx.Helpers;
-using Elsa.Telnyx.Payloads.Call;
-using Elsa.Workflows;
-using Elsa.Workflows.Attributes;
-using Elsa.Workflows.UIHints;
-using Elsa.Workflows.Models;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-/// Represents a Telnyx webhook event trigger.
-///
-[Activity("Telnyx", "Telnyx", "A Telnyx webhook event that executes when a call is hangup.", Kind = ActivityKind.Trigger)]
-public class CallHangup : Activity
-{
- ///
- public CallHangup([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- /// A list of call control IDs to listen for.
- ///
- [Input(Description = "A list of call control IDs to listen for.", UIHint = InputUIHints.MultiText)]
- public Input> CallControlIds { get; set; } = default!;
-
- ///
- protected override void Execute(ActivityExecutionContext context)
- {
- var callControlIds = CallControlIds.Get(context);
-
- foreach (var callControlId in callControlIds)
- {
- var payload = new CallHangupStimulus(callControlId);
- context.CreateBookmark(new CreateBookmarkArgs
- {
- Stimulus = payload,
- Callback = Resume,
- BookmarkName = Type,
- IncludeActivityInstanceId = false
- });
- }
- }
-
- private async ValueTask Resume(ActivityExecutionContext context)
- {
- var input = context.GetWorkflowInput(WebhookSerializerOptions.Create());
- context.Set(Result, input);
- await context.CompleteActivityAsync();
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/Dial.cs b/src/modules/Elsa.Telnyx/Activities/Dial.cs
deleted file mode 100644
index 9e5511bdd..000000000
--- a/src/modules/Elsa.Telnyx/Activities/Dial.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Extensions;
-using Elsa.Telnyx.Client.Models;
-using Elsa.Telnyx.Client.Services;
-using Elsa.Telnyx.Exceptions;
-using Elsa.Telnyx.Extensions;
-using Elsa.Telnyx.Options;
-using Elsa.Workflows;
-using Elsa.Workflows.Attributes;
-using Elsa.Workflows.UIHints;
-using Elsa.Workflows.Models;
-using Microsoft.Extensions.Options;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-/// Dial a number or SIP URI.
-///
-[Activity(Constants.Namespace, "Dial a number or SIP URI.", Kind = ActivityKind.Task)]
-public class Dial : CodeActivity
-{
- ///
- public Dial([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- /// The DID or SIP URI to dial out and bridge to the given call.
- ///
- [Input(Description = "The DID or SIP URI to dial out and bridge to the given call.")]
- public Input To { get; set; } = default!;
-
- ///
- /// The 'from' number to be used as the caller id presented to the destination ('To' number). The number should be in +E164 format. This attribute will default to the 'From' number of the original call if omitted.
- ///
- [Input(Description = "The 'from' number to be used as the caller id presented to the destination ('To' number). The number should be in +E164 format. This attribute will default to the 'From' number of the original call if omitted.")]
- public Input From { get; set; } = default!;
-
- ///
- /// The string to be used as the caller id name (SIP From Display Name) presented to the destination ('To' number). The string should have a maximum of 128 characters, containing only letters, numbers, spaces, and -_~!.+ special characters. If omitted, the display name will be the same as the number in the 'From' field.
- ///
- [Input(Description =
- "The string to be used as the caller id name (SIP From Display Name) presented to the destination ('To' number). The string should have a maximum of 128 characters, containing only letters, numbers, spaces, and -_~!.+ special characters. If omitted, the display name will be the same as the number in the 'From' field.")]
- public Input FromDisplayName { get; set; } = default!;
-
- ///
- /// Enables answering machine detection.
- ///
- [Input(
- Description = "Enables answering machine detection.",
- UIHint = InputUIHints.DropDown,
- Options = new[] { "disabled", "detect", "detect_beep", "detect_words", "greeting_end", "premium" },
- DefaultValue = "disabled")]
- public Input AnsweringMachineDetection { get; set; } = new("disabled");
-
- ///
- /// Start recording automatically after an event. Disabled by default.
- ///
- [Input(Description = "Start recording automatically after an event. Disabled by default.")]
- public Input Record { get; set; } = default!;
-
- ///
- /// Defines the format of the recording ('wav' or 'mp3') when `record` is specified.
- ///
- [Input(
- Description = "Defines the format of the recording ('wav' or 'mp3') when `record` is specified.",
- UIHint = InputUIHints.DropDown,
- Options = new[] { "wav", "mp3" },
- DefaultValue = "mp3"
- )]
- public Input RecordFormat { get; set; } = new("mp3");
-
- ///
- protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
- {
- var response = await DialAsync(context);
- Result.Set(context, response);
- }
-
- private async Task DialAsync(ActivityExecutionContext context)
- {
- var telnyxOptions = context.GetRequiredService>().Value;
- var callControlAppId = telnyxOptions.CallControlAppId;
-
- if (callControlAppId == null)
- throw new MissingCallControlAppIdException("No Call Control ID configured");
-
- var fromNumber = From.GetOrDefault(context);
- var clientState = context.CreateCorrelatingClientState();
-
- var request = new DialRequest(
- callControlAppId,
- To.Get(context),
- fromNumber,
- FromDisplayName.GetOrDefault(context).SanitizeCallerName(),
- AnsweringMachineDetection.GetOrDefault(context),
- Record: Record.GetOrDefault(context) ? "record-from-answer" : default,
- RecordFormat: RecordFormat.GetOrDefault(context) ?? "mp3",
- ClientState: clientState
- );
-
- var telnyxClient = context.GetRequiredService();
- var response = await telnyxClient.Calls.DialAsync(request, context.CancellationToken);
-
- return response.Data;
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/DialAndWait.cs b/src/modules/Elsa.Telnyx/Activities/DialAndWait.cs
deleted file mode 100644
index 751843556..000000000
--- a/src/modules/Elsa.Telnyx/Activities/DialAndWait.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Extensions;
-using Elsa.Telnyx.Attributes;
-using Elsa.Telnyx.Bookmarks;
-using Elsa.Telnyx.Client.Models;
-using Elsa.Telnyx.Client.Services;
-using Elsa.Telnyx.Exceptions;
-using Elsa.Telnyx.Extensions;
-using Elsa.Telnyx.Options;
-using Elsa.Telnyx.Payloads.Abstractions;
-using Elsa.Telnyx.Payloads.Call;
-using Elsa.Workflows;
-using Elsa.Workflows.Activities.Flowchart.Attributes;
-using Elsa.Workflows.Attributes;
-using Elsa.Workflows.UIHints;
-using Elsa.Workflows.Models;
-using Microsoft.Extensions.Options;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-/// Dial a number or SIP URI.
-///
-[Activity(Constants.Namespace, "Dial a number or SIP URI and wait for an event.", Kind = ActivityKind.Task)]
-[FlowNode("Answered", "Hangup")]
-[WebhookDriven(WebhookEventTypes.CallAnswered, WebhookEventTypes.CallHangup)]
-public class DialAndWait : Activity
-{
- ///
- public DialAndWait([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- /// The DID or SIP URI to dial out and bridge to the given call.
- ///
- [Input(Description = "The DID or SIP URI to dial out and bridge to the given call.")]
- public Input To { get; set; } = default!;
-
- ///
- /// The 'from' number to be used as the caller id presented to the destination ('To' number). The number should be in +E164 format. This attribute will default to the 'From' number of the original call if omitted.
- ///
- [Input(Description = "The 'from' number to be used as the caller id presented to the destination ('To' number). The number should be in +E164 format. This attribute will default to the 'From' number of the original call if omitted.")]
- public Input From { get; set; } = default!;
-
- ///
- /// The string to be used as the caller id name (SIP From Display Name) presented to the destination ('To' number). The string should have a maximum of 128 characters, containing only letters, numbers, spaces, and -_~!.+ special characters. If omitted, the display name will be the same as the number in the 'From' field.
- ///
- [Input(Description =
- "The string to be used as the caller id name (SIP From Display Name) presented to the destination ('To' number). The string should have a maximum of 128 characters, containing only letters, numbers, spaces, and -_~!.+ special characters. If omitted, the display name will be the same as the number in the 'From' field.")]
- public Input FromDisplayName { get; set; } = default!;
-
- ///
- /// Enables answering machine detection.
- ///
- [Input(
- Description = "Enables answering machine detection.",
- UIHint = InputUIHints.DropDown,
- Options = new[] { "disabled", "detect", "detect_beep", "detect_words", "greeting_end", "premium" },
- DefaultValue = "disabled")]
- public Input AnsweringMachineDetection { get; set; } = new("disabled");
-
- ///
- /// Start recording automatically after an event. Disabled by default.
- ///
- [Input(Description = "Start recording automatically after an event. Disabled by default.")]
- public Input Record { get; set; } = default!;
-
- ///
- /// Defines the format of the recording ('wav' or 'mp3') when `record` is specified.
- ///
- [Input(
- Description = "Defines the format of the recording ('wav' or 'mp3') when `record` is specified.",
- UIHint = InputUIHints.DropDown,
- Options = new[] { "wav", "mp3" },
- DefaultValue = "mp3"
- )]
- public Input RecordFormat { get; set; } = new("mp3");
-
- ///
- protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
- {
- var response = await DialAsync(context);
- var answeredBookmark = new WebhookEventStimulus(WebhookEventTypes.CallAnswered, response.CallControlId);
- var hangupBookmark = new WebhookEventStimulus(WebhookEventTypes.CallHangup, response.CallControlId);
-
- context.CreateBookmark(answeredBookmark, OnCallAnswered, false);
- context.CreateBookmark(hangupBookmark, OnCallHangup, false);
- }
-
- private async ValueTask OnCallAnswered(ActivityExecutionContext context)
- {
- var payload = context.GetWorkflowInput();
- Result.Set(context, payload);
- await context.CompleteActivityWithOutcomesAsync("Answered");
- }
-
- private async ValueTask OnCallHangup(ActivityExecutionContext context)
- {
- var payload = context.GetWorkflowInput();
- Result.Set(context, payload);
- await context.CompleteActivityWithOutcomesAsync("Hangup");
- }
-
- private async Task DialAsync(ActivityExecutionContext context)
- {
- var telnyxOptions = context.GetRequiredService>().Value;
- var callControlAppId = telnyxOptions.CallControlAppId;
-
- if (callControlAppId == null)
- throw new MissingCallControlAppIdException("No Call Control ID configured");
-
- var fromNumber = From.GetOrDefault(context);
- var clientState = context.CreateCorrelatingClientState();
-
- var request = new DialRequest(
- callControlAppId,
- To.Get(context),
- fromNumber,
- FromDisplayName.GetOrDefault(context).SanitizeCallerName(),
- AnsweringMachineDetection.GetOrDefault(context),
- Record: Record.GetOrDefault(context) ? "record-from-answer" : default,
- RecordFormat: RecordFormat.GetOrDefault(context) ?? "mp3",
- ClientState: clientState
- );
-
- var telnyxClient = context.GetRequiredService();
- var response = await telnyxClient.Calls.DialAsync(request, context.CancellationToken);
-
- return response.Data;
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/FlowAnswerCall.cs b/src/modules/Elsa.Telnyx/Activities/FlowAnswerCall.cs
deleted file mode 100644
index 5851ceb0a..000000000
--- a/src/modules/Elsa.Telnyx/Activities/FlowAnswerCall.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Workflows;
-using Elsa.Workflows.Activities.Flowchart.Attributes;
-using Elsa.Workflows.Activities.Flowchart.Models;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-[FlowNode("Connected", "Disconnected")]
-public class FlowAnswerCall : AnswerCallBase
-{
- ///
- public FlowAnswerCall([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- protected override async ValueTask HandleConnectedAsync(ActivityExecutionContext context) => await context.CompleteActivityAsync(new Outcomes("Connected"));
-
- ///
- protected override async ValueTask HandleDisconnectedAsync(ActivityExecutionContext context) => await context.CompleteActivityAsync(new Outcomes("Disconnected"));
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/FlowBridgeCalls.cs b/src/modules/Elsa.Telnyx/Activities/FlowBridgeCalls.cs
deleted file mode 100644
index 24bb3569a..000000000
--- a/src/modules/Elsa.Telnyx/Activities/FlowBridgeCalls.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Workflows;
-using Elsa.Workflows.Activities.Flowchart.Attributes;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-[FlowNode("Bridged", "Disconnected")]
-public class FlowBridgeCalls : BridgeCallsBase
-{
- ///
- public FlowBridgeCalls([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- protected override ValueTask HandleDisconnectedAsync(ActivityExecutionContext context) => context.CompleteActivityAsync("Disconnected");
-
- ///
- protected override ValueTask HandleBridgedAsync(ActivityExecutionContext context) => context.CompleteActivityAsync("Bridged");
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/FlowHangupCall.cs b/src/modules/Elsa.Telnyx/Activities/FlowHangupCall.cs
deleted file mode 100644
index 9fb415f8c..000000000
--- a/src/modules/Elsa.Telnyx/Activities/FlowHangupCall.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Workflows;
-using Elsa.Workflows.Activities.Flowchart.Attributes;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-[FlowNode("Done", "Disconnected")]
-public class FlowHangupCall : HangupCallBase
-{
- ///
- public FlowHangupCall([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- protected override ValueTask HandleDoneAsync(ActivityExecutionContext context) => context.CompleteActivityWithOutcomesAsync("Done");
-
- ///
- protected override ValueTask HandleDisconnectedAsync(ActivityExecutionContext context) => context.CompleteActivityWithOutcomesAsync("Disconnected");
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/FlowPlayAudio.cs b/src/modules/Elsa.Telnyx/Activities/FlowPlayAudio.cs
deleted file mode 100644
index 30a54f110..000000000
--- a/src/modules/Elsa.Telnyx/Activities/FlowPlayAudio.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Workflows;
-using Elsa.Workflows.Activities.Flowchart.Attributes;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-[FlowNode("Playback started", "Disconnected")]
-public class FlowPlayAudio : PlayAudioBase
-{
- ///
- public FlowPlayAudio([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- protected override ValueTask HandlePlaybackStartedAsync(ActivityExecutionContext context) => context.CompleteActivityWithOutcomesAsync("Playback started");
-
- ///
- protected override ValueTask HandleDisconnectedAsync(ActivityExecutionContext context) => context.CompleteActivityWithOutcomesAsync("Disconnected");
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/FlowSpeakText.cs b/src/modules/Elsa.Telnyx/Activities/FlowSpeakText.cs
deleted file mode 100644
index eeddbc958..000000000
--- a/src/modules/Elsa.Telnyx/Activities/FlowSpeakText.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Workflows;
-using Elsa.Workflows.Activities.Flowchart.Attributes;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-[FlowNode("Done", "Finished speaking", "Disconnected")]
-public class FlowSpeakText : SpeakTextBase
-{
- ///
- public FlowSpeakText([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- protected override async ValueTask HandleDisconnected(ActivityExecutionContext context) => await context.CompleteActivityWithOutcomesAsync("Disconnected", "Done");
-
- ///
- protected override async ValueTask HandleSpeakingHasFinished(ActivityExecutionContext context) => await context.CompleteActivityWithOutcomesAsync("Finished speaking", "Done");
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/FlowStartRecording.cs b/src/modules/Elsa.Telnyx/Activities/FlowStartRecording.cs
deleted file mode 100644
index 7ca25d52e..000000000
--- a/src/modules/Elsa.Telnyx/Activities/FlowStartRecording.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Workflows;
-using Elsa.Workflows.Activities.Flowchart.Attributes;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-[FlowNode("Recording finished", "Disconnected")]
-public class FlowStartRecording : StartRecordingBase
-{
- ///
- public FlowStartRecording([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- protected override ValueTask HandleDisconnectedAsync(ActivityExecutionContext context) => context.CompleteActivityWithOutcomesAsync("Disconnected");
-
- ///
- protected override ValueTask HandleCallRecordingSavedAsync(ActivityExecutionContext context) => context.CompleteActivityWithOutcomesAsync("Recording finished");
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/FlowStopAudioPlayback.cs b/src/modules/Elsa.Telnyx/Activities/FlowStopAudioPlayback.cs
deleted file mode 100644
index cb946d2a0..000000000
--- a/src/modules/Elsa.Telnyx/Activities/FlowStopAudioPlayback.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Workflows;
-using Elsa.Workflows.Activities.Flowchart.Attributes;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-[FlowNode("Done", "Disconnected")]
-public class FlowStopAudioPlayback : StopAudioPlaybackBase
-{
- ///
- public FlowStopAudioPlayback([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- protected override ValueTask HandleDoneAsync(ActivityExecutionContext context) => context.CompleteActivityWithOutcomesAsync("Done");
-
- ///
- protected override ValueTask HandleDisconnectedAsync(ActivityExecutionContext context) => context.CompleteActivityWithOutcomesAsync("Disconnected");
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/GatherUsingAudio.cs b/src/modules/Elsa.Telnyx/Activities/GatherUsingAudio.cs
deleted file mode 100644
index 082ac0dcd..000000000
--- a/src/modules/Elsa.Telnyx/Activities/GatherUsingAudio.cs
+++ /dev/null
@@ -1,158 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Extensions;
-using Elsa.Telnyx.Attributes;
-using Elsa.Telnyx.Bookmarks;
-using Elsa.Telnyx.Client.Models;
-using Elsa.Telnyx.Client.Services;
-using Elsa.Telnyx.Extensions;
-using Elsa.Telnyx.Payloads.Call;
-using Elsa.Workflows;
-using Elsa.Workflows.Activities.Flowchart.Attributes;
-using Elsa.Workflows.Attributes;
-using Elsa.Workflows.Models;
-using Elsa.Workflows.Runtime;
-using Refit;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-/// Play an audio file on the call until the required DTMF signals are gathered to build interactive menus.
-///
-[Activity(Constants.Namespace, "Play an audio file on the call until the required DTMF signals are gathered to build interactive menus.", Kind = ActivityKind.Task)]
-[FlowNode("Valid input", "Invalid input", "Disconnected")]
-[WebhookDriven(WebhookEventTypes.CallGatherEnded)]
-public class GatherUsingAudio : Activity, IBookmarksPersistedHandler
-{
- ///
- public GatherUsingAudio([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- /// The call control ID of the call from which to gather input. Leave empty to use the ambient call control ID, if there is any.
- ///
- [Input(DisplayName = "Call Control ID", Description = "The call control ID of the call from which to gather input. Leave empty to use the ambient call control ID, if there is any.", Category = "Advanced")]
- public Input CallControlId { get; set; } = default!;
-
- ///
- /// The URL of a file to be played back at the beginning of each prompt. The URL can point to either a WAV or MP3 file.
- ///
- [Input(
- DisplayName = "Audio URL",
- Description = "The URL of a file to be played back at the beginning of each prompt. The URL can point to either a WAV or MP3 file."
- )]
- public Input? AudioUrl { get; set; } = default!;
-
- ///
- /// The number of milliseconds to wait for input between digits.
- ///
- [Input(
- DisplayName = "Inter Digit Timeout",
- Description = "The number of milliseconds to wait for input between digits.",
- Category = "Advanced",
- DefaultValue = 5000
- )]
- public Input? InterDigitTimeoutMillis { get; set; } = new(5000);
-
- ///
- /// The URL of a file to play when digits don't match the Valid Digits setting or the number of digits is not between Min and Max. The URL can point to either a WAV or MP3 file.
- ///
- [Input(
- DisplayName = "Invalid Audio Url",
- Description = "The URL of a file to play when digits don't match the Valid Digits setting or the number of digits is not between Min and Max. The URL can point to either a WAV or MP3 file."
- )]
- public Input? InvalidAudioUrl { get; set; }
-
- ///
- /// A list of all digits accepted as valid.
- ///
- [Input(
- Description = "A list of all digits accepted as valid.",
- Category = "Advanced",
- DefaultValue = "0123456789#*"
- )]
- public Input? ValidDigits { get; set; } = new("0123456789#*");
-
- ///
- /// The minimum number of digits to fetch. This parameter has a minimum value of 1.
- ///
- [Input(Description = "The minimum number of digits to fetch. This parameter has a minimum value of 1.", DefaultValue = 1)]
- public Input? MinimumDigits { get; set; } = new(1);
-
- ///
- /// The maximum number of digits to fetch. This parameter has a maximum value of 128.
- ///
- [Input(Description = "The maximum number of digits to fetch. This parameter has a maximum value of 128.", DefaultValue = 128)]
- public Input? MaximumDigits { get; set; } = new(128);
-
- ///
- /// The maximum number of times the file should be played if there is no input from the user on the call.
- ///
- [Input(Description = "The maximum number of times the file should be played if there is no input from the user on the call.", DefaultValue = 3)]
- public Input? MaximumTries { get; set; } = new(3);
-
- ///
- /// The digit used to terminate input if fewer than `maximum_digits` digits have been gathered.
- ///
- [Input(Description = "The digit used to terminate input if fewer than `maximum_digits` digits have been gathered.", DefaultValue = "#")]
- public Input? TerminatingDigit { get; set; } = new("#");
-
- ///
- /// The number of milliseconds to wait for a DTMF response after file playback ends before a replaying the sound file.
- ///
- [Input(
- DisplayName = "Timeout",
- Description = "The number of milliseconds to wait for a DTMF response after file playback ends before a replaying the sound file.",
- Category = "Advanced",
- DefaultValue = 60000
- )]
- public Input? TimeoutMillis { get; set; } = new(60000);
-
- ///
- /// Calls out to Telnyx to actually begin gathering input.
- ///
- public async ValueTask BookmarksPersistedAsync(ActivityExecutionContext context)
- {
- var request = new GatherUsingAudioRequest(
- AudioUrl.Get(context) ?? throw new Exception("AudioUrl is required."),
- context.CreateCorrelatingClientState(),
- default,
- InterDigitTimeoutMillis.Get(context),
- InvalidAudioUrl.Get(context),
- MaximumDigits.Get(context),
- MaximumTries.Get(context),
- MinimumDigits.Get(context),
- TerminatingDigit.Get(context).EmptyToNull(),
- TimeoutMillis.Get(context),
- ValidDigits.Get(context).EmptyToNull()
- );
-
- var callControlId = CallControlId.Get(context);
- var telnyxClient = context.GetRequiredService();
-
- try
- {
- await telnyxClient.Calls.GatherUsingAudioAsync(callControlId, request, context.CancellationToken);
- }
- catch (ApiException e)
- {
- if (!await e.CallIsNoLongerActiveAsync()) throw;
- await context.CompleteActivityWithOutcomesAsync("Disconnected");
- }
- }
-
- ///
- protected override void Execute(ActivityExecutionContext context)
- {
- var callControlId = CallControlId.Get(context);
- context.CreateBookmark(new WebhookEventStimulus(WebhookEventTypes.CallGatherEnded, callControlId), ResumeAsync);
- }
-
- private async ValueTask ResumeAsync(ActivityExecutionContext context)
- {
- var payload = context.GetWorkflowInput();
- var outcome = payload.Status == "valid" ? "Valid input" : "Invalid input";
- context.Set(Result, payload);
- await context.CompleteActivityWithOutcomesAsync(outcome);
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/GatherUsingSpeak.cs b/src/modules/Elsa.Telnyx/Activities/GatherUsingSpeak.cs
deleted file mode 100644
index eaea2c4ca..000000000
--- a/src/modules/Elsa.Telnyx/Activities/GatherUsingSpeak.cs
+++ /dev/null
@@ -1,190 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Extensions;
-using Elsa.Telnyx.Attributes;
-using Elsa.Telnyx.Bookmarks;
-using Elsa.Telnyx.Client.Models;
-using Elsa.Telnyx.Client.Services;
-using Elsa.Telnyx.Extensions;
-using Elsa.Telnyx.Payloads.Call;
-using Elsa.Workflows;
-using Elsa.Workflows.Activities.Flowchart.Attributes;
-using Elsa.Workflows.Attributes;
-using Elsa.Workflows.UIHints;
-using Elsa.Workflows.Models;
-using Refit;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-/// Convert text to speech and play it on the call until the required DTMF signals are gathered to build interactive menus.
-///
-[Activity(Constants.Namespace, "Convert text to speech and play it on the call until the required DTMF signals are gathered to build interactive menus.", Kind = ActivityKind.Task)]
-[FlowNode("Valid input", "Invalid input", "Disconnected")]
-[WebhookDriven(WebhookEventTypes.CallGatherEnded)]
-public class GatherUsingSpeak : Activity
-{
- ///
- public GatherUsingSpeak([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- /// The call control ID of the call from which to gather input. Leave empty to use the ambient call control ID, if there is any.
- ///
- [Input(DisplayName = "Call Control ID", Description = "The call control ID of the call from which to gather input. Leave empty to use the ambient call control ID, if there is any.", Category = "Advanced")]
- public Input CallControlId { get; set; } = default!;
-
- ///
- /// The language you want spoken.
- ///
- [Input(
- Description = "The language you want spoken.",
- UIHint = InputUIHints.DropDown,
- Options = new[] { "en-US", "en-AU", "nl-NL", "es-ES", "ru-RU" },
- DefaultValue = "en-US"
- )]
- public Input Language { get; set; } = new("en-US");
-
- ///
- /// The gender of the voice used to speak back the text.
- ///
- [Input(
- Description = "The gender of the voice used to speak back the text.",
- UIHint = InputUIHints.DropDown,
- Options = new[] { "female", "male" },
- DefaultValue = "female"
- )]
- public Input Voice { get; set; } = new("female");
-
- ///
- /// The text or SSML to be converted into speech. There is a 5,000 character limit.
- ///
- [Input(
- Description = "The text or SSML to be converted into speech. There is a 5,000 character limit.",
- UIHint = InputUIHints.MultiLine
- )]
- public Input Payload { get; set; } = default!;
-
- ///
- /// The type of the provided payload. The payload can either be plain text, or Speech Synthesis Markup Language (SSML).
- ///
- [Input(
- Description = "The type of the provided payload. The payload can either be plain text, or Speech Synthesis Markup Language (SSML).",
- UIHint = InputUIHints.DropDown,
- Options = new[] { "", "text", "ssml" }
- )]
- public Input? PayloadType { get; set; }
-
- ///
- /// "This parameter impacts speech quality, language options and payload types. When using `basic`, only the `en-US` language and payload type `text` are allowed."
- ///
- [Input(
- Description = "This parameter impacts speech quality, language options and payload types. When using `basic`, only the `en-US` language and payload type `text` are allowed.",
- UIHint = InputUIHints.DropDown,
- Options = new[] { "", "basic", "premium" },
- Category = "Advanced"
- )]
- public Input? ServiceLevel { get; set; }
-
- ///
- /// The number of milliseconds to wait for input between digits.
- ///
- [Input(
- DisplayName = "Inter Digit Timeout",
- Description = "The number of milliseconds to wait for input between digits.",
- Category = "Advanced",
- DefaultValue = 5000
- )]
- public Input? InterDigitTimeoutMillis { get; set; } = new(5000);
-
- ///
- /// A list of all digits accepted as valid.
- ///
- [Input(
- Description = "A list of all digits accepted as valid.",
- Category = "Advanced",
- DefaultValue = "0123456789#*"
- )]
- public Input? ValidDigits { get; set; } = new("0123456789#*");
-
- ///
- /// The minimum number of digits to fetch. This parameter has a minimum value of 1.
- ///
- [Input(Description = "The minimum number of digits to fetch. This parameter has a minimum value of 1.", DefaultValue = 1)]
- public Input? MinimumDigits { get; set; } = new(1);
-
- ///
- /// The maximum number of digits to fetch. This parameter has a maximum value of 128.
- ///
- [Input(Description = "The maximum number of digits to fetch. This parameter has a maximum value of 128.", DefaultValue = 128)]
- public Input? MaximumDigits { get; set; } = new(128);
-
- ///
- /// The maximum number of times the file should be played if there is no input from the user on the call.
- ///
- [Input(Description = "The maximum number of times the file should be played if there is no input from the user on the call.", DefaultValue = 3)]
- public Input? MaximumTries { get; set; } = new(3);
-
- ///
- /// The digit used to terminate input if fewer than `maximum_digits` digits have been gathered.
- ///
- [Input(Description = "The digit used to terminate input if fewer than `maximum_digits` digits have been gathered.", DefaultValue = "#")]
- public Input? TerminatingDigit { get; set; } = new("#");
-
- ///
- /// The number of milliseconds to wait for a DTMF response after file playback ends before a replaying the sound file.
- ///
- [Input(
- DisplayName = "Timeout",
- Description = "The number of milliseconds to wait for a DTMF response after file playback ends before a replaying the sound file.",
- Category = "Advanced",
- DefaultValue = 60000
- )]
- public Input? TimeoutMillis { get; set; } = new(60000);
-
- ///
- protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
- {
- var callControlId = CallControlId.Get(context);
-
- var request = new GatherUsingSpeakRequest(
- Language.Get(context) ?? throw new Exception("Language is required."),
- Voice.Get(context) ?? throw new Exception("Voice is required."),
- Payload.Get(context) ?? throw new Exception("Payload is required."),
- PayloadType.GetOrDefault(context),
- ServiceLevel.GetOrDefault(context),
- InterDigitTimeoutMillis.GetOrDefault(context),
- MaximumDigits.GetOrDefault(context),
- MaximumTries.GetOrDefault(context),
- MinimumDigits.GetOrDefault(context),
- TerminatingDigit.GetOrDefault(context).EmptyToNull(),
- TimeoutMillis.GetOrDefault(context),
- ValidDigits.GetOrDefault(context).EmptyToNull(),
- context.CreateCorrelatingClientState(context.Id)
- );
-
- var telnyxClient = context.GetRequiredService();
-
- try
- {
- // Send the request to Telnyx.
- await telnyxClient.Calls.GatherUsingSpeakAsync(callControlId, request, context.CancellationToken);
-
- // Create a bookmark so we can resume this activity when the call.gather.ended webhook comes back.
- context.CreateBookmark(new WebhookEventStimulus(WebhookEventTypes.CallGatherEnded, callControlId), ResumeAsync, true);
- }
- catch (ApiException e)
- {
- if (!await e.CallIsNoLongerActiveAsync()) throw;
- await context.CompleteActivityWithOutcomesAsync("Disconnected");
- }
- }
-
- private async ValueTask ResumeAsync(ActivityExecutionContext context)
- {
- var payload = context.GetWorkflowInput();
- var outcome = payload.Status == "valid" ? "Valid input" : "Invalid input";
- context.Set(Result, payload);
- await context.CompleteActivityWithOutcomesAsync(outcome);
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/GetCallStatus.cs b/src/modules/Elsa.Telnyx/Activities/GetCallStatus.cs
deleted file mode 100644
index 4f0aa5c9e..000000000
--- a/src/modules/Elsa.Telnyx/Activities/GetCallStatus.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Extensions;
-using Elsa.Telnyx.Client.Services;
-using Elsa.Workflows;
-using Elsa.Workflows.Activities.Flowchart.Attributes;
-using Elsa.Workflows.Attributes;
-using Elsa.Workflows.Models;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-[FlowNode("Alive", "Dead", "Done")]
-[Activity(Constants.Namespace, "Get the status of a call.", Kind = ActivityKind.Task)]
-public class GetCallStatus : Activity
-{
- ///
- public GetCallStatus([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- /// Unique identifier and token for controlling the call.
- ///
- [Input(
- DisplayName = "Call Control ID",
- Description = "Unique identifier and token for controlling the call.",
- Category = "Advanced"
- )]
- public Input CallControlId { get; set; } = default!;
-
- ///
- protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
- {
- var client = context.GetRequiredService();
- var callControlId = CallControlId.Get(context);
- var response = await client.Calls.GetStatusAsync(callControlId, context.CancellationToken);
- var isAlive = response.Data.IsAlive;
- var outcome = isAlive ? "Alive" : "Dead";
-
- Result.Set(context, isAlive);
-
- await context.CompleteActivityWithOutcomesAsync(outcome, "Done");
- }
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/HangupCall.cs b/src/modules/Elsa.Telnyx/Activities/HangupCall.cs
deleted file mode 100644
index c378d9d2a..000000000
--- a/src/modules/Elsa.Telnyx/Activities/HangupCall.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Workflows;
-using Elsa.Workflows.Attributes;
-using JetBrains.Annotations;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-[PublicAPI]
-public class HangupCall : HangupCallBase
-{
- ///
- public HangupCall([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- /// The to execute when the call was no longer active.
- ///
- [Port] public IActivity? Disconnected { get; set; }
-
- ///
- protected override async ValueTask HandleDoneAsync(ActivityExecutionContext context) => await context.CompleteActivityAsync(OnCompletedAsync);
-
- ///
- protected override async ValueTask HandleDisconnectedAsync(ActivityExecutionContext context) => await context.ScheduleActivityAsync(Disconnected, OnCompletedAsync);
-
- ///
- /// Executed when any child activity completed.
- ///
- private async ValueTask OnCompletedAsync(ActivityCompletedContext context) => await context.TargetContext.CompleteActivityAsync();
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/HangupCallBase.cs b/src/modules/Elsa.Telnyx/Activities/HangupCallBase.cs
deleted file mode 100644
index dd2cb998c..000000000
--- a/src/modules/Elsa.Telnyx/Activities/HangupCallBase.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using Elsa.Extensions;
-using Elsa.Telnyx.Client.Models;
-using Elsa.Telnyx.Client.Services;
-using Elsa.Telnyx.Extensions;
-using Elsa.Workflows;
-using Elsa.Workflows.Attributes;
-using Elsa.Workflows.Models;
-using Refit;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-/// Hang up the call.
-///
-[Activity(Constants.Namespace, "Hang up the call.", Kind = ActivityKind.Task)]
-public abstract class HangupCallBase : Activity
-{
- ///
- protected HangupCallBase(string? source = default, int? line = default) : base(source, line)
- {
- }
-
- ///
- /// Unique identifier and token for controlling the call.
- ///
- [Input(DisplayName = "Call Control ID", Description = "Unique identifier and token for controlling the call.", Category = "Advanced")]
- public Input CallControlId { get; set; } = default!;
-
- ///
- protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
- {
- var callControlId = CallControlId.Get(context);
- var request = new HangupCallRequest(ClientState: context.CreateCorrelatingClientState());
- var telnyxClient = context.GetRequiredService();
-
- try
- {
- await telnyxClient.Calls.HangupCallAsync(callControlId, request, context.CancellationToken);
- await HandleDoneAsync(context);
- }
- catch (ApiException e)
- {
- if (!await e.CallIsNoLongerActiveAsync()) throw;
- await HandleDisconnectedAsync(context);
- }
- }
-
- ///
- /// Executed when the call was hangup.
- ///
- protected abstract ValueTask HandleDoneAsync(ActivityExecutionContext context);
-
- ///
- /// Executed when the call was no longer active.
- ///
- protected abstract ValueTask HandleDisconnectedAsync(ActivityExecutionContext context);
-}
\ No newline at end of file
diff --git a/src/modules/Elsa.Telnyx/Activities/IncomingCall.cs b/src/modules/Elsa.Telnyx/Activities/IncomingCall.cs
deleted file mode 100644
index 82df2aa0c..000000000
--- a/src/modules/Elsa.Telnyx/Activities/IncomingCall.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using System.Runtime.CompilerServices;
-using Elsa.Expressions.Models;
-using Elsa.Extensions;
-using Elsa.Telnyx.Bookmarks;
-using Elsa.Telnyx.Helpers;
-using Elsa.Telnyx.Models;
-using Elsa.Telnyx.Payloads.Call;
-using Elsa.Workflows;
-using Elsa.Workflows.Attributes;
-using Elsa.Workflows.UIHints;
-using Elsa.Workflows.Models;
-
-namespace Elsa.Telnyx.Activities;
-
-///
-/// Triggered when an inbound phone call is received for any of the specified source or destination phone numbers.
-///
-[Activity(
- "Telnyx",
- "Telnyx",
- "Triggered when an inbound phone call is received for any of the specified source or destination phone numbers.",
- Kind = ActivityKind.Trigger)]
-public class IncomingCall : Trigger
-{
- ///
- public IncomingCall([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
- {
- }
-
- ///
- /// A list of destination numbers to respond to.
- ///
- [Input(Description = "A list of destination numbers to respond to.", UIHint = InputUIHints.MultiText)]
- public Input> To { get; set; } = default!;
-
- ///
- /// A list of source numbers to respond to.
- ///
- [Input(Description = "A list of source numbers to respond to.", UIHint = InputUIHints.MultiText)]
- public Input> From { get; set; } = default!;
-
- ///
- /// Match any inbound calls.
- ///
- [Input(Description = "Match any inbound calls.")]
- public Input CatchAll { get; set; } = default!;
-
- ///
- protected override IEnumerable