summaryrefslogtreecommitdiff
path: root/lib/chessh/schema/bot.ex
blob: 9a86d694c4ab3470bd471701f59df071f774c4fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
defmodule Chessh.Bot do
  alias Chessh.{Player, Game, Repo}
  use Ecto.Schema
  import Ecto.Query
  import Ecto.Changeset

  require Logger

  @derive {Jason.Encoder, only: [:id, :name, :webhook, :token, :public]}
  schema "bots" do
    field(:name, :string)
    field(:webhook, :string)
    field(:token, :string)
    field(:public, :boolean, default: false)

    belongs_to(:player, Player, foreign_key: :player_id)

    timestamps()
  end

  def changeset(game, attrs) do
    game
    |> cast(attrs, [
      :public,
      :name,
      :webhook,
      :token,
      :player_id
    ])
    |> validate_required([:name, :webhook, :token, :public])
    |> validate_format(:webhook, ~r/^https:\/\//, message: "must start with https://")
    |> unique_constraint(:name)
  end

  def make_game_status_message(%Game{
        id: game_id,
        bot: %Chessh.Bot{id: bot_id, name: bot_name},
        fen: fen,
        turn: turn,
        status: status,
        light_player_id: light_player_id,
        dark_player_id: dark_player_id
      }) do
    %{
      bot_id: bot_id,
      bot_name: bot_name,
      game_id: game_id,
      fen: fen,
      turn: Atom.to_string(turn),
      bot_turn:
        (is_nil(light_player_id) && turn == :light) || (is_nil(dark_player_id) && turn == :dark),
      status: Atom.to_string(status)
    }
  end

  def redrive_games(%Chessh.Bot{id: bot_id, webhook: webhook}) do
    messages =
      Repo.all(from(g in Game, where: g.bot_id == ^bot_id))
      |> Repo.preload([:bot])
      |> Enum.map(&make_game_status_message/1)

    send_message(webhook, messages)
  end

  def send_update(%Game{bot: %Chessh.Bot{webhook: webhook}} = game) do
    send_message(webhook, make_game_status_message(game))
  end

  defp send_message(webhook, msg) do
    :httpc.request(
      :post,
      {String.to_charlist(webhook), [], 'application/json', Jason.encode!(msg)},
      [],
      []
    )
  end
end