Added SendEmail activity (#19)

This commit is contained in:
Sipke Schoorstra 2019-02-16 11:57:45 +01:00 committed by GitHub
parent c2797e6b71
commit 54d16e9767
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 312 additions and 7 deletions

View file

@ -63,6 +63,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleDashboard.Web", "src\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Persistence.InMemory", "src\core\Elsa.Persistence.InMemory\Elsa.Persistence.InMemory.csproj", "{089E23E7-0B8D-4BB6-949D-EB669C116D9E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Activities.Email", "src\activities\Elsa.Activities.Email\Elsa.Activities.Email.csproj", "{D20FCB88-9DCA-49EA-9CC2-5B94DD935D30}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Web.Activities.Email", "src\web\modules\Elsa.Web.Activities.Email\Elsa.Web.Activities.Email.csproj", "{6B5E8D2F-3C4A-407A-B78C-DF4C3B32FF92}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -149,6 +153,14 @@ Global
{089E23E7-0B8D-4BB6-949D-EB669C116D9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{089E23E7-0B8D-4BB6-949D-EB669C116D9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{089E23E7-0B8D-4BB6-949D-EB669C116D9E}.Release|Any CPU.Build.0 = Release|Any CPU
{D20FCB88-9DCA-49EA-9CC2-5B94DD935D30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D20FCB88-9DCA-49EA-9CC2-5B94DD935D30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D20FCB88-9DCA-49EA-9CC2-5B94DD935D30}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D20FCB88-9DCA-49EA-9CC2-5B94DD935D30}.Release|Any CPU.Build.0 = Release|Any CPU
{6B5E8D2F-3C4A-407A-B78C-DF4C3B32FF92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B5E8D2F-3C4A-407A-B78C-DF4C3B32FF92}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B5E8D2F-3C4A-407A-B78C-DF4C3B32FF92}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B5E8D2F-3C4A-407A-B78C-DF4C3B32FF92}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -178,6 +190,8 @@ Global
{B5E36E84-1978-43C7-8859-F5184C9A657C} = {B33F1927-FF0A-4826-80C6-F480E9C43892}
{27BD3AE7-8D3B-4D19-A8E3-4DC6922C2213} = {C55090FE-8506-4FDA-928F-5ACBB9CBE019}
{089E23E7-0B8D-4BB6-949D-EB669C116D9E} = {35F44BE9-13D0-417C-A01A-F0787BEE6DC3}
{D20FCB88-9DCA-49EA-9CC2-5B94DD935D30} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
{6B5E8D2F-3C4A-407A-B78C-DF4C3B32FF92} = {B33F1927-FF0A-4826-80C6-F480E9C43892}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8B0975FD-7050-48B0-88C5-48C33378E158}

View file

@ -0,0 +1,13 @@
using Elsa.Expressions;
using Elsa.Models;
namespace Elsa.Activities.Email.Activities
{
public class SendEmail : Activity
{
public WorkflowExpression<string> From { get; set; }
public WorkflowExpression<string> To { get; set; }
public WorkflowExpression<string> Subject { get; set; }
public WorkflowExpression<string> Body { get; set; }
}
}

View file

@ -0,0 +1,27 @@
using System.Collections.Generic;
using Elsa.Activities.Email.Activities;
using Elsa.Models;
using Microsoft.Extensions.Localization;
namespace Elsa.Activities.Email
{
public class ActivityDescriptors : ActivityDescriptorProviderBase
{
public ActivityDescriptors(IStringLocalizer<ActivityDescriptors> localizer)
{
T = localizer;
}
private IStringLocalizer<ActivityDescriptors> T { get; }
private LocalizedString Category => T["Email"];
protected override IEnumerable<ActivityDescriptor> Describe()
{
yield return ActivityDescriptor.ForAction<SendEmail>(
Category,
T["Send Email"],
T["Send an email message via SMTP."],
T["Done"]);
}
}
}

View file

