// 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; }
}