StrongGrid 0.109.0

dotnet add package StrongGrid --version 0.109.0                
NuGet\Install-Package StrongGrid -Version 0.109.0                
此命令旨在在 Visual Studio 的包管理器控制台中使用,因为它使用了 NuGet 模块版本的 Install-Package
<PackageReference Include="StrongGrid" Version="0.109.0" />                
对于支持 PackageReference 的项目,请将此 XML 节复制到项目文件中以引用该包。
paket add StrongGrid --version 0.109.0                
#r "nuget: StrongGrid, 0.109.0"                
#r 指令可用于 F# Interactive 和 Polyglot Notebooks。将其复制到交互式工具或脚本的源代码中,以引用包。
// Install StrongGrid as a Cake Addin
#addin nuget:?package=StrongGrid&version=0.109.0

// Install StrongGrid as a Cake Tool
#tool nuget:?package=StrongGrid&version=0.109.0                

StrongGrid

Discussions at https://github.com/Jericho/StrongGrid/discussions FOSSA Status License Sourcelink

Build status Tests Coverage Status CodeFactor

发布说明 NuGet(稳定版) MyGet(预发布版)
GitHub release NuGet Version MyGet Pre Release

关于

StrongGrid 是一个用于 SendGrid v3 API 的强类型库。

从 2016 年 2 月开始,它作为 SendGrid 自己的库的一个分支。当时,SendGrid 的 API 的 C# 客户端广泛使用了 dynamic 类型,这非常不便,并且让开发者感到非常困难。此外,他们的 C# 客户端只覆盖了 mail 终端点,但无法访问 email marketing API 中的其他终端点,例如创建列表和分段,导入联系人等。我在 2016 年 3 月向 SendGrid 提交了一个 pull request,但未获接受,并在 2016 年 6 月最终关闭。

2016年10月,我决定将这个库发布为nuget包,因为SendGrid的库仍然使用dynamic且缺乏强类型。截至2017年2月14日,dynamic已从SendGrid的官方csharp库中移除,并增加了对.Net Standard的支持。

StrongGrid包括一个客户端,它允许您与SendGrid API中的所有“资源”交互(例如:发送电子邮件、管理列表、联系人分段、根据条件搜索联系人、创建API密钥等)。

StrongGrid还包括一个解析器,用于解析从SendGrid发送到您自己的WebAPI的webhook。此解析器支持SendGrid可以发布到您的API的两个类型的webhook:事件webhook和入站解析webhook。

自2017年11月起,StrongGrid还包括一个“预热引擎”,允许您使用自定义的计划来预热IP地址。

如果您需要有关如何设置SendGrid webhooks的信息,请参阅以下资源

安装

将StrongGrid纳入您的C#项目的最简单方法是向项目中添加nuget包

PM> Install-Package StrongGrid

一旦您在项目中正确引用了StrongGrid库,请添加以下命名空间

using StrongGrid;

.NET框架支持

StrongGrid支持4.86.07.0 .NET框架,以及任何支持.NET Standard 2.1的框架(包括.NET Core 3.xASP.NET Core 3.x)。

用法

客户端

您可以像这样声明客户端变量

var apiKey = "... your api key...";
var strongGridClient = new StrongGrid.Client(apiKey);

如果您需要使用代理,可以将它传递给客户端

var apiKey = "... your api key...";
var proxy = new WebProxy("http://myproxy:1234");
var strongGridClient = new StrongGrid.Client(apiKey, proxy);

最常见的情况之一是发送事务性电子邮件。

以下是一些示例

// Send an email to a single recipient
var messageId = await strongGridClient.Mail.SendToSingleRecipientAsync(to, from, subject, html, text).ConfigureAwait(false);

// Send an email to multiple recipients
var messageId = await strongGridClient.Mail.SendToMultipleRecipientsAsync(new[] { to1, to2, to3 }, from, subject, html, text).ConfigureAwait(false);

// Include attachments when sending an email
var attachments = new[]
{
	Attachment.FromLocalFile(@"C:\MyDocuments\MySpreadsheet.xlsx"),
	Attachment.FromLocalFile(@"C:\temp\Headshot.jpg")
};
var messageId = await strongGridClient.Mail.SendToSingleRecipientAsync(to, from, subject, html, text, attachments: attachments).ConfigureAwait(false);

