Skip to content

Instantly share code, notes, and snippets.

@danielskovli
Created November 22, 2024 08:25
Show Gist options
  • Select an option

  • Save danielskovli/892478b277720fbf57c27374946f6a41 to your computer and use it in GitHub Desktop.

Select an option

Save danielskovli/892478b277720fbf57c27374946f6a41 to your computer and use it in GitHub Desktop.
Using CorrespondenceClient in an Altinn 3 app
// TT02 + Test environments for Altinn Auth, Correspondence, and Maskinporten
// Base64 decode the `jwkBase64` to see the underlying format of the jwk credentials,
// if you want to provide this raw value instead of the encoded version, use key `jwk`
// If you need to use another name than `MaskinportenSettings` for the Maskinporten configuration,
// that can be done, but requires one extra line of code in your Program.cs implementation.
{
"PlatformSettings": {
"ApiCorrespondenceEndpoint": "https://platform.tt02.altinn.no/correspondence/api/v1/",
"ApiAuthenticationEndpoint": "https://platform.tt02.altinn.no/authentication/api/v1/"
},
"MaskinportenSettings": {
"authority": "https://test.maskinporten.no/",
"clientId": "the-client-id-guid",
"jwkBase64": "ewogICAgICAicCI6ICItU09GNmp3V0N3b19nSlByTnJhcVNkNnZRckFzRmxZd1VScHQ0NC1BNlRXUnBoaUo4b3czSTNDWGxxUG1LeG5VWDVDcnd6SF8yeldTNGtaaU9zQTMtajhiUE9hUjZ2a3pRSG14YmFkWmFmZjBUckdJajNQUlhxcVdMRHdsZjNfNklDV2gzOFhodXNBeDVZRE0tRm8zZzRLVWVHM2NxMUFvTkJ4NHV6Sy1IRHMiLAogICAgICAia3R5IjogIlJTQSIsCiAgICAgICJxIjogIndwWUlpOVZJLUJaRk9aYUNaUmVhYm4xWElQbW8tbEJIendnc1RCdHVfeUJma1FQeGI1Q1ZnZFFnaVQ4dTR3Tkl4NC0zb2ROdXhsWGZING1Hc25xOWFRaFlRNFEyc2NPUHc5V2dNM1dBNE1GMXNQQXgzUGJLRkItU01RZmZ4aXk2cVdJSmRQSUJ4OVdFdnlseW9XbEhDcGZsUWplT3U2dk43WExsZ3c5T2JhVSIsCiAgICAgICJkIjogIks3Y3pqRktyWUJfRjJYRWdoQ1RQY2JTbzZZdExxelFwTlZleF9HZUhpTmprWmNpcEVaZ3g4SFhYLXpNSi01ZWVjaTZhY1ZjSzhhZzVhQy01Mk84LTU5aEU3SEE2M0FoRzJkWFdmamdQTXhaVE9MbnBheWtZbzNWa0NGNF9FekpLYmw0d2ludnRuTjBPc2dXaVZiTDFNZlBjWEdqbHNTUFBIUlAyaThDajRqX21OM2JVcy1FbVM5UzktSXlia1luYV9oNUMxMEluXy1tWHpsQ2dCNU9FTXFzd2tNUWRZVTBWbHVuWHM3YXlPT0h2WWpQMWFpYml0MEpyay1iWVFHSy1mUVFFVWNZRkFSN1ZLMkxIaUJwU0NvbzBiSjlCQ1BZb196bTVNVnVId21xbzNtdml1Vy1lMnVhbW5xVHpZUEVWRE1lMGZBSkZtcVBGcGVwTzVfcXE2USIsCiAgICAgICJlIjogIkFRQUIiLAogICAgICAidXNlIjogInNpZyIsCiAgICAgICJraWQiOiAiYXNkZjEyMzQiLAogICAgICAicWkiOiAicXpFUUdXOHBPVUgtR2pCaFUwVXNhWWtEM2dWTVJvTF9CbGlRckp4ZTAwY29YeUtIZGVEX2M1bDFDNFFJZzRJSjZPMnFZZ2wyamRnWVNmVHA0S2NDNk1Obm8tSVFiSnlPRDU2Qmo4eVJUUjA5TkZvTGhDUjNhY0xmMkhwTXNKNUlqbTdBUHFPVWlCeW9hVkExRlR4bzYtZGNfZ1NiQjh1ZDI2bFlFRHdsYWMwIiwKICAgICAgImRwIjogInRnTU14N2FFQ0NiQmctY005Vmo0Q2FXbGR0d01LWGxvTFNoWTFlSTJOS3BOTVFKR2JhdWdjTVRHQ21qTk1fblgzTVZ0cHRvMWFPbTMySlhCRjlqc1RHZWtONWJmVGNJbmZsZ3Bsc21uR2pMckNqN0xYTG9wWUxiUnBabF9iNm1JaThuU2ZCQXVQR2hEUzc4UWZfUXhFR1Bxb2h6cEZVTW5UQUxzOVI0Nkk1YyIsCiAgICAgICJhbGciOiAiUlMyNTYiLAogICAgICAiZHEiOiAibE40cF9ha1lZVXpRZTBWdHp4LW1zNTlLLUZ4bzdkQmJqOFhGOWhnSzdENzlQam5SRGJTRTNVWEgtcGlQSzNpSXhyeHFGZkZuVDJfRS15REJIMjBOMmZ4YllwUVZNQnpZc1UtUGQ2OFBBV1Nnd05TU29XVmhwdEdjaTh4bFlfMDJkWDRlbEF6T1ZlOUIxdXBEMjc5cWJXMVdKVG5TQmp4am1LVU5lQjVPdDAwIiwKICAgICAgIm4iOiAidlY3dW5TclNnekV3ZHo0dk8wTnNmWDB0R1NwT2RITE16aDFseUVtU2RYbExmeVYtcUxtbW9qUFI3S2pUU2NDbDI1SFI4SThvWG1mcDhSZ19vbnA0LUlZWW5ZV0RTNngxVlViOVlOQ3lFRTNQQTUtVjlOYzd5ckxxWXpyMTlOSkJmdmhJVEd5QUFVTjFCeW5JeXJ5NFFMbHRYYTRKSTFiLTh2QXNJQ0xyU1dQZDdibWxrOWo3bU1jV3JiWlNIZHNTMGNpVFgzYTc2UXdMb0F2SW54RlhCU0ludXF3ZVhnVjNCZDFQaS1DZGpCR0lVdXVyeVkybEwybmRnVHZUY2tZUTBYeEtGR3lCdDNaMEhJMzRBRFBrVEZneWFMX1F4NFpIZ3d6ZjRhTHBXaHF3OGVWanpPMXlucjJ3OUd4b2dSN1pWUjY3VFI3eUxSS3VrMWdIdFlkUkJ3IgogICAgfQ=="
}
}
using System;
using System.Threading.Tasks;
using Altinn.App.Core.Features.Correspondence;
using Altinn.App.Core.Features.Correspondence.Builder;
using Altinn.App.Core.Features.Correspondence.Models;
using Altinn.App.Core.Internal.Auth;
using Altinn.App.Core.Models;
namespace Altinn.App;
internal sealed class CorrespondenceClientDemo(
ICorrespondenceClient correspondenceClient,
IUserTokenProvider userTokenProvider
)
{
public async Task<SendCorrespondenceResponse> SendCorrespondenceWithMaskinporten()
{
CorrespondenceRequest request = CorrespondenceRequestFactory();
CorrespondenceAuthorisation authorisation = CorrespondenceAuthorisation.Maskinporten;
return await correspondenceClient.Send(
new SendCorrespondencePayload(request, authorisation)
);
}
public async Task<SendCorrespondenceResponse> SendCorrespondenceWithUserToken()
{
CorrespondenceRequest request = CorrespondenceRequestFactory();
Func<Task<JwtToken>> authorisation = async () =>
{
string cookieToken = userTokenProvider.GetUserToken();
JwtToken token = JwtToken.Parse(cookieToken);
return await Task.FromResult(token);
};
return await correspondenceClient.Send(
new SendCorrespondencePayload(request, authorisation)
);
}
public async Task<GetCorrespondenceStatusResponse> GetCorrespondenceStatus(
Guid correspondenceId
)
{
return await correspondenceClient.GetStatus(
new GetCorrespondenceStatusPayload(
correspondenceId,
CorrespondenceAuthorisation.Maskinporten
)
);
}
private CorrespondenceRequest CorrespondenceRequestFactory()
{
return CorrespondenceRequestBuilder
.Create()
.WithResourceId("a valid resource registry identifier")
.WithSender("sender's organisation number")
.WithSendersReference("sender's arbitrary reference for the correspondence")
.WithRecipients(
["receiving organisation number", "and maybe a person's national identity number"]
)
.WithAllowSystemDeleteAfter(DateTime.Now.AddYears(1))
.WithContent(
CorrespondenceContentBuilder
.Create()
.WithLanguage("en")
.WithTitle("Hello from .NET πŸ‘‹πŸ»")
.WithSummary("The message summary")
.WithBody("The message body with markdown support: **bold** *italic* `code`")
)
.WithNotification(
CorrespondenceNotificationBuilder
.Create()
.WithNotificationTemplate(CorrespondenceNotificationTemplate.CustomMessage)
.WithEmailSubject("New Altinn message")
.WithEmailBody(
"You have a new message in your Altinn inbox, log in to see what's new."
)
.WithSmsBody("Got πŸ“¨ in Altinn")
.WithNotificationChannel(CorrespondenceNotificationChannel.EmailPreferred)
)
.WithAttachment(
CorrespondenceAttachmentBuilder
.Create()
.WithFilename("attachment.txt")
.WithName("The attachment πŸ“Ž")
.WithSendersReference("sender's arbitrary reference for the attachment")
.WithDataType("text/plain")
.WithData("This is the attachment content"u8.ToArray())
)
.Build();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment