Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Slackbot.Net.Endpoints.Models.Events;

namespace Slackbot.Net.Endpoints.Abstractions;

public interface IHandleAssistantThreadContextChanged
{
Task<EventHandledResponse> Handle(EventMetaData eventMetadata, AssistantThreadContextChangedEvent slackEvent);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Slackbot.Net.Endpoints.Models.Events;

namespace Slackbot.Net.Endpoints.Abstractions;

public interface IHandleAssistantThreadStarted
{
Task<EventHandledResponse> Handle(EventMetaData eventMetadata, AssistantThreadStartedEvent slackEvent);
}
2 changes: 2 additions & 0 deletions source/src/Slackbot.Net.Endpoints/EventTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ public static class EventTypes
public const string EmojiChanged = "emoji_changed";
public const string Message = "message";
public const string ReactionAdded = "reaction_added";
public const string AssistantThreadStarted = "assistant_thread_started";
public const string AssistantThreadContextChanged = "assistant_thread_context_changed";
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public static IApplicationBuilder UseSlackbot(
app.MapWhen(EmojiChangedEvents.ShouldRun, b => b.UseMiddleware<EmojiChangedEvents>());
app.MapWhen(MessageEvents.ShouldRun, b => b.UseMiddleware<MessageEvents>());
app.MapWhen(ReactionAddedEvents.ShouldRun, b => b.UseMiddleware<ReactionAddedEvents>());
app.MapWhen(AssistantThreadStartedEvents.ShouldRun, b => b.UseMiddleware<AssistantThreadStartedEvents>());
app.MapWhen(AssistantThreadContextChangedEvents.ShouldRun, b => b.UseMiddleware<AssistantThreadContextChangedEvents>());

return app;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ public ISlackbotHandlersBuilder AddInteractiveBlockActionsHandler<T>()
public ISlackbotHandlersBuilder AddEmojiChangedHandler<T>() where T : class, IHandleEmojiChanged;
public ISlackbotHandlersBuilder AddMessageHandler<T>() where T : class, IHandleMessage;
public ISlackbotHandlersBuilder AddReactionAddedHandler<T>() where T : class, IHandleReactionAdded;
public ISlackbotHandlersBuilder AddAssistantThreadStartedHandler<T>() where T : class, IHandleAssistantThreadStarted;
public ISlackbotHandlersBuilder AddAssistantThreadContextChangedHandler<T>() where T : class, IHandleAssistantThreadContextChanged;
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,18 @@ public ISlackbotHandlersBuilder AddReactionAddedHandler<T>() where T : class, IH
services.AddSingleton<IHandleReactionAdded, T>();
return this;
}

public ISlackbotHandlersBuilder AddAssistantThreadStartedHandler<T>()
where T : class, IHandleAssistantThreadStarted
{
services.AddSingleton<IHandleAssistantThreadStarted, T>();
return this;
}

public ISlackbotHandlersBuilder AddAssistantThreadContextChangedHandler<T>()
where T : class, IHandleAssistantThreadContextChanged
{
services.AddSingleton<IHandleAssistantThreadContextChanged, T>();
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Slackbot.Net.Endpoints.Abstractions;
using Slackbot.Net.Endpoints.Models.Events;

namespace Slackbot.Net.Endpoints.Middlewares;

public class AssistantThreadContextChangedEvents(
RequestDelegate next,
ILogger<AssistantThreadContextChangedEvents> logger,
IEnumerable<IHandleAssistantThreadContextChanged> responseHandlers
)
{
public async Task Invoke(HttpContext context)
{
var assistantEvent = (AssistantThreadContextChangedEvent)context.Items[HttpItemKeys.SlackEventKey];
var metadata = (EventMetaData)context.Items[HttpItemKeys.EventMetadataKey];

foreach (var handler in responseHandlers)
{
try
{
logger.LogInformation("Handling using {HandlerType}", handler.GetType());
var response = await handler.Handle(metadata, assistantEvent);
logger.LogInformation("Handler response: {Response}", response.Response);
}
catch (Exception e)
{
logger.LogError(e, e.Message);
}
}

context.Response.StatusCode = 200;
}

public static bool ShouldRun(HttpContext ctx)
{
return ctx.Items.ContainsKey(HttpItemKeys.EventTypeKey)
&& ctx.Items[HttpItemKeys.EventTypeKey].ToString() == EventTypes.AssistantThreadContextChanged;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Slackbot.Net.Endpoints.Abstractions;
using Slackbot.Net.Endpoints.Models.Events;

namespace Slackbot.Net.Endpoints.Middlewares;

public class AssistantThreadStartedEvents(
RequestDelegate next,
ILogger<AssistantThreadStartedEvents> logger,
IEnumerable<IHandleAssistantThreadStarted> responseHandlers
)
{
public async Task Invoke(HttpContext context)
{
var assistantEvent = (AssistantThreadStartedEvent)context.Items[HttpItemKeys.SlackEventKey];
var metadata = (EventMetaData)context.Items[HttpItemKeys.EventMetadataKey];

foreach (var handler in responseHandlers)
{
try
{
logger.LogInformation("Handling using {HandlerType}", handler.GetType());
var response = await handler.Handle(metadata, assistantEvent);
logger.LogInformation("Handler response: {Response}", response.Response);
}
catch (Exception e)
{
logger.LogError(e, e.Message);
}
}

context.Response.StatusCode = 200;
}

public static bool ShouldRun(HttpContext ctx)
{
return ctx.Items.ContainsKey(HttpItemKeys.EventTypeKey)
&& ctx.Items[HttpItemKeys.EventTypeKey].ToString() == EventTypes.AssistantThreadStarted;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ private static SlackEvent ToEventType(JsonElement eventJson, string raw)
return JsonSerializer.Deserialize<MessageEvent>(json, WebOptions);
case EventTypes.ReactionAdded:
return JsonSerializer.Deserialize<ReactionAddedEvent>(json, WebOptions);
case EventTypes.AssistantThreadStarted:
return JsonSerializer.Deserialize<AssistantThreadStartedEvent>(json, WebOptions);
case EventTypes.AssistantThreadContextChanged:
return JsonSerializer.Deserialize<AssistantThreadContextChangedEvent>(json, WebOptions);
default:
var unknownSlackEvent = JsonSerializer.Deserialize<UnknownSlackEvent>(json, WebOptions);
unknownSlackEvent.RawJson = raw;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Slackbot.Net.Endpoints.Models.Events;

public class AssistantThreadContextChangedEvent : SlackEvent
{
public AssistantThread Assistant_Thread { get; set; }
public string Event_Ts { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Slackbot.Net.Endpoints.Models.Events;

public class AssistantThreadStartedEvent : SlackEvent
{
public AssistantThread Assistant_Thread { get; set; }
public string Event_Ts { get; set; }
}

public class AssistantThread
{
public string User_Id { get; set; }
public string Channel_Id { get; set; }
public string Thread_Ts { get; set; }
public AssistantThreadContext Context { get; set; }
}

public class AssistantThreadContext
{
public string Channel_Id { get; set; }
public string Team_Id { get; set; }
public string Enterprise_Id { get; set; }
}
24 changes: 24 additions & 0 deletions source/src/Slackbot.Net.SlackClients.Http/ISlackClient.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using Slackbot.Net.SlackClients.Http.Models.Requests.AssistantThreadsSetStatus;
using Slackbot.Net.SlackClients.Http.Models.Requests.AssistantThreadsSetSuggestedPrompts;
using Slackbot.Net.SlackClients.Http.Models.Requests.AssistantThreadsSetTitle;
using Slackbot.Net.SlackClients.Http.Models.Requests.ChatPostEphemeral;
using Slackbot.Net.SlackClients.Http.Models.Requests.ChatPostMessage;
using Slackbot.Net.SlackClients.Http.Models.Requests.ChatUpdate;
Expand Down Expand Up @@ -127,4 +130,25 @@ public interface ISlackClient
Task<FileUploadResponse> FilesUpload(FileUploadRequest fileupload);

Task<FileUploadResponse> FilesUpload(FileUploadMultiPartRequest req);

/// <summary>
/// Scopes required: `assistant:write`
/// Sets the status of the assistant (e.g. "is thinking...") shown in the assistant pane.
/// </summary>
/// <remarks>https://api.slack.com/methods/assistant.threads.setStatus</remarks>
Task<Response> AssistantThreadsSetStatus(AssistantThreadsSetStatusRequest request);

/// <summary>
/// Scopes required: `assistant:write`
/// Sets the title of the assistant thread, shown in the History/Chat tabs.
/// </summary>
/// <remarks>https://api.slack.com/methods/assistant.threads.setTitle</remarks>
Task<Response> AssistantThreadsSetTitle(AssistantThreadsSetTitleRequest request);

/// <summary>
/// Scopes required: `assistant:write`
/// Sets suggested prompts for the assistant thread.
/// </summary>
/// <remarks>https://api.slack.com/methods/assistant.threads.setSuggestedPrompts</remarks>
Task<Response> AssistantThreadsSetSuggestedPrompts(AssistantThreadsSetSuggestedPromptsRequest request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Slackbot.Net.SlackClients.Http.Models.Requests.AssistantThreadsSetStatus;

public class AssistantThreadsSetStatusRequest
{
public string Channel_Id { get; set; }
public string Thread_Ts { get; set; }
public string Status { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Slackbot.Net.SlackClients.Http.Models.Requests.AssistantThreadsSetSuggestedPrompts;

public class AssistantThreadsSetSuggestedPromptsRequest
{
public string Channel_Id { get; set; }
public string Thread_Ts { get; set; }
public AssistantThreadPrompt[] Prompts { get; set; }
public string Title { get; set; }
}

public class AssistantThreadPrompt
{
public string Title { get; set; }
public string Message { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Slackbot.Net.SlackClients.Http.Models.Requests.AssistantThreadsSetTitle;

public class AssistantThreadsSetTitleRequest
{
public string Channel_Id { get; set; }
public string Thread_Ts { get; set; }
public string Title { get; set; }
}
19 changes: 19 additions & 0 deletions source/src/Slackbot.Net.SlackClients.Http/SlackClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using Microsoft.Extensions.Logging;
using Slackbot.Net.SlackClients.Http.Extensions;
using Slackbot.Net.SlackClients.Http.Models.Requests.AssistantThreadsSetStatus;
using Slackbot.Net.SlackClients.Http.Models.Requests.AssistantThreadsSetSuggestedPrompts;
using Slackbot.Net.SlackClients.Http.Models.Requests.AssistantThreadsSetTitle;
using Slackbot.Net.SlackClients.Http.Models.Requests.ChatPostEphemeral;
using Slackbot.Net.SlackClients.Http.Models.Requests.ChatPostMessage;
using Slackbot.Net.SlackClients.Http.Models.Requests.ChatUpdate;
Expand Down Expand Up @@ -228,5 +231,21 @@ public async Task<FileUploadResponse> FilesUpload(FileUploadMultiPartRequest req
return await _client.PostParametersAsMultiPartFormData<FileUploadResponse>(parameters, req.File, "files.upload", s => _logger.LogTrace(s));
}

/// <inheritdoc/>
public async Task<Response> AssistantThreadsSetStatus(AssistantThreadsSetStatusRequest request)
{
return await _client.PostJson<Response>(request, "assistant.threads.setStatus", s => _logger.LogTrace(s));
}

/// <inheritdoc/>
public async Task<Response> AssistantThreadsSetTitle(AssistantThreadsSetTitleRequest request)
{
return await _client.PostJson<Response>(request, "assistant.threads.setTitle", s => _logger.LogTrace(s));
}

/// <inheritdoc/>
public async Task<Response> AssistantThreadsSetSuggestedPrompts(AssistantThreadsSetSuggestedPromptsRequest request)
{
return await _client.PostJson<Response>(request, "assistant.threads.setSuggestedPrompts", s => _logger.LogTrace(s));
}
}
Loading