Files
crm-calls/calls/backend/Calls.Api/Recording/RecordingOptions.cs

80 lines
4.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace Calls.Api.Recording;
/// <summary>
/// Настройки записи и транскрипции. Имена — как переменные окружения Coolify (см. README «Запис і транскрипція»).
/// Без OPENAI_API_KEY или CRM_USER_EMAIL/CRM_USER_PASSWORD запись делается, но обработка ждёт настроек
/// (в CRM и вики ничего не пишется, файлы остаются на диске).
/// </summary>
public sealed class RecordingOptions
{
public bool Enabled { get; init; } = true;
public int MaxConcurrentCalls { get; init; } = 1;
public int MinCallSeconds { get; init; } = 60;
/// <summary>С какого числа участников начинается звонок и запись (один человек в комнате — ещё не звонок).</summary>
public int RecordMinParticipants { get; init; } = 2;
/// <summary>Сколько комната должна быть пустой, чтобы звонок считался законченным (переподключения).</summary>
public TimeSpan EmptyGrace { get; init; } = TimeSpan.FromSeconds(20);
public TimeSpan PollInterval { get; init; } = TimeSpan.FromSeconds(5);
public string ProsodyUrl { get; init; } = "http://jitsi-prosody:5280";
public string XmppDomain { get; init; } = "meet.jitsi";
public string JibriUrl { get; init; } = "http://jitsi-jibri:2222";
public string MeetBaseUrl { get; init; } = "https://meet.volcanic.tes.gd";
public string RecorderDomain { get; init; } = "hidden.meet.jitsi";
public string RecorderUser { get; init; } = "recorder";
public string RecorderPassword { get; init; } = "";
public string RecordingsDir { get; init; } = "/recordings";
public string OpenAiKey { get; init; } = "";
public string OpenAiModel { get; init; } = "whisper-1";
public string OpenAiBaseUrl { get; init; } = "https://api.openai.com/v1";
public long MaxPartBytes { get; init; } = 25L * 1024 * 1024;
public string SupabaseUrl { get; init; } = "";
public string SupabaseKey { get; init; } = "";
public string CrmUserEmail { get; init; } = "";
public string CrmUserPassword { get; init; } = "";
public string Bucket { get; init; } = "files";
public string Prefix { get; init; } = "calls/";
public string WikiUrl { get; init; } = "https://wiki-crm.tes.gd";
public string WikiFolder { get; init; } = "Дзвінки";
public string TimeZoneId { get; init; } = "Europe/Warsaw";
public bool HasOpenAi => OpenAiKey.Length > 0;
public bool HasCrmUser => CrmUserEmail.Length > 0 && CrmUserPassword.Length > 0;
public static RecordingOptions From(IConfiguration c)
{
static string S(IConfiguration c, string k, string d) => string.IsNullOrWhiteSpace(c[k]) ? d : c[k]!.Trim();
static int I(IConfiguration c, string k, int d) => int.TryParse(c[k], out var v) && v >= 0 ? v : d;
var prefix = S(c, "RECORDINGS_PREFIX", "calls/").TrimStart('/');
if (prefix.Length > 0 && !prefix.EndsWith('/')) prefix += "/";
return new RecordingOptions
{
Enabled = !string.Equals(c["RECORDING_ENABLED"], "false", StringComparison.OrdinalIgnoreCase),
MaxConcurrentCalls = Math.Max(1, I(c, "MAX_CONCURRENT_CALLS", 1)),
MinCallSeconds = I(c, "MIN_CALL_SECONDS", 60),
RecordMinParticipants = Math.Max(1, I(c, "RECORD_MIN_PARTICIPANTS", 2)),
ProsodyUrl = S(c, "PROSODY_URL", "http://jitsi-prosody:5280").TrimEnd('/'),
JibriUrl = S(c, "JIBRI_URL", "http://jitsi-jibri:2222").TrimEnd('/'),
MeetBaseUrl = "https://" + S(c, "Jitsi:Domain", "meet.volcanic.tes.gd"),
RecorderPassword = S(c, "JIBRI_RECORDER_PASSWORD", ""),
RecordingsDir = S(c, "RECORDINGS_DIR", "/recordings"),
OpenAiKey = S(c, "OPENAI_API_KEY", ""),
OpenAiModel = S(c, "OPENAI_TRANSCRIBE_MODEL", "whisper-1"),
OpenAiBaseUrl = S(c, "OPENAI_BASE_URL", "https://api.openai.com/v1").TrimEnd('/'),
MaxPartBytes = I(c, "TRANSCRIBE_MAX_PART_MB", 25) * 1024L * 1024,
SupabaseUrl = S(c, "Supabase:Url", "").TrimEnd('/'),
SupabaseKey = S(c, "Supabase:PublishableKey", ""),
CrmUserEmail = S(c, "CRM_USER_EMAIL", ""),
CrmUserPassword = c["CRM_USER_PASSWORD"] ?? "",
Bucket = S(c, "RECORDINGS_BUCKET", "files"),
Prefix = prefix,
WikiUrl = S(c, "WIKI_URL", "https://wiki-crm.tes.gd").TrimEnd('/'),
WikiFolder = S(c, "WIKI_CALLS_FOLDER", "Дзвінки"),
TimeZoneId = S(c, "CALLS_TIME_ZONE", "Europe/Warsaw"),
};
}
}