--- /dev/null
+defmodule Notifier.FBGraph.LastPost do
+ use Agent
+
+ def start_link(_) do
+ Agent.start_link(fn -> %{} end, name: __MODULE__)
+ end
+
+ def set(id, post) do
+ Agent.update(__MODULE__, fn state ->
+ Map.put(state, id, post)
+ end)
+ end
+
+ def get(id) do
+ Agent.get(__MODULE__, fn state -> Map.get(state, id, %{id: nil}) end)
+ end
+end
use GenServer
require Logger
+ alias Notifier.FBGraph.LastPost
alias Notifier.SMTP
@graph_url "https://www.facebook.com/api/graphql"
notifier: notifier,
from: from,
http: http,
- notify: notify,
- last_post: %{id: nil}
+ notify: notify
}, {:continue, :get_latest_post}}
end
def handle_continue(:get_latest_post, %{http: http, id: id} = state) do
- last_post =
- :post
- |> Finch.build(@graph_url, headers(), body(id))
- |> Finch.request(http)
- |> handle_response()
- |> handle_post()
- |> maybe_notify(state)
-
- poll_interval = 60_000 * (15..25 |> Enum.random())
+ :post
+ |> Finch.build(@graph_url, headers(), body(id))
+ |> Finch.request(http)
+ |> handle_response()
+ |> handle_post()
+ |> maybe_notify(state)
+ |> set_last_post(state)
+
+ poll_interval = 60_000 * (5..10 |> Enum.random())
Logger.info("Will poll #{state.name} again in #{poll_interval}ms")
Process.send_after(self(), :get_posts, poll_interval)
- {:noreply, %{state | last_post: last_post}}
+ {:noreply, state}
end
def handle_info(:get_posts, state), do: {:noreply, state, {:continue, :get_latest_post}}
- defp maybe_notify({:error, _}, %{last_post: last_post}), do: last_post
+ defp set_last_post(nil, _), do: :noop
- defp maybe_notify(%{id: id}, %{last_post: %{id: id} = last_post}),
- do: last_post
+ defp set_last_post(post, %{id: id}) do
+ LastPost.set(id, post)
+ end
+
+ defp maybe_notify({:error, _}, _), do: nil
+
+ defp maybe_notify(%{id: id} = post, %{id: fb_id} = state) do
+ case LastPost.get(fb_id) do
+ %{id: ^id} -> post
+ _old_post -> notify(post, state)
+ end
+ end
- defp maybe_notify(
+ defp notify(
%{message: message, images: images} = post,
%{notifier: notifier, from: from, notify: notify, name: name}
) do
error
end
+ defp handle_post([res | _]) do
+ Logger.error("FB Graph returned error: #{inspect(res)}")
+ {:error, :no_data}
+ end
+
+ defp handle_post(res) do
+ Logger.error("Unhandled result: #{inspect(res)}")
+ {:error, :no_data}
+ end
+
defp handle_response({:ok, %Finch.Response{status: 200, body: body}}) do
body
|> String.split("\r\n")