Skip to content

Commit

Permalink
Get interaction tracking by message working right
Browse files Browse the repository at this point in the history
  • Loading branch information
ProducerMatt committed Mar 21, 2024
1 parent 7ae872f commit ab6f332
Show file tree
Hide file tree
Showing 11 changed files with 308 additions and 140 deletions.
11 changes: 9 additions & 2 deletions .dialyzer_ignore.exs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
[
{"deps/nostrum/lib/nostrum/consumer.ex", "Function Nostrum.ConsumerGroup.join/1 does not exist."},
{"lib/service/discord.ex", "Function Nostrum.Api.get_channel_message/2 does not exist."},
{"lib/service/discord.ex", "Function Nostrum.Cache.Me.get/0 does not exist."},
{"lib/service/discord.ex", "Function Nostrum.Api.create_message/2 does not exist."},
{"lib/service/discord.ex", "Function Nostrum.Api.get_user!/1 does not exist."},
{"lib/service/discord.ex", "Function Nostrum.Struct.User.full_name/1 does not exist."},
{"lib/service/discord.ex", "Function Nostrum.Api.get_channel_message/2 does not exist."},
{"lib/service/discord.ex", "Function Nostrum.Cache.Me.get/0 does not exist."},
{"lib/stampede/application.ex", "Function Mix.env/0 does not exist."},
{"lib/stampede/interact.ex", "Function Mix.env/0 does not exist."},
{"/build/source/lib/elixir/lib/gen_server.ex", "Callback info about the Nostrum.Consumer behaviour is not available."},
{"deps/type_check/lib/type_check/spec.ex", "The pattern can never match the type {:ok, [], _}."},
{"lib/plugin.ex", "Function usage_tuples/0 has no local return."},
{"lib/plugin.ex", "Function job_result/0 has no local return."},
{"lib/plugin.ex", "Function plugin_job_result/0 has no local return."},
{"lib/service/discord.ex", "Function vips/0 has no local return."},
{"lib/service/discord.ex", "Function logger_state/0 has no local return."},
{"lib/service/dummy.ex", "@spec for send_msg has more types than are returned by the function."},
{"lib/service/dummy.ex", "Function dummy_channel_id/0 has no local return."},
Expand All @@ -21,7 +22,10 @@
{"lib/service/dummy.ex", "Function msg_tuple_incoming/0 has no local return."},
{"lib/service/dummy.ex", "Function channel/0 has no local return."},
{"lib/service/dummy.ex", "Function channel_buffers/0 has no local return."},
{"lib/site_config.ex", "Function server_id/0 has no local return."},
{"lib/site_config.ex", "Function schema/0 has no local return."},
{"lib/site_config.ex", "Function cfg_list/0 has no local return."},
{"lib/stampede.ex", "Function server_id/0 has no local return."},
{"lib/stampede.ex", "Function log_level/0 has no local return."},
{"lib/stampede.ex", "Function log_msg/0 has no local return."},
{"lib/stampede.ex", "Function prefix/0 has no local return."},
Expand All @@ -33,7 +37,10 @@
{"lib/stampede.ex", "Function channel_lock_status/0 has no local return."},
{"lib/stampede.ex", "Function throw_internal_error/0 has no local return."},
{"lib/stampede.ex", "Function throw_internal_error/1 only terminates with explicit exception."},
{"lib/stampede/cfg_table.ex", "Function vips/0 has no local return."},
{"lib/stampede/cfg_table.ex", "Function table_object/0 has no local return."},
{"lib/stampede/interact.ex", "Function mod_state/0 has no local return."},
{"lib/stampede/table_ids.ex", "Function mod_state/0 has no local return."},
{"lib/txt_block.ex", "Function block/0 has no local return."},
{"lib/txt_block.ex", "Function type/0 has no local return."},
{"lib/txt_block.ex", "Function t/0 has no local return."},
Expand Down
83 changes: 47 additions & 36 deletions lib/plugin.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ defmodule Plugin do
require PluginCrashInfo
alias PluginCrashInfo, as: CrashInfo
alias Stampede, as: S
alias S.{Msg, Response, Interaction}
require Interaction
alias S.{Msg, Response, InteractionForm}
require InteractionForm
@first_response_timeout 500

@typedoc """
Expand Down Expand Up @@ -150,6 +150,8 @@ defmodule Plugin do
end
end

@spec! query_plugins(list(S.module_function_args() | module()), SiteConfig.t(), S.Msg.t()) ::
nil | {response :: Response.t(), interaction_id :: S.interaction_id()}
def query_plugins(call_list, cfg, msg) do
tasks =
Enum.map(call_list, fn
Expand Down Expand Up @@ -229,17 +231,19 @@ defmodule Plugin do
nil ->
nil

chosen_response = %Response{callback: nil} ->
S.Interaction.new(
plugin: chosen_response.origin_plug,
msg: msg,
response: chosen_response,
channel_lock: chosen_response.channel_lock,
traceback: traceback
)
|> S.Interact.record_interaction!()
%Response{callback: nil} ->
{:ok, iid} =
S.InteractionForm.new(
service: cfg.service,
plugin: chosen_response.origin_plug,
msg: msg,
response: chosen_response,
channel_lock: chosen_response.channel_lock,
traceback: traceback
)
|> S.Interact.prepare_interaction!()

chosen_response
{chosen_response, iid}

%Response{callback: {mod, fun, args}} ->
followup =
Expand All @@ -253,41 +257,48 @@ defmodule Plugin do
followup.why
]

S.Interaction.new(
plugin: chosen_response.origin_plug,
msg: msg,
response: followup,
channel_lock: followup.channel_lock,
traceback: new_tb
)
|> S.Interact.record_interaction!()
{:ok, iid} =
S.InteractionForm.new(
service: cfg.service,
plugin: chosen_response.origin_plug,
msg: msg,
response: followup,
channel_lock: followup.channel_lock,
traceback: new_tb
)
|> S.Interact.prepare_interaction!()

followup
{followup, iid}
end
end

@doc "Poll all enabled plugins and choose the most relevant one."
@spec! get_top_response(SiteConfig.t(), Msg.t()) :: nil | Response.t()
@spec! get_top_response(SiteConfig.t(), Msg.t()) ::
nil | {response :: Response.t(), interaction_id :: S.interaction_id()}
def get_top_response(cfg, msg) do
case S.Interact.channel_locked?(msg.channel_id) do
{{m, f, a}, _plugin, _iid} ->
response = query_plugins([{m, f, [cfg, msg | a]}], cfg, msg)

Map.update!(response, :why, fn tb ->
[
"Channel ",
msg.channel_id |> inspect(),
"was locked to module ",
m |> inspect(),
", function ",
"f",
", so we called it.\n"
| tb
]
end)
{response, iid} = query_plugins([{m, f, [cfg, msg | a]}], cfg, msg)

explained_response =
Map.update!(response, :why, fn tb ->
[
"Channel ",
msg.channel_id |> inspect(),
"was locked to module ",
m |> inspect(),
", function ",
"f",
", so we called it.\n"
| tb
]
end)

{explained_response, iid}

false ->
__MODULE__.ls(SiteConfig.fetch!(cfg, :plugs))
|> MapSet.to_list()
|> query_plugins(cfg, msg)
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/plugin/why.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ defmodule Plugin.Why do
require Stampede.Response
alias Plugin.Why.Debugging
alias Stampede, as: S
alias S.{Response, Interaction}
require Interaction
alias S.{Response, InteractionForm}
require InteractionForm

use Plugin

Expand Down
15 changes: 11 additions & 4 deletions lib/service/discord.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ defmodule Service.Discord do
@consecutive_msg_limit 10

@impl Service
@spec! into_msg(service_msg :: %Nostrum.Struct.Message{}) :: S.Msg.t()
def into_msg(msg) do
Msg.new(
id: msg.id,
Expand Down Expand Up @@ -154,6 +155,7 @@ defmodule Service.Discord do
send_msg(
channel_id,
formatted
|> TxtBlock.to_str_list(Service.Discord)
)
end)

Expand Down Expand Up @@ -323,11 +325,11 @@ defmodule Service.Discord.Handler do
else
cond do
discord_msg.guild_id in state.guild_ids ->
do_msg_create(discord_msg)
:ok = do_msg_create(discord_msg)

Discord.dm?(discord_msg) ->
if vip_in_this_context?(state.vip_ids, discord_msg.guild_id, discord_msg.author.id) do
do_msg_create(discord_msg)
:ok = do_msg_create(discord_msg)
else
Logger.warning(fn ->
[
Expand Down Expand Up @@ -363,12 +365,17 @@ defmodule Service.Discord.Handler do
our_cfg = S.CfgTable.get_cfg!(Discord, our_msg.server_id)

case Plugin.get_top_response(our_cfg, our_msg) do
%Response{text: r_text} when r_text != nil ->
Api.create_message(our_msg.channel_id, r_text)
{%Response{text: r_text}, iid} when r_text != nil ->
{:ok, %{id: bot_response_msg_id}} =
Api.create_message(our_msg.channel_id, r_text)

S.Interact.finalize_interaction(iid, bot_response_msg_id)

nil ->
:do_nothing
end

:ok
end
end

Expand Down
36 changes: 24 additions & 12 deletions lib/service/dummy.ex
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,13 @@ defmodule Service.Dummy do
msg_content(),
keyword()
) ::
%{response: nil | Response.t(), posted_msg_id: dummy_msg_id()} | nil | Response.t()
%{
response: nil | Response.t(),
posted_msg_id: dummy_msg_id(),
bot_response_msg_id: nil | dummy_msg_id()
}
| nil
| Response.t()
def send_msg(server_id, channel, user, text, opts \\ []) do
GenServer.call(__MODULE__, {:add_msg, {server_id, channel, user, text, opts[:ref]}, opts})
end
Expand Down Expand Up @@ -310,21 +316,27 @@ defmodule Service.Dummy do
{:reply, nil, state}
else
%{
msg_id: incoming_msg_id,
msg_object: incoming_msg,
posted_msg_id: incoming_msg_id,
posted_msg_object: incoming_msg,
new_state: new_state_1
} = do_add_new_msg(msg_tuple, state)

cfg = S.CfgTable.get_cfg!(__MODULE__, server_id)
response = Plugin.get_top_response(cfg, incoming_msg)

result =
case response do
response when is_struct(response, Response) ->
%{new_state: new_state_2} =
case Plugin.get_top_response(cfg, incoming_msg) do
{response, iid} when is_struct(response, Response) ->
%{new_state: new_state_2, posted_msg_id: bot_response_msg_id} =
do_post_response({server_id, channel}, response, new_state_1)

{:reply, %{response: response, posted_msg_id: incoming_msg_id}, new_state_2}
S.Interact.finalize_interaction(iid, bot_response_msg_id)

{:reply,
%{
response: response,
posted_msg_id: incoming_msg_id,
bot_response_msg_id: bot_response_msg_id
}, new_state_2}

nil ->
{:reply, %{response: nil, posted_msg_id: incoming_msg_id}, new_state_1}
Expand Down Expand Up @@ -391,8 +403,8 @@ defmodule Service.Dummy do
end

@spec! do_add_new_msg(tuple(), %__MODULE__{}) :: %{
msg_id: dummy_msg_id(),
msg_object: %Msg{},
posted_msg_id: dummy_msg_id(),
posted_msg_object: %Msg{},
new_state: %__MODULE__{}
}
defp do_add_new_msg(msg_tuple = {server_id, channel, user, text, ref}, state) do
Expand All @@ -414,8 +426,8 @@ defmodule Service.Dummy do
msg_object = into_msg(msg_tuple |> Tuple.insert_at(0, msg_id))

%{
msg_id: msg_id,
msg_object: msg_object,
posted_msg_id: msg_id,
posted_msg_object: msg_object,
new_state: state
}
end
Expand Down
1 change: 1 addition & 0 deletions lib/stampede.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ defmodule Stampede do
false | {module_function_args(), atom(), integer()}
@type! timestamp :: String.t()
@type! service_name :: atom()
@type! interaction_id :: non_neg_integer()

def confused_response(),
do: "*confused beeping*"
Expand Down
1 change: 1 addition & 0 deletions lib/stampede/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ defmodule Stampede.Application do
default_children = [
{PartitionSupervisor, child_spec: Task.Supervisor, name: Stampede.QuickTaskSupers},
# NOTE: call with Stampede.quick_task_via()
Stampede.TableIds,
{Stampede.CfgTable, config_dir: Keyword.fetch!(startup_args, :config_dir)},
{Stampede.Interact, wipe_tables: Keyword.fetch!(startup_args, :clear_state)}
]
Expand Down
Loading

0 comments on commit ab6f332

Please sign in to comment.