Slack.NetStandard 2.16.3

.NET Core package that helps with Slack interactions

There is a newer prerelease version of this package available.
See the version list below for details.
Install-Package Slack.NetStandard -Version 2.16.3
dotnet add package Slack.NetStandard --version 2.16.3
<PackageReference Include="Slack.NetStandard" Version="2.16.3" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Slack.NetStandard --version 2.16.3
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Slack.NetStandard, 2.16.3"
#r directive can be used in F# Interactive, C# scripting and .NET Interactive. Copy this into the interactive tool or source code of the script to reference the package.
// Install Slack.NetStandard as a Cake Addin
#addin nuget:?package=Slack.NetStandard&version=2.16.3

// Install Slack.NetStandard as a Cake Tool
#tool nuget:?package=Slack.NetStandard&version=2.16.3
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

Slack.NetStandard

.NET Core NuGet package that helps with Slack interactions
Available at https://www.nuget.org/packages/Slack.NetStandard

Create OAuth URL

using Slack.NetStandard.Auth;

var builder = new OAuthV2Builder("clientId")
{
    State = "stateGoesHere", 
    BotScope = "channels:read"
};
var redirectUri = builder.BuildUri();

Get OAuth Access Token from Code

using Slack.NetStandard.Auth;

var token = await OAuthV2Builder.Exchange(code,clientId,clientSecret);

Verify Incoming Request is from Slack

using Slack.NetStandard;

var verifier = new RequestVerifier(signingSecret);
var verified = verifier.Verify(request.Headers[RequestVerifier.SignatureHeaderName], long.Parse(request.Headers[RequestVerifier.TimestampHeaderName]), request.Body);

Receive/Respond to a slash command payload

var command = new SlashCommand(payloadText);

var message = new InteractionMessage();
message.Blocks.Add(new Section{Text = new PlainText("Only title is required")});
message.Blocks.Add(new Divider());
message.Send(command.ResponseUrl);

await command.Respond(message);

// or - if it's not from a slash command, any response url can use
await command.Response(responseUrl);

Building & sending a modal

var view = new View
{
    Type = "modal",
    Title = "Create New Story",
    Close = "Cancel",
    Submit = "Submit",
    Blocks = new IMessageBlock[]
    {
       new Section{Text = new PlainText("Only title is required")}
    }
};

var client = new SlackWebApiClient(accessToken);
var response = await client.View.Open(triggerId,view);

Sending a new message to a channel

var request = new PostMessageRequest {Channel = "C123456"};
request.Blocks.Add(new Section{Text = new PlainText("Hi There!")});

var client = new SlackWebApiClient("token");
await client.Chat.Post(request);

Parse Events API Body

using Slack.NetStandard.EventsApi;
using Slack.NetStandard.EventsApi.CallbackEvents;

var eventObject = JsonConvert.DeserializeObject<Event>(input.Body);

if (eventObject is EventCallback callback)
{
    switch(callback.Event)
    {
        case AppHomeOpened appHome:
            break;
        case GroupClose groupClose:
            break;

    }
}

Parse incoming text for entities (channels, users, links etc.)

var entities = TextParser.FindEntities("<@W123456|Steven>");
if(entities.First() is UserMention mention)
{
    var userId = mention.UserId //W123456
    var label = mention.Label //Steven
}

Socket Mode - getting to your payload

if(msg.Contains("envelope_id")) //If there's no envelope ID it's a Hello or Disconnect object
{
   var env = JsonConvert.DeserializeObject<Envelope>(msg);
   switch(env.Payload) {
     case SlashCommand command:
       //logic here
       break;
     case EventCallback evt: 
       //logic here
       break;
     case InteractionPayload payload:
       //logic here
       break;
   }
   var ack = new Acknowledge{EnvelopeId=env.EnvelopeId} //All messages must be acknowledged within a few seconds
   Send(ack);
}

For a .NET 3.1 client that helps with a lot of the Socket Mode plumbing, the SocketSample app is now available at Slack.NetStandard.AsyncEnumerable

Slack.NetStandard

.NET Core NuGet package that helps with Slack interactions
Available at https://www.nuget.org/packages/Slack.NetStandard

Create OAuth URL

using Slack.NetStandard.Auth;

var builder = new OAuthV2Builder("clientId")
{
    State = "stateGoesHere", 
    BotScope = "channels:read"
};
var redirectUri = builder.BuildUri();

Get OAuth Access Token from Code

using Slack.NetStandard.Auth;

var token = await OAuthV2Builder.Exchange(code,clientId,clientSecret);

Verify Incoming Request is from Slack

using Slack.NetStandard;

var verifier = new RequestVerifier(signingSecret);
var verified = verifier.Verify(request.Headers[RequestVerifier.SignatureHeaderName], long.Parse(request.Headers[RequestVerifier.TimestampHeaderName]), request.Body);

Receive/Respond to a slash command payload

var command = new SlashCommand(payloadText);

var message = new InteractionMessage();
message.Blocks.Add(new Section{Text = new PlainText("Only title is required")});
message.Blocks.Add(new Divider());
message.Send(command.ResponseUrl);

await command.Respond(message);

// or - if it's not from a slash command, any response url can use
await command.Response(responseUrl);

Building & sending a modal

var view = new View
{
    Type = "modal",
    Title = "Create New Story",
    Close = "Cancel",
    Submit = "Submit",
    Blocks = new IMessageBlock[]
    {
       new Section{Text = new PlainText("Only title is required")}
    }
};

var client = new SlackWebApiClient(accessToken);
var response = await client.View.Open(triggerId,view);

Sending a new message to a channel

var request = new PostMessageRequest {Channel = "C123456"};
request.Blocks.Add(new Section{Text = new PlainText("Hi There!")});

var client = new SlackWebApiClient("token");
await client.Chat.Post(request);

Parse Events API Body

using Slack.NetStandard.EventsApi;
using Slack.NetStandard.EventsApi.CallbackEvents;

var eventObject = JsonConvert.DeserializeObject<Event>(input.Body);

if (eventObject is EventCallback callback)
{
    switch(callback.Event)
    {
        case AppHomeOpened appHome:
            break;
        case GroupClose groupClose:
            break;

    }
}

Parse incoming text for entities (channels, users, links etc.)

var entities = TextParser.FindEntities("<@W123456|Steven>");
if(entities.First() is UserMention mention)
{
    var userId = mention.UserId //W123456
    var label = mention.Label //Steven
}

Socket Mode - getting to your payload

if(msg.Contains("envelope_id")) //If there's no envelope ID it's a Hello or Disconnect object
{
   var env = JsonConvert.DeserializeObject<Envelope>(msg);
   switch(env.Payload) {
     case SlashCommand command:
       //logic here
       break;
     case EventCallback evt: 
       //logic here
       break;
     case InteractionPayload payload:
       //logic here
       break;
   }
   var ack = new Acknowledge{EnvelopeId=env.EnvelopeId} //All messages must be acknowledged within a few seconds
   Send(ack);
}

For a .NET 3.1 client that helps with a lot of the Socket Mode plumbing, the SocketSample app is now available at Slack.NetStandard.AsyncEnumerable

Release Notes

AsOption and AsOptionGroup added as IOption extensions

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Slack.NetStandard:

Package Downloads
Slack.NetStandard.Endpoint
Small library used to build single Slack endpoints - allowing simpler wiring of Slack apps by examining the full request and deserializing appropriately
Slack.NetStandard.AsyncEnumerable
Additional support for Slack.NetStandard apps running Socket Mode

GitHub repositories

This package is not used by any popular GitHub repositories.

Version History