您可以通过客户端访问大量的“资源”(如联系人、列表、分段、设置、发件人身份验证等),每个资源都提供多种方法,如检索、创建、更新、删除等。

以下是一些示例

// Import a new contact or update existing contact if a match is found
var importJobId = await client.Contacts.UpsertAsync(email, firstName, lastName, addressLine1, addressLine2, city, stateOrProvince, country, postalCode, alternateEmails, customFields, null, cancellationToken).ConfigureAwait(false);

// Import several new contacts or update existing contacts when a match is found
var contacts = new[]
{
	new Models.Contact("[email protected]", "John", "Doe"),
	new Models.Contact("[email protected]", "John", "Smith"),
	new Models.Contact("[email protected]", "Bob", "Smith")
};
var importJobId = await client.Contacts.UpsertAsync(contacts, null, cancellationToken).ConfigureAwait(false);

// Send an email
await strongGridClient.Mail.SendToSingleRecipientAsync(to, from, subject, htmlContent, textContent);

// Retreive all the API keys in your account
var apiKeys = await strongGridClient.ApiKeys.GetAllAsync();

// Add an email address to a suppression group
await strongGridClient.Suppressions.AddAddressToUnsubscribeGroupAsync(groupId, "[email protected]");

// Get statistics between the two specific dates
var globalStats = await strongGridClient.Statistics.GetGlobalStatisticsAsync(startDate, endDate);

// Create a new email template
var template = await strongGridClient.Templates.CreateAsync("My template");

动态模板

2018年8月,SendGrid在其API中发布了新功能,允许您使用Handlebars语法指定内容中的合并字段。在StrongGrid中使用此强大的新功能非常简单。

首先,在创建新模板时,必须指定TemplateType.Dynamic,如下例所示

var dynamicTemplate = await strongGridClient.Templates.CreateAsync("My dynamic template", TemplateType.Dynamic).ConfigureAwait(false);

其次,创建内容的版本,其中您使用Handlebars语法来定义合并字段,您还可以指定可选的“测试数据”,SendGrid UI将使用这些数据向您展示示例。请放心,这些测试数据绝不会发送给任何收件人。以下代码示例演示了创建包含简单替换的动态模板版本,用于CreditBalance、用于Customer.first_nameCustomer.last_name深度对象替换以及显示多个订单信息的迭代器