@ -0,0 +1,42 @@
using System.Net.Mail;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Activities.Email.Activities;
using Elsa.Handlers;
using Elsa.Models;
using Elsa.Results;
namespace Elsa.Activities.Email.Drivers
{
public class SendEmailDriver : ActivityDriver<SendEmail>
{
private readonly IWorkflowExpressionEvaluator expressionEvaluator;
private readonly SmtpClient smtpClient;
public SendEmailDriver(IWorkflowExpressionEvaluator expressionEvaluator, SmtpClient smtpClient)
{
this.expressionEvaluator = expressionEvaluator;
this.smtpClient = smtpClient;
}
protected override async Task<ActivityExecutionResult> OnExecuteAsync(SendEmail activity, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken)
{
var from = await expressionEvaluator.EvaluateAsync(activity.From, workflowContext, cancellationToken);
var to = await expressionEvaluator.EvaluateAsync(activity.To, workflowContext, cancellationToken);
var subject = await expressionEvaluator.EvaluateAsync(activity.Subject, workflowContext, cancellationToken);
var body = await expressionEvaluator.EvaluateAsync(activity.Body, workflowContext, cancellationToken);
var mailMessage = new MailMessage
{
From = new MailAddress(@from),
Body = body,
Subject = subject
};
mailMessage.To.Add(to);
smtpClient.SendAsync(mailMessage, null);
return Endpoint("Done");
}
}
}

View file

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageVersion>1.0.0</PackageVersion>
<Authors>Sipke Schoorstra</Authors>
<Description>Elsa is a set of workflowing libraries and tools to enable super-fast workflowing capabilities in any .NET Core application.</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/sfmskywalker/Elsa</PackageProjectUrl>
<RepositoryUrl>https://github.com/sfmskywalker/Elsa</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows, orchard</PackageTags>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,39 @@
using System;
using System.Net.Mail;
using Elsa.Activities.Email.Drivers;
using Elsa.Activities.Email.Options;
using Elsa.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace Elsa.Activities.Email.Extensions
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddEmailDescriptors(this IServiceCollection services)
{
return services.AddActivityDescriptors<ActivityDescriptors>();
}
public static IServiceCollection AddEmailDrivers(this IServiceCollection services, IConfiguration configuration)
{
services.AddEmailDescriptors();
services
.AddOptions()
.Configure<SmtpOptions>(configuration)
.AddSingleton(CreateSmtpClient)
.AddActivityDriver<SendEmailDriver>();
return services;
}
private static SmtpClient CreateSmtpClient(IServiceProvider serviceProvider)
{
var options = serviceProvider.GetRequiredService<IOptions<SmtpOptions>>().Value;
return new SmtpClient(options.Host, options.Port);
}
}
}

View file

@ -0,0 +1,8 @@
namespace Elsa.Activities.Email.Options
{
public class SmtpOptions
{
public string Host { get; set; }
public int Port { get; set; }
}
}

View file

@ -24,6 +24,7 @@
<ItemGroup>
<ProjectReference Include="..\..\web\modules\Elsa.Web.Activities.Console\Elsa.Web.Activities.Console.csproj" />
<ProjectReference Include="..\..\web\modules\Elsa.Web.Activities.Email\Elsa.Web.Activities.Email.csproj" />
<ProjectReference Include="..\..\web\modules\Elsa.Web.Activities.Http\Elsa.Web.Activities.Http.csproj" />
<ProjectReference Include="..\..\web\modules\Elsa.Web.Activities.Primitives\Elsa.Web.Activities.Primitives.csproj" />
<ProjectReference Include="..\..\web\modules\Elsa.Web.Components\Elsa.Web.Components.csproj" />

View file

@ -20,6 +20,7 @@
<ItemGroup>
<ProjectReference Include="..\..\activities\Elsa.Activities.Console\Elsa.Activities.Console.csproj" />
<ProjectReference Include="..\..\activities\Elsa.Activities.Email\Elsa.Activities.Email.csproj" />
<ProjectReference Include="..\..\activities\Elsa.Activities.Http\Elsa.Activities.Http.csproj" />
<ProjectReference Include="..\..\activities\Elsa.Activities.Primitives\Elsa.Activities.Primitives.csproj" />
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />

