-module(bot_controller). -include("records.hrl"). -export([register/0, stop/0, delete/0, count_bots/0]). -define(REG_NAME, {bot_registration, node()}). %% ------------------------------------------------------------------ %% @doc Асинхронно регистрирует ботов (одновременно только один процесс). %% Возвращает pid процесса или ошибку. %% ------------------------------------------------------------------ register() -> Count = list_to_integer(os:getenv("BOT_COUNT", "0")), Domain = list_to_binary(os:getenv("BOT_DOMAIN", "eventhub.com")), Password = list_to_binary(os:getenv("BOT_DEFAULT_PASSWORD", "botpass123")), if Count =< 0 -> {error, <<"BOT_COUNT must be greater than 0">>}; true -> io:format("Starting async registration of ~p bots with domain ~s...~n", [Count, Domain]), Pid = spawn(fun() -> register_bots(Count, Domain, Password) end), case global:register_name(?REG_NAME, Pid) of yes -> {ok, Pid}; no -> % Уже есть активный процесс регистрации exit(Pid, kill), {error, registration_already_running} end end. %% ------------------------------------------------------------------ %% @doc Останавливает текущий процесс регистрации. %% ------------------------------------------------------------------ stop() -> case global:whereis_name(?REG_NAME) of undefined -> io:format("No active bot registration found.~n"); Pid -> exit(Pid, kill), io:format("Bot registration process ~p stopped.~n", [Pid]) end. %% ------------------------------------------------------------------ %% @doc Удаляет всех пользователей с ролью bot. %% ------------------------------------------------------------------ delete() -> Bots = mnesia:dirty_match_object(#user{role = bot, _ = '_'}), lists:foreach(fun(#user{id = Id}) -> mnesia:dirty_delete({user, Id}) end, Bots), io:format("Deleted ~p bots.~n", [length(Bots)]), ok. %% ------------------------------------------------------------------ %% @doc Возвращает количество ботов в базе. %% ------------------------------------------------------------------ count_bots() -> length(mnesia:dirty_match_object(#user{role = bot, _ = '_'})). %% ------------------------------------------------------------------ %% Внутренние функции %% ------------------------------------------------------------------ register_bots(Count, Domain, Password) -> register_bots(Count, Domain, Password, []). register_bots(0, _, _, Acc) -> io:format("Async registration completed. Created ~p bots.~n", [length(Acc)]), global:unregister_name(?REG_NAME); register_bots(N, Domain, Password, Acc) -> Email = generate_email(Domain), case core_user:create_bot(Email, Password) of {ok, _User} -> register_bots(N-1, Domain, Password, [Email | Acc]); {error, duplicate_email} -> register_bots(N, Domain, Password, Acc); {error, _} -> register_bots(N-1, Domain, Password, Acc) end. generate_email(Domain) -> Name = random_string(8), <<"bot_", Name/binary, "@", Domain/binary>>. random_string(Length) -> Chars = <<"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789">>, list_to_binary([lists:nth(rand:uniform(byte_size(Chars)), binary_to_list(Chars)) || _ <- lists:seq(1, Length)]).