var subject = "Dear {{Customer.first_name}}";
var htmlContent = @"
	<html>
		<body>
			Hello {{Customer.first_name}} {{Customer.last_name}}. 
			You have a credit balance of {{CreditBalance}}<br/>
			<ol>
			{{#each Orders}}
				<li>You ordered: {{this.item}} on: {{this.date}}</li>
			{{/each}}
			</ol>
		</body>
	</html>";
var textContent = "... this is the text content ...";
var testData = new
{
	Customer = new
	{
		first_name = "aaa",
		last_name = "aaa"
	},
	CreditBalance = 99.88,
	Orders = new[]
	{
		new { item = "item1", date = "1/1/2018" },
		new { item = "item2", date = "1/2/2018" },
		new { item = "item3", date = "1/3/2018" }
	}
};
await strongGridClient.Templates.CreateVersionAsync(dynamicTemplate.Id, "Version 1", subject, htmlContent, textContent, true, EditorType.Code, testData).ConfigureAwait(false);

最后,您可以向收件人发送电子邮件并指定适用于他们的动态数据,如下所示

var dynamicData = new
{
	Customer = new
	{
		first_name = "Bob",
		last_name = "Smith"
	},
	CreditBalance = 56.78,
	Orders = new[]
	{
		new { item = "shoes", date = "2/1/2018" },
		new { item = "hat", date = "1/4/2018" }
	}
};
var to = new MailAddress("[email protected]", "Bob Smith");
var from = new MailAddress("[email protected]", "John Smith");
var messageId = await strongGridClient.Mail.SendToSingleRecipientAsync(to, from, dynamicTemplate.Id, dynamicData).ConfigureAwait(false);

Webhook解析器

以下是一个基本示例,展示如何解析SendGrid的webhook的.net 6.0 API控制器

using Microsoft.AspNetCore.Mvc;
using StrongGrid;

namespace WebApplication1.Controllers
{
	[Route("api/[controller]")]
	[ApiController]
	public class SendGridWebhooksController : ControllerBase
	{
		[HttpPost]
		[Route("Events")]
		public async Task<IActionResult> ReceiveEvents()
		{
			var parser = new WebhookParser();
			var events = await parser.ParseEventsWebhookAsync(Request.Body).ConfigureAwait(false);

			// ... do something with the events ...

			return Ok();
		}

		[HttpPost]
		[Route("InboundEmail")]
		public async Task<IActionResult> ReceiveInboundEmail()
		{
			var parser = new WebhookParser();
			var inboundEmail = await parser.ParseInboundEmailWebhookAsync(Request.Body).ConfigureAwait(false);

			// ... do something with the inbound email ...

			return Ok();
		}
    }
}

解析已签名webhook

SendGrid 具备名为 签名的 Event Webhook 请求 的功能,您可以在登录 SendGrid 账户后,在 设置 > 邮件设置 > 事件设置 下启用该功能。启用此功能时,SendGrid 会将与每个 webhook 一起包含额外的信息,以便您验证该 webhook 确实来自 SendGrid,因此可以信任。具体来说,webhook 将包括一个“签名”和一个“时间戳”,您必须使用这两个值以及您在启用功能时 SendGrid 生成的公钥来验证提交给你的数据。请注意,SendGrid 有时将此值称为“验证键”。如果您对此验证数据的细节好奇并想了解更多信息,我邀请您阅读 SendGrid 关于此主题的 文档

但是,如果您想避免学习如何执行验证,并且只想方便地自动执行此验证,StrongGrid 可以帮助您!WebhookParser 类有一个名为 ParseSignedEventsWebhookAsync 的方法,它将自动验证数据,如果验证失败,将引发安全异常。如果验证失败,您应将 webhook 数据视为无效。以下是其工作原理:

using Microsoft.AspNetCore.Mvc;
using StrongGrid;
using System.Security;

namespace WebApplication1.Controllers
{
	[Route("api/[controller]")]
	[ApiController]
	public class SendGridWebhooksController : ControllerBase
	{
		[HttpPost]
		[Route("SignedEvents")]
		public async Task<IActionResult> ReceiveSignedEvents()
		{
			// Get your public key
			var apiKey = "... your api key...";
			var strongGridClient = new StrongGrid.Client(apiKey);
			var publicKey = await strongGridClient.WebhookSettings.GetSignedEventsPublicKeyAsync().ConfigureAwait(false);

			// Get the signature and the timestamp from the request headers
			var signature = Request.Headers[WebhookParser.SIGNATURE_HEADER_NAME]; // SIGNATURE_HEADER_NAME is a convenient constant provided so you don't have to remember the name of the header
			var timestamp = Request.Headers[WebhookParser.TIMESTAMP_HEADER_NAME]; // TIMESTAMP_HEADER_NAME is a convenient constant provided so you don't have to remember the name of the header

			// Parse the events. The signature will be automatically validated and a security exception thrown if unable to validate
			try
			{
				var parser = new WebhookParser();
				var events = await parser.ParseSignedEventsWebhookAsync(Request.Body, publicKey, signature, timestamp).ConfigureAwait(false);

				// ... do something with the events...
			}
			catch (SecurityException e)
			{
				// ... unable to validate the data...
			}

			return Ok();
		}
	}
}

预热引擎

SendGrid 已经提供了预热 IP 地址的方式,但您无法控制此过程。StrongGrid 通过为您提供可以根据您需求定制的预热引擎来解决此问题。

典型用法
// Prepare the warmup engine
var poolName = "warmup_pool";
var dailyVolumePerIpAddress = new[] { 50, 100, 500, 1000 };
var resetDays = 1; // Should be 1 if you send on a daily basis, should be 2 if you send every other day, should be 7 if you send on a weekly basis, etc.
var warmupSettings = new WarmupSettings(poolName, dailyVolumePerIpAddress, resetDays);
var warmupEngine = new WarmupEngine(warmupSettings, client);

// This is a one-time call to create the IP pool that will be used to warmup the IP addresses
var ipAddresses = new[] { "168.245.123.132", "168.245.123.133" };
await warmupEngine.PrepareWithExistingIpAddressesAsync(ipAddresses, CancellationToken.None).ConfigureAwait(false);

// Send emails using any of the following methods
var result = warmupEngine.SendToSingleRecipientAsync(...);
var result = warmupEngine.SendToMultipleRecipientsAsync(...);
var result = warmupEngine.SendAsync(...);

Send... 方法返回一个 WarmupResult 对象,它会告诉您是否已完成操作,并且还会提供使用 IP 池发送的邮件的消息 ID(如果适用)和默认 IP 地址发送的邮件的消息 ID(默认 IP 地址不会被预热)。预热引擎将使用 IP 池发送邮件,直到达到每天的容量限制,多余的邮件将使用默认 IP 地址发送。当您接近每天的容量限制时,预热引擎可能必须将给定的“发送”拆分为两个消息:其中一个使用 IP 池发送,另一个使用默认 IP 地址发送。让我们用一个例子来说明:假设您在自己达到每日预热限制之前还有 15 封邮件,您尝试向 20 个收件人发送邮件。在这种情况下,前 15 封邮件将使用预热 IP 池发送,剩下的 5 封邮件将使用默认 IP 地址发送。

更高级的用法

建议的每日容量:如果您不确定使用哪些每日限制,SendGrid 提供了建议的时间表,StrongGrid 提供了一个方便的方法来使用建议的时间表,该时间表根据您预期每天发送的电子邮件数量而定制。您只需提供一个关于每日容量的粗略估计值,StrongGrid 就可以配置适当的预热设置。以下是一个示例

var poolName = "warmup_pool";
var estimatedDailyVolume = 50000; // Should be your best guess: how many emails you will be sending in a typical day
var resetDays = 1; // Should be 1 if you send on a daily basis, should be 2 if you send every other day, should be 7 if you send on a weekly basis, etc.
var warmupSettings = WarmupSettings.FromSendGridRecomendedSettings(poolName, estimatedDailyVolume, resetDays);

进度仓库:默认情况下,StrongGrid的WarmupEngine将在您的计算机的temp文件夹中的文件写入进度信息,但您可以选择覆盖此设置。您可以更改保存此文件的文件夹,也可以选择使用完全不同的仓库。开箱即用,StrongGrid提供FileSystemWarmupProgressRepositoryMemoryWarmupProgressRepository。它还提供一个名为IWarmupProgressRepository的接口,允许您编写自己的实现,将进度数据保存到更适合您的位置,例如数据库、Azure、AWS等。请注意,MemoryWarmupProgressRepository旨在用于测试,我们不推荐在生产中使用它。这个建议的主要原因是因为数据存储在内存中,当您重新启动计算机时,数据会丢失。这意味着每次您重新启动计算机,您的预热过程都会从头开始。

// You select one of the following repositories available out of the box:
var warmupProgressRepository = new MemoryWarmupProgressRepository();
var warmupProgressRepository = new FileSystemWarmupProgressRepository();
var warmupProgressRepository = new FileSystemWarmupProgressRepository(@"C:\temp\myfolder\");
var warmupEngine = new WarmupEngine(warmupSettings, client, warmupProgressRepository);

购买新的IP地址:您可以使用SendGrid的用户界面购买新的IP地址,但StrongGrid的WarmupEngine使这个过程更加简单。您不需要调用PrepareWithExistingIpAddressesAsync(如前所述),而是可以调用PrepareWithNewIpAddressesAsync,StrongGrid将负责将新的IP地址添加到您的账户,并将它们添加到一个新的IP池中以便预热。提醒一下,请注意,应仅调用一次PrepareWithExistingIpAddressesAsyncPrepareWithNewIpAddressesAsync。如果再次调用任意一个方法,都将因为IP池已被创建而引发异常。

var howManyAddresses = 2; // How many ip addresses do you want to purchase?
var subusers = new[] { "your_subuser" }; // The subusers you authorize to send emails on the new ip addresses
await warmupEngine.PrepareWithNewIpAddressesAsync(howManyAddresses, subusers, CancellationToken.None).ConfigureAwait(false);

预热过程结束:当过程完成时,IP池将被删除,预热好的IP地址将返回到默认池中。之后,您可以调用strongGridClient.Mail.SendAsync(...)方法来发送您的电子邮件。

许可证

FOSSA Status

产品 兼容的和附加的计算目标框架版本。
.NET net5.0 已计算。 net5.0-windows 已计算。 net6.0 兼容。 net6.0-android 已计算。 net6.0-ios 已计算。 net6.0-maccatalyst 已计算。 net6.0-macos 已计算。 net6.0-tvos 已计算。 net6.0-windows 已计算。 net7.0 兼容。 net7.0-android 已计算。 net7.0-ios 已计算。 net7.0-maccatalyst 已计算。 net7.0-macos 已计算。 net7.0-tvos 已计算。 net7.0-windows 已计算。 net8.0 已计算。 net8.0-android 已计算。 net8.0-browser 已计算。 net8.0-ios 已计算。 net8.0-maccatalyst 已计算。 net8.0-macos 已计算。 net8.0-tvos 已计算。 net8.0-windows 已计算。
.NET Core netcoreapp3.0 已计算。 netcoreapp3.1 已计算。
.NET Standard netstandard2.1 兼容。
.NET Framework net48 兼容。 net481 已计算。
MonoAndroid monoandroid 已计算。
MonoMac monomac 已计算。
MonoTouch monotouch 已计算。
Tizen tizen60 已计算。
Xamarin.iOS xamarinios 已计算。
Xamarin.Mac xamarinmac 已计算。
Xamarin.TVOS xamarintvos 已计算。
Xamarin.WatchOS xamarinwatchos was computed. 
兼容目标框架(s)
包含目标框架(s) (在包中)
关于 目标框架.NET Standard 了解更多。

NuGet 包 (7)

显示依赖 StrongGrid 的顶级 5 个 NuGet 包

下载
Cake.SendGrid

Cake 构建插件,提供通过 SendGrid 发送电子邮件的别名。

AuthScape.TicketSystem

包描述

CodeStream.Comms.Messages

CodeStream Communication Messages为应用程序提供基础架构代码

Magnet.Providers.SendGrid

框架,用于在集成测试中接收短信和电子邮件。

Qw3.Mail.Service

用于与 stronggrid 库集成的简单包装服务。这使得可以一次性修改所有项目更容易。

GitHub 存储库 (1)

显示依赖 StrongGrid 的顶级 1 个流行 GitHub 存储库

存储库 星标
SciSharp/BotSharp
.NET 中的 AI 代理框架
版本 下载 最后更新
0.109.0 18,393 6/19/2024
0.108.0 12,655 5/26/2024
0.107.0 19,690 4/18/2024
0.106.0 23,837 2/16/2024
0.105.0 10,777 2/1/2024
0.104.0 9,754 1/19/2024
0.103.0 14,205 1/8/2024
0.102.0 11,401 11/18/2023
0.101.0 87,703 6/2/2023
0.100.0 4,901 6/1/2023
0.99.0 208 6/1/2023
0.98.0 117,808 1/20/2023
0.97.0 9,173 1/12/2023
0.96.0 30,649 12/2/2022
0.95.1 25,532 11/13/2022
0.94.0 31,640 9/30/2022
0.93.0 12,059 9/13/2022
0.92.0 10,775 8/22/2022
0.91.0 39,011 6/26/2022
0.90.0 30,411 4/21/2022
0.89.0 32,227 3/21/2022
0.88.2 22,179 3/15/2022
0.88.1 637 3/14/2022
0.88.0 7,552 2/5/2022
0.87.0 3,611 1/18/2022
0.86.0 636 1/14/2022
0.85.0 21,863 1/14/2022
0.84.0 61,081 11/25/2021
0.83.0 1,880 11/11/2021
0.82.0 115,958 5/23/2021
0.81.0 4,001 5/9/2021
0.80.0 723 5/5/2021
0.79.0 80,224 4/27/2021
0.78.0 1,583 4/15/2021
0.77.0 14,815 4/4/2021
0.76.0 55,035 1/20/2021
0.75.0 107,795 11/28/2020
0.74.0 1,024 11/26/2020
0.73.0 87,915 10/3/2020
0.72.1 61,372 9/15/2020
0.71.0 18,803 8/7/2020
0.70.0 32,741 6/24/2020
0.69.0 39,552 5/10/2020
0.68.0 14,200 4/13/2020
0.67.0 8,338 4/3/2020
0.66.0 23,859 3/26/2020
0.65.0 8,909 3/11/2020
0.64.0 6,736 3/6/2020
0.63.1 34,725 1/3/2020
0.62.0 23,851 11/29/2019
0.61.0 31,845 9/22/2019
0.60.0 61,978 7/7/2019
0.59.0 7,012 6/21/2019
0.58.0 3,730 6/6/2019
0.57.1 1,082 6/3/2019
0.56.1 900 5/30/2019
0.56.0 35,890 5/28/2019
0.55.0 15,335 5/16/2019
0.54.0 5,910 5/2/2019
0.53.0 3,714 4/23/2019
0.52.0 917 4/19/2019
0.51.0 3,239 4/14/2019
0.50.2 49,087 3/27/2019
0.50.1 921 3/27/2019
0.50.0 1,729 3/11/2019
0.49.1 14,842 11/9/2018
0.49.0 4,353 10/25/2018
0.48.0 24,115 8/20/2018
0.47.3 2,503 8/15/2018
0.47.2 1,024 8/14/2018
0.47.1 1,033 8/14/2018
0.47.0 2,681 8/4/2018
0.46.0 2,244 7/27/2018
0.45.0 14,352 6/12/2018
0.44.0 5,000 5/23/2018
0.43.0 11,261 5/5/2018
0.42.0 1,116 5/4/2018
0.41.0 1,199 5/2/2018
0.40.0 3,296 4/18/2018
0.39.0 1,905 4/9/2018
0.38.0 1,713 4/3/2018
0.37.0 2,476 3/20/2018
0.36.0 5,400 2/18/2018
0.35.0 8,503 1/17/2018
0.34.0 6,323 11/20/2017
0.33.0 3,027 11/16/2017
0.32.0 3,090 10/27/2017
0.31.0 4,091 10/4/2017
0.30.0 15,836 10/2/2017
0.29.0 2,367 9/17/2017
0.28.0 25,807 6/3/2017
0.27.0 6,328 4/24/2017
0.26.0 2,431 3/29/2017
0.25.0 1,549 3/24/2017
0.24.0 1,224 3/19/2017
0.23.0 1,392 3/9/2017
0.22.0 1,556 2/21/2017
0.21.0 1,254 2/19/2017
0.20.0 1,283 2/18/2017
0.19.0 1,288 2/13/2017
0.18.3 1,508 2/3/2017
0.18.2 1,204 2/2/2017
0.18.1 2,207 1/28/2017
0.18.0 11,432 1/5/2017
0.17.0 3,753 12/14/2016
0.16.0 2,934 12/7/2016
0.15.0 1,217 12/2/2016
0.14.0 1,228 11/30/2016
0.13.0 1,171 11/29/2016
0.12.0 1,190 11/26/2016
0.11.0 1,128 11/22/2016
0.10.0 1,372 11/14/2016
0.9.0 1,179 11/11/2016
0.8.0 1,194 11/10/2016
0.7.2 1,292 10/27/2016
0.7.1 1,111 10/27/2016
0.7.0 1,165 10/27/2016
0.6.0 1,183 10/25/2016
0.5.0 1,152 10/22/2016
0.4.0 1,154 10/20/2016
0.3.0 1,167 10/19/2016
0.2.0 1,168 10/17/2016
0.1.0 1,230 10/17/2016