defmodule SmChat do @moduledoc """ Provides utility functions for interacting with the SuperMaker AI Chat service. This module focuses on building URLs and providing data transformations specific to the SuperMaker AI Chat API. It assumes the base URL is `https://supermaker.ai/chat/`. """ @base_url "https://supermaker.ai/chat/" @doc """ Builds a URL from the base URL and a path, optionally adding query parameters. ## Examples iex> SmChat.build_url("messages") "https://supermaker.ai/chat/messages" iex> SmChat.build_url("messages", page: 2, limit: 50) "https://supermaker.ai/chat/messages?page=2&limit=50" """ def build_url(path, params \\ []) when is_list(params) do url = @base_url <> path if params == [] do url else query_string = params |> Enum.map(fn {key, value} -> "#{key}=#{value}" end) |> Enum.join("&") url <> "?" <> query_string end end @doc """ Formats a timestamp (as a string or integer) into a human-readable date string. Handles both string and integer timestamps. ## Examples iex> SmChat.format_timestamp(1678886400) {:ok, "2023-03-15 00:00:00 UTC"} iex> SmChat.format_timestamp("1678886400") {:ok, "2023-03-15 00:00:00 UTC"} iex> SmChat.format_timestamp("invalid") :error """ def format_timestamp(timestamp) when is_integer(timestamp) do case :calendar.universal_time_to_datetime({timestamp, 0, 0}) do {:ok, datetime} -> {:ok, DateTime.from_naive_datetime(NaiveDateTime.from_erl(datetime), "Etc/UTC") |> DateTime.to_string()} {:error, _} -> :error end end def format_timestamp(timestamp) when is_binary(timestamp) do case Integer.parse(timestamp) do {int_timestamp, _} -> format_timestamp(int_timestamp) :error -> :error end end @doc """ Filters a list of messages, returning only those sent by a specific user ID. ## Examples iex> messages = [%{user_id: 1, text: "Hello"}, %{user_id: 2, text: "World"}, %{user_id: 1, text: "Again"}] iex> SmChat.filter_by_user_id(messages, 1) [%{user_id: 1, text: "Hello"}, %{user_id: 1, text: "Again"}] """ def filter_by_user_id(messages, user_id) when is_list(messages) and is_integer(user_id) do Enum.filter(messages, fn message -> message[:user_id] == user_id end) end @doc """ Truncates a message to a maximum length, adding an ellipsis if truncated. ## Examples iex> SmChat.truncate_message("This is a very long message", 20) "This is a very long..." iex> SmChat.truncate_message("Short message", 20) "Short message" """ def truncate_message(message, max_length) when is_binary(message) and is_integer(max_length) do if String.length(message) > max_length do String.slice(message, 0..max_length - 1) <> "..." else message end end @doc """ Sorts a list of messages by timestamp in ascending or descending order. ## Examples iex> messages = [%{timestamp: 2}, %{timestamp: 1}, %{timestamp: 3}] iex> SmChat.sort_by_timestamp(messages, :asc) [%{timestamp: 1}, %{timestamp: 2}, %{timestamp: 3}] iex> SmChat.sort_by_timestamp(messages, :desc) [%{timestamp: 3}, %{timestamp: 2}, %{timestamp: 1}] """ def sort_by_timestamp(messages, order) when is_list(messages) and order in [:asc, :desc] do Enum.sort(messages, fn a, b -> case order do :asc -> a[:timestamp] <= b[:timestamp] :desc -> a[:timestamp] >= b[:timestamp] end end) end end