View file

@ -1,4 +1,5 @@
using Elsa.Activities.Console.Extensions;
using Elsa.Activities.Email.Extensions;
using Elsa.Activities.Http.Extensions;
using Elsa.Activities.Primitives.Extensions;
using Elsa.Extensions;
@ -29,7 +30,8 @@ namespace SampleHost.Web
.AddWorkflowsFileSystemPersistence(Configuration.GetSection("FileStore"))
.AddPrimitiveWorkflowDrivers()
.AddConsoleWorkflowDrivers()
.AddHttpWorkflowDrivers();
.AddHttpWorkflowDrivers()
.AddEmailDrivers(Configuration.GetSection("Smtp"));
services
.AddMvc()

View file

@ -8,5 +8,12 @@
"FileStore": {
"RootDirectory": "C:\\Activities\\Projects\\Elsa\\src\\samples\\SampleDashboard.Web\\App_Data\\Sites\\Default\\workflows",
"Format": "YAML"
},
"Smtp": {
"Host": "localhost",
"Port": 2525,
"Credentials": {
"Type": "None"
}
}
}

View file

@ -2,6 +2,6 @@
[assembly: Module(
Name = "Console Activities",
Category = "Workflows",
Category = "Elsa Workflows",
Description = "Provides a set of primitive activities."
)]

View file

@ -0,0 +1,26 @@
using Elsa.Activities.Email.Activities;
using Elsa.Web.Activities.Email.ViewModels;
using Elsa.Web.Components.ViewModels;
using Elsa.Web.Drivers;
namespace Elsa.Web.Activities.Email.Display
{
public class SendEmailDisplay : ActivityDisplayDriver<SendEmail, SendEmailViewModel>
{
protected override void EditActivity(SendEmail activity, SendEmailViewModel model)
{
model.From = new ExpressionViewModel(activity.From);
model.To = new ExpressionViewModel(activity.To);
model.Subject = new ExpressionViewModel(activity.Subject);
model.Body = new ExpressionViewModel(activity.Body);
}
protected override void UpdateActivity(SendEmailViewModel model, SendEmail activity)
{
activity.From = model.From.ToWorkflowExpression<string>();
activity.To = model.To.ToWorkflowExpression<string>();
activity.Subject = model.Subject.ToWorkflowExpression<string>();
activity.Body = model.Body.ToWorkflowExpression<string>();
}
}
}

View file

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageVersion>1.0.0</PackageVersion>
<Authors>Sipke Schoorstra</Authors>
<Description>Elsa is a set of workflowing libraries and tools to enable super-fast workflowing capabilities in any .NET Core application.</Description>
<Copyright>2019</Copyright>
<PackageProjectUrl>https://github.com/sfmskywalker/Elsa</PackageProjectUrl>
<RepositoryUrl>https://github.com/sfmskywalker/Elsa</RepositoryUrl>
<RepositoryType>GitHub</RepositoryType>
<PackageTags>elsa, workflows, orchard</PackageTags>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\activities\Elsa.Activities.Email\Elsa.Activities.Email.csproj" />
<ProjectReference Include="..\Elsa.Web.Abstractions\Elsa.Web.Abstractions.csproj" />
<ProjectReference Include="..\Elsa.Web.Components\Elsa.Web.Components.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="OrchardCore.Module.Targets" Version="1.0.0-beta3-70705" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,7 @@
using OrchardCore.Modules.Manifest;
[assembly: Module(
Name = "Email Activities",
Category = "Elsa Workflows",
Description = "Provides a Send Email activity."
)]

View file

@ -0,0 +1,18 @@
using Elsa.Activities.Email.Extensions;
using Elsa.Web.Activities.Email.Display;
using Elsa.Web.Extensions;
using Microsoft.Extensions.DependencyInjection;
using OrchardCore.Modules;
namespace Elsa.Web.Activities.Email
{
public class Startup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services
.AddEmailDescriptors()
.AddActivityDisplay<SendEmailDisplay>();
}
}
}

