// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.Text.Json.Serialization; using Microsoft.Teams.Apps.Schema; namespace Microsoft.Teams.Apps.Handlers.TaskModules; /// /// Task module response types. /// public static class TaskModuleResponseTypes { /// /// Continue type - displays a card or URL in the task module. /// public const string Continue = "continue"; /// /// Message type - displays a plain text message. /// public const string Message = "message"; } /// /// Task module size constants. /// public static class TaskModuleSizes { /// /// Small size. /// public const string Small = "small"; /// /// Medium size. /// public const string Medium = "medium"; /// /// Large size. /// public const string Large = "large"; } /// /// Task module response wrapper. /// public class TaskModuleResponse { /// /// The task module result. /// [JsonPropertyName("task")] public Response? Task { get; set; } /// /// Creates a new builder for TaskModuleResponse. /// public static TaskModuleResponseBuilder CreateBuilder() { return new TaskModuleResponseBuilder(); } } /// /// Builder for TaskModuleResponse. /// public class TaskModuleResponseBuilder { private string? _type; private string? _title; private TeamsAttachment? _card; private object _height = TaskModuleSizes.Small; private object _width = TaskModuleSizes.Small; private string? _message; /// /// Sets the type of the response. Use constants. /// public TaskModuleResponseBuilder WithType(string type) { _type = type; return this; } /// /// Sets the title of the task module. /// public TaskModuleResponseBuilder WithTitle(string title) { _title = title; return this; } /// /// Sets the card content for continue type. /// public TaskModuleResponseBuilder WithCard(TeamsAttachment card) { _card = card; return this; } /// /// Sets the height. Can be a number (pixels) or use constants. /// public TaskModuleResponseBuilder WithHeight(object height) { _height = height; return this; } /// /// Sets the width. Can be a number (pixels) or use constants. /// public TaskModuleResponseBuilder WithWidth(object width) { _width = width; return this; } /// /// Sets the message for message type. /// public TaskModuleResponseBuilder WithMessage(string message) { _message = message; return this; } /// /// Builds the TaskModuleResponse. /// internal TaskModuleResponse Validate() { if (string.IsNullOrEmpty(_type)) { throw new InvalidOperationException("Type must be set. Use WithType() to specify TaskModuleResponseTypes.Continue or TaskModuleResponseTypes.Message."); } object? value = _type switch { TaskModuleResponseTypes.Continue => ValidateContinueType(), TaskModuleResponseTypes.Message => ValidateMessageType(), _ => throw new InvalidOperationException($"Unknown task module response type: {_type}") }; return new TaskModuleResponse { Task = new Response { Type = _type, Value = value } }; } private object ValidateContinueType() { if (_card == null) { throw new InvalidOperationException("Card must be set for Continue type. Use WithCard()."); } if (!string.IsNullOrEmpty(_message)) { throw new InvalidOperationException("Message cannot be set for Continue type. Message is only used with Message type."); } return new { title = _title, height = _height, width = _width, card = _card }; } private string ValidateMessageType() { if (string.IsNullOrEmpty(_message)) { throw new InvalidOperationException("Message must be set for Message type. Use WithMessage()."); } if (!string.IsNullOrEmpty(_title)) { throw new InvalidOperationException("Title cannot be set for Message type. Title is only used with Continue type."); } if (_card != null) { throw new InvalidOperationException("Card cannot be set for Message type. Card is only used with Continue type."); } return _message; } /// /// Builds the TaskModuleResponse and wraps it in an . /// /// The HTTP status code (default: 200). public InvokeResponse Build(int statusCode = 200) { return new InvokeResponse(statusCode, Validate()); } } /// /// Task module result. /// public class Response { /// /// Type of result. /// [JsonPropertyName("type")] public required string Type { get; set; } /// /// The result value. /// [JsonPropertyName("value")] public object? Value { get; set; } }