基于Elsa扩展SendEmail活动的批量邮件与工作流调用技术咨询
基于Elsa框架实现批量邮件营销模块的实操方案
一、联系人加载与过滤实现
1. 从数据库加载并过滤
自定义LoadContactsFromDatabase活动,结合Elsa的表达式能力实现动态过滤:
- 活动输入配置:添加
FilterExpression(类型选Liquid/JavaScript,支持用户写过滤规则,比如{{ Contact.Subscribed && Contact.Region == 'Asia' }}) - 核心逻辑代码:
public class LoadContactsFromDatabase : Activity { [ActivityInput(Hint = "过滤规则(Liquid格式)")] public string FilterExpression { get; set; } = string.Empty; private readonly AppDbContext _dbContext; private readonly ILiquidTemplateRenderer _liquidRenderer; public LoadContactsFromDatabase(AppDbContext dbContext, ILiquidTemplateRenderer liquidRenderer) { _dbContext = dbContext; _liquidRenderer = liquidRenderer; } protected override async ValueTask<IActivityExecutionResult> OnExecuteAsync(ActivityExecutionContext context) { var allContacts = await _dbContext.Contacts.ToListAsync(); var filteredContacts = new List<Contact>(); foreach (var contact in allContacts) { var renderResult = await _liquidRenderer.RenderAsync(FilterExpression, new { Contact = contact }); if (bool.TryParse(renderResult, out var isMatch) && isMatch) filteredContacts.Add(contact); } // 将筛选结果存入工作流上下文,供后续SendEmail活动调用 context.WorkflowContext.Set("FilteredContacts", filteredContacts); return Done(); } }
- 后续搭配Elsa内置的
ForEach活动,遍历FilteredContacts列表,逐个执行你自定义的SendEmail活动。
2. 上传CSV文件加载联系人
自定义UploadCsvContacts活动,实现文件上传+解析+过滤:
- 活动输入配置:添加
CsvFile(类型设为IFormFile,Elsa仪表盘会自动生成上传控件)、FilterExpression(同上述过滤规则) - 核心逻辑代码(依赖CsvHelper库):
public class UploadCsvContacts : Activity { [ActivityInput(Hint = "上传联系人CSV")] public IFormFile CsvFile { get; set; } = default!; [ActivityInput(Hint = "过滤规则(JavaScript格式)")] public string FilterExpression { get; set; } = string.Empty; private readonly IJavascriptEvaluator _javascriptEvaluator; public UploadCsvContacts(IJavascriptEvaluator javascriptEvaluator) { _javascriptEvaluator = javascriptEvaluator; } protected override async ValueTask<IActivityExecutionResult> OnExecuteAsync(ActivityExecutionContext context) { // 解析CSV var contacts = new List<Contact>(); using (var reader = new StreamReader(CsvFile.OpenReadStream())) using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture)) { contacts = csv.GetRecords<Contact>().ToList(); } // JS表达式过滤 var filteredContacts = new List<Contact>(); foreach (var contact in contacts) { var isMatch = await _javascriptEvaluator.EvaluateAsync<bool>(FilterExpression, new { Contact = contact }); if (isMatch) filteredContacts.Add(contact); } context.WorkflowContext.Set("FilteredContacts", filteredContacts); return Done(); } }
二、工作流运行后自动停止
直接用Elsa内置的TerminateWorkflow活动:
- 在工作流设计器中,把
TerminateWorkflow拖到ForEach活动的末尾(所有邮件发送完成后) - 可选:添加
If活动判断FilteredContacts是否为空,若为空直接跳转至TerminateWorkflow,避免无意义执行
三、通过仪表盘调用工作流
1. 手动触发
- 进入Elsa仪表盘的Workflows页面,找到目标工作流
- 点击Run按钮,若工作流有输入参数(比如CSV文件、过滤规则),会弹出参数填写界面,提交后立即触发运行
2. 配置自动触发(可选)
- 定时触发:添加
Cron活动到工作流开头,在仪表盘配置Cron表达式(比如0 0 10 * * ?每天10点运行) - HTTP触发:添加
HttpEndpoint活动,配置触发路径,在仪表盘的Triggers页面启用,通过请求该路径触发
自定义活动参考截图
- 自定义SendEmail活动配置界面:

- 自定义活动输入设置界面:

内容的提问来源于stack exchange,提问作者Rashid Raza
相关产品推荐
相关产品推荐