Version Downloads Last updated
2.17.0-beta4 73 6/8/2021
2.17.0-beta3 157 5/30/2021
2.17.0-beta2 112 5/22/2021
2.17.0-beta1 54 5/8/2021
2.16.3 492 6/8/2021
2.16.2 333 5/30/2021
2.16.1 101 5/22/2021
2.16.0 329 5/8/2021
2.16.0-beta3 72 5/2/2021
2.16.0-beta2 46 4/28/2021
2.16.0-beta1 137 4/7/2021
2.15.2 103 5/2/2021
2.15.1 59 4/28/2021
2.15.0 278 4/7/2021
2.15.0-beta5 41 4/7/2021
2.15.0-beta3 1,172 3/21/2021
2.15.0-beta2 146 3/18/2021
2.15.0-beta1 59 3/17/2021
2.14.4 46 4/7/2021
2.14.2 833 3/21/2021
2.14.1 78 3/18/2021
2.14.0 94 3/17/2021
2.14.0-beta3 50 3/4/2021
2.14.0-beta2 55 3/2/2021
2.14.0-beta1 60 3/2/2021
2.13.2 203 3/4/2021
2.13.1 5,492 3/2/2021
2.13.0 136 3/2/2021
2.13.0-beta1 76 2/24/2021
2.12.0 178 2/24/2021
2.12.0-beta1 49 2/22/2021
2.11.0 550 2/22/2021
2.10.1 111 2/11/2021
2.10.0 419 1/28/2021
2.10.0-beta2 62 1/16/2021
2.10.0-beta1 62 1/15/2021
2.9.2 73 1/27/2021
2.9.1 93 1/16/2021
2.9.0 87 1/15/2021
2.9.0-beta8 95 1/11/2021
2.9.0-beta7 120 12/10/2020
2.9.0-beta6 112 11/30/2020
2.9.0-beta5 126 11/28/2020
2.9.0-beta4 133 11/26/2020
2.9.0-beta3 154 10/20/2020
2.9.0-beta2 104 10/20/2020
2.9.0-beta 125 10/20/2020
2.8.7 888 1/11/2021
2.8.6 878 12/10/2020
2.8.5 420 11/30/2020
2.8.4 203 11/28/2020
2.8.3 156 11/26/2020
2.8.2 904 10/20/2020
2.8.1 110 10/20/2020
2.8.0 125 10/20/2020
2.8.0-beta 198 10/17/2020
2.7.0 205 10/17/2020
2.7.0-beta2 109 10/17/2020
2.7.0-beta 154 10/14/2020
2.6.1 110 10/17/2020
2.6.0 161 10/14/2020
2.6.0-beta 221 10/8/2020
2.5.1 268 10/8/2020
2.5.0 223 10/8/2020
2.4.0 174 10/5/2020
2.3.0 469 9/17/2020
2.2.1 12,764 9/1/2020
2.2.0 139 8/28/2020
2.1.0 6,946 6/16/2020
2.0.0 320 5/29/2020
1.7.1 163 5/28/2020
1.7.0 240 5/21/2020
1.6.0 161 5/21/2020
1.5.5 195 5/17/2020
1.5.4 153 5/14/2020
1.5.3 187 5/11/2020
1.5.2 218 5/6/2020
1.5.1 216 5/4/2020
1.5.0 173 5/4/2020
1.4.2 176 5/4/2020
1.4.1 177 5/4/2020
1.4.0 198 5/4/2020
1.3.2 194 5/4/2020
1.3.1 226 4/30/2020
1.3.0 164 4/29/2020
1.2.1 163 4/29/2020
1.2.0 167 4/29/2020
1.1.0 161 4/28/2020
1.0.2 164 4/28/2020
1.0.1 179 4/27/2020
1.0.0 236 4/21/2020
0.5.0 198 4/13/2020
0.4.1-alpha8 205 4/12/2020
0.4.1-alpha7 203 4/12/2020
0.4.1-alpha6 207 4/12/2020
0.4.1-alpha4 221 4/12/2020
0.4.1-alpha3 227 4/12/2020
0.4.1-alpha2 170 4/12/2020
0.4.1-alpha1 177 4/11/2020
0.4.0-pre 330 4/5/2020
0.3.2 242 1/3/2020
0.3.1 216 1/3/2020
0.3.0 254 1/2/2020
0.2.2 243 12/23/2019
0.2.1 201 12/23/2019
0.2.1-pre 220 12/19/2019
0.2.0 207 12/20/2019
0.2.0-pre 223 12/18/2019
0.1.1-pre 193 12/17/2019
0.1.0 205 12/19/2019
0.1.0-pre 203 12/17/2019