View file

@ -0,0 +1,12 @@
using Elsa.Web.Components.ViewModels;
namespace Elsa.Web.Activities.Email.ViewModels
{
public class SendEmailViewModel
{
public ExpressionViewModel From { get; set; }
public ExpressionViewModel To { get; set; }
public ExpressionViewModel Subject { get; set; }
public ExpressionViewModel Body { get; set; }
}
}

View file

@ -0,0 +1,6 @@
@model ActivityShapeModel<SendEmail>
@{
var activityDescriptor = Model.Activity.Descriptor;
}
<h4 class="card-title"><i class="fas fa-globe"></i>@activityDescriptor.DisplayText</h4>
<p>@activityDescriptor.Description</p>

View file

@ -0,0 +1,6 @@
@model ActivityShapeModel<SendEmail>
<header>
<h4><i class="fas fa-globe"></i>@Model.DisplayText</h4>
<i>&quot;@($"{Model.Activity.Subject}")&quot;</i>
</header>

View file

@ -0,0 +1,25 @@
@model SendEmailViewModel
<div class="form-group">
<label asp-for="From">@T["From"]</label>
<vc:expression-editor model="@Model.From" prefix="@Html.NameFor(m => m.From)"></vc:expression-editor>
<span asp-validation-for="From" class="text-danger"></span>
<small class="form-text text-muted">@T["The sender's email address."]</small>
</div>
<div class="form-group">
<label asp-for="To">@T["To"]</label>
<vc:expression-editor model="@Model.To" prefix="@Html.NameFor(m => m.To)"></vc:expression-editor>
<span asp-validation-for="To" class="text-danger"></span>
<small class="form-text text-muted">@T["The recipient's email address."]</small>
</div>
<div class="form-group">
<label asp-for="Subject">@T["Subject"]</label>
<vc:expression-editor model="@Model.Subject" prefix="@Html.NameFor(m => m.Subject)"></vc:expression-editor>
<span asp-validation-for="Subject" class="text-danger"></span>
<small class="form-text text-muted">@T["The subject of the email message."]</small>
</div>
<div class="form-group">
<label asp-for="Body">@T["Body"]</label>
<vc:expression-editor model="@Model.Body" prefix="@Html.NameFor(m => m.Body)"></vc:expression-editor>
<span asp-validation-for="Body" class="text-danger"></span>
<small class="form-text text-muted">@T["The message to send."]</small>
</div>

View file

@ -0,0 +1,7 @@
@using Elsa.Web.ViewModels
@using Elsa.Activities.Email.Activities
@using Elsa.Web.Activities.Email.ViewModels
@using OrchardCore.Mvc.Core.Utilities
@inherits OrchardCore.DisplayManagement.Razor.RazorPage<TModel>
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Elsa.Web.Components

View file

@ -2,6 +2,6 @@
[assembly: Module(
Name = "HTTP Activities",
Category = "Workflows",
Category = "Elsa Workflows",
Description = "Provides a set of HTTP activities."
)]

View file

@ -2,6 +2,6 @@
[assembly: Module(
Name = "Primitive Activities",
Category = "Workflows",
Category = "Elsa Workflows",
Description = "Provides a set of primitive activities."
)]

View file

@ -2,7 +2,7 @@
[assembly: Module(
Name = "Workflows View Components",
Category = "Workflows",
Category = "Elsa Workflows",
Description = "Provides a set of reusable view components such as the Workflow Editor.",
Dependencies = new[] { "OrchardCore.Resources" }
)]

View file

@ -2,7 +2,7 @@
[assembly: Module(
Name = "Workflows Management",
Category = "Workflows",
Category = "Elsa Workflows",
Description = "Provides admin screens to manage workflows.",
Dependencies = new[] { "Elsa.Web.BootstrapTheme.Web.Components" }
)]

View file

@ -2,6 +2,6 @@
[assembly: Module(
Name = "File System Persistence Provider",
Category = "Workflows",
Category = "Elsa Workflows",
Description = "Registers a file system based persistence provider."
)]