Skip to content

Commit bcc1816

Browse files
authored
Add Trigger requests response support (#43)
1 parent b647637 commit bcc1816

File tree

19 files changed

+127
-48
lines changed

19 files changed

+127
-48
lines changed

.github/workflows/wf-samples-build.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jobs:
1616
env:
1717
APP_NAME: ${{ inputs.appName }}
1818
PUBLISH_DIR: ${{ github.workspace }}/publish
19+
SOLUTION_FILE: InvvardDev.Ifttt.Samples.sln
1920

2021
steps:
2122
- name: Checkout Samples directory
@@ -32,8 +33,8 @@ jobs:
3233

3334
- name: Build & Publish ${{ env.APP_NAME }}
3435
run: |
35-
dotnet restore
36-
dotnet build --configuration Release
36+
dotnet restore ${{ env.SOLUTION_FILE }}
37+
dotnet build ${{ env.SOLUTION_FILE }} --configuration Release --no-restore
3738
dotnet publish --no-build --property:PublishDir=${{ env.PUBLISH_DIR }}/
3839
working-directory: samples
3940

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvvardDev.Ifttt.Samples.Trigger", "InvvardDev.Ifttt.Samples.Trigger\InvvardDev.Ifttt.Samples.Trigger.ProjRef.csproj", "{8A6E23C3-C46C-4566-AEC6-B7B8BE149F8F}"
4+
EndProject
5+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "package_src", "package_src", "{E46C4FED-BC2D-43E1-93CE-6D46B4EDE526}"
6+
EndProject
7+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvvardDev.Ifttt", "..\src\InvvardDev.Ifttt.csproj", "{BE9A9B91-0261-4385-B978-31D8424EA249}"
8+
EndProject
9+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvvardDev.Ifttt.Tests", "..\tests\InvvardDev.Ifttt.Tests\InvvardDev.Ifttt.Tests.csproj", "{A088DAE7-B95E-49D7-ABB3-C2F306CDD4BC}"
10+
EndProject
11+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvvardDev.Ifttt.TestFactories", "..\tests\InvvardDev.Ifttt.TestFactories\InvvardDev.Ifttt.TestFactories.csproj", "{B16B04F2-764F-40A7-A778-8E4819EC8963}"
12+
EndProject
13+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{EBA9CC63-D444-4BB0-9374-F59836B1E113}"
14+
EndProject
15+
Global
16+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
17+
Debug|Any CPU = Debug|Any CPU
18+
Release|Any CPU = Release|Any CPU
19+
EndGlobalSection
20+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
21+
{8A6E23C3-C46C-4566-AEC6-B7B8BE149F8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22+
{8A6E23C3-C46C-4566-AEC6-B7B8BE149F8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
23+
{8A6E23C3-C46C-4566-AEC6-B7B8BE149F8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
24+
{8A6E23C3-C46C-4566-AEC6-B7B8BE149F8F}.Release|Any CPU.Build.0 = Release|Any CPU
25+
{BE9A9B91-0261-4385-B978-31D8424EA249}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26+
{BE9A9B91-0261-4385-B978-31D8424EA249}.Debug|Any CPU.Build.0 = Debug|Any CPU
27+
{BE9A9B91-0261-4385-B978-31D8424EA249}.Release|Any CPU.ActiveCfg = Release|Any CPU
28+
{BE9A9B91-0261-4385-B978-31D8424EA249}.Release|Any CPU.Build.0 = Release|Any CPU
29+
{A088DAE7-B95E-49D7-ABB3-C2F306CDD4BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30+
{A088DAE7-B95E-49D7-ABB3-C2F306CDD4BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
31+
{A088DAE7-B95E-49D7-ABB3-C2F306CDD4BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
32+
{A088DAE7-B95E-49D7-ABB3-C2F306CDD4BC}.Release|Any CPU.Build.0 = Release|Any CPU
33+
{B16B04F2-764F-40A7-A778-8E4819EC8963}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34+
{B16B04F2-764F-40A7-A778-8E4819EC8963}.Debug|Any CPU.Build.0 = Debug|Any CPU
35+
{B16B04F2-764F-40A7-A778-8E4819EC8963}.Release|Any CPU.ActiveCfg = Release|Any CPU
36+
{B16B04F2-764F-40A7-A778-8E4819EC8963}.Release|Any CPU.Build.0 = Release|Any CPU
37+
EndGlobalSection
38+
GlobalSection(NestedProjects) = preSolution
39+
{EBA9CC63-D444-4BB0-9374-F59836B1E113} = {E46C4FED-BC2D-43E1-93CE-6D46B4EDE526}
40+
{BE9A9B91-0261-4385-B978-31D8424EA249} = {E46C4FED-BC2D-43E1-93CE-6D46B4EDE526}
41+
{B16B04F2-764F-40A7-A778-8E4819EC8963} = {EBA9CC63-D444-4BB0-9374-F59836B1E113}
42+
{A088DAE7-B95E-49D7-ABB3-C2F306CDD4BC} = {EBA9CC63-D444-4BB0-9374-F59836B1E113}
43+
EndGlobalSection
44+
EndGlobal
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<InvariantGlobalization>true</InvariantGlobalization>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.22.0" />
10+
<PackageReference Include="Microsoft.OpenApi" Version="1.6.13" />
11+
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
12+
</ItemGroup>
13+
14+
<ItemGroup>
15+
<Content Update="appsettings.Development.json">
16+
<DependentUpon>appsettings.json</DependentUpon>
17+
</Content>
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<ProjectReference Include="..\..\src\InvvardDev.Ifttt.csproj" />
22+
</ItemGroup>
23+
24+
</Project>

samples/InvvardDev.Ifttt.Samples.Trigger/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
.UseSwaggerUI();
4141

4242
app.ConfigureIftttToolkit()
43-
.UseServiceKeyAuthentication()
43+
.UseServiceKeyAuthentication(clientIftttOptions.BypassServiceKey)
4444
.ConfigureTriggers();
4545

4646
await app.RunAsync();

src/Controllers/TriggerController.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,16 @@ public class TriggerController([FromKeyedServices(ProcessorKind.Trigger)] IProce
1818
[ProducesResponseType(StatusCodes.Status200OK)]
1919
[ProducesResponseType(StatusCodes.Status404NotFound)]
2020
[Consumes("application/json")]
21+
[Produces("application/json")]
2122
public async Task<IActionResult> ExecuteTrigger(string triggerSlug, TriggerRequest triggerRequest)
2223
{
2324
if (await triggerService.GetProcessorInstance<ITrigger>(triggerSlug) is not { } trigger)
2425
{
2526
return NotFound();
2627
}
2728

28-
await trigger.ExecuteAsync(triggerRequest);
29+
var result = await trigger.ExecuteAsync(triggerRequest);
2930

30-
return Ok();
31+
return Ok(result.Serialize());
3132
}
3233
}

src/Hosting/Extensions/CoreHostingExtensions.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,18 @@ public static IIftttAppBuilder ConfigureIftttToolkit(this IApplicationBuilder ap
8888
/// Extension method to use the IFTTT service key authentication middleware.
8989
/// </summary>
9090
/// <param name="appBuilder">The <see cref="IIftttAppBuilder"/> instance.</param>
91+
/// <param name="bypassServiceKey">
92+
/// If <c>True</c>, middleware is not used<br/>
93+
/// (SHOULD ONLY BE USED IN DEV ENVIRONMENT)
94+
/// </param>
9195
/// <returns>The <see cref="IIftttAppBuilder"/> instance.</returns>
92-
public static IIftttAppBuilder UseServiceKeyAuthentication(this IIftttAppBuilder appBuilder)
96+
public static IIftttAppBuilder UseServiceKeyAuthentication(this IIftttAppBuilder appBuilder, bool bypassServiceKey)
9397
{
98+
if (bypassServiceKey)
99+
{
100+
return appBuilder;
101+
}
102+
94103
ArgumentNullException.ThrowIfNull(appBuilder);
95104

96105
appBuilder.App.UseWhen(context => context.Request.Path.StartsWithSegments(IftttConstants.BaseApiPath),

src/InvvardDev.Ifttt.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<PackageId>$(AssemblyName)</PackageId>
2727

2828
<AssemblyName>InvvardDev.Ifttt</AssemblyName>
29-
<VersionPrefix>0.1.12</VersionPrefix>
29+
<VersionPrefix>0.1.13</VersionPrefix>
3030
<PackageVersion>$(Version)</PackageVersion>
3131

3232
<Title>IFTTT.NET package</Title>

src/Toolkit/Contracts/ITrigger.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ public interface ITrigger
1212
/// </summary>
1313
/// <param name="triggerRequest">The trigger request that contains the trigger fields data.</param>
1414
/// <param name="cancellationToken"></param>
15-
Task ExecuteAsync(TriggerRequest triggerRequest, CancellationToken cancellationToken = default);
16-
}
15+
/// <returns>The Trigger response.</returns>
16+
Task<TriggerResponse> ExecuteAsync(TriggerRequest triggerRequest, CancellationToken cancellationToken = default);
17+
}

src/Toolkit/Extensions/TriggerFieldsMapper.cs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,24 @@ public static class TriggerFieldsMapper
99
/// <summary>
1010
/// Extension method to map a dictionary to a trigger fields class.
1111
/// </summary>
12-
/// <remarks>Any unrecognized trigger field slug is stored in the <see cref="TriggerFieldsBase.Metadata"/> dictionary.</remarks>
12+
/// <remarks>Any unmatched trigger field slug is ignored.</remarks>
1313
/// <param name="dictionary">The dictionary of data field slugs and its related data.</param>
14-
/// <typeparam name="T">The <see cref="TriggerFieldsBase"/> derived type to map to.</typeparam>
14+
/// <typeparam name="T">The targeted <typeparamref name="T"/> type to map to.</typeparam>
1515
/// <returns>A new <typeparamref name="T"/> instance.</returns>
1616
public static T To<T>(this Dictionary<string, string> dictionary)
17-
where T : TriggerFieldsBase, new()
17+
where T : class, new()
1818
{
1919
var triggerFields = new T();
2020

2121
foreach (var (key, value) in dictionary)
2222
{
23-
if (triggerFields.GetType()
24-
.GetProperties()
25-
.SingleOrDefault(p => p.GetCustomAttribute<DataFieldAttribute>()?.Slug == key)
26-
is { CanWrite: true } property
27-
&& TypeDescriptor.GetConverter(property.PropertyType).ConvertFrom(dictionary[key]) is { } result)
23+
if (triggerFields.GetType().GetProperties().SingleOrDefault(p => p.GetCustomAttribute<DataFieldAttribute>()?.Slug == key) is { CanWrite: true } property
24+
&& TypeDescriptor.GetConverter(property.PropertyType).ConvertFrom(value) is { } result)
2825
{
2926
property.SetValue(triggerFields, result);
3027
}
31-
else
32-
{
33-
triggerFields.Metadata.Add(key, value);
34-
}
3528
}
3629

3730
return triggerFields;
3831
}
39-
}
32+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.Text.Json;
2+
3+
namespace InvvardDev.Ifttt.Toolkit;
4+
5+
public abstract record BaseResponse
6+
{
7+
public virtual string Serialize() => Serialize(jsonSerializerOptions);
8+
9+
private readonly JsonSerializerOptions jsonSerializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower };
10+
11+
private string Serialize(JsonSerializerOptions options)
12+
=> JsonSerializer.Serialize(this, GetType(), options);
13+
}

0 commit comments

Comments
 (0)