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
|