An example AT Protocol application, written in Elixir using atex and Drinkup.
1defmodule StatusphereWeb.StatusController do
2 alias Statusphere.Repo
3 require Logger
4 use StatusphereWeb, :controller
5
6 def create(conn, %{"status" => status}) do
7 rkey = to_string(Atex.TID.now())
8
9 with {:ok, client} <- Atex.XRPC.OAuthClient.from_conn(conn),
10 {:ok, record} <-
11 Xyz.Statusphere.Status.main(%{
12 status: status,
13 createdAt: NaiveDateTime.utc_now() |> NaiveDateTime.to_iso8601()
14 }),
15 {:ok, _, client} <-
16 Atex.XRPC.post(
17 client,
18 %Com.Atproto.Repo.PutRecord{
19 input: %{
20 repo: client.did,
21 collection: "xyz.statusphere.status",
22 rkey: rkey,
23 record: record
24 }
25 }
26 ) do
27 uri =
28 Atex.AtURI.to_string(%Atex.AtURI{
29 authority: client.did,
30 collection: "xyz.statusphere.status",
31 rkey: rkey
32 })
33
34 optimistic_insert =
35 %Statusphere.Status{}
36 |> Statusphere.Status.changeset(%{
37 uri: uri,
38 author_did: client.did,
39 status: record.status,
40 created_at: NaiveDateTime.from_iso8601!(record.createdAt),
41 indexed_at: NaiveDateTime.utc_now()
42 })
43 |> Repo.insert()
44
45 case optimistic_insert do
46 {:ok, _} ->
47 nil
48
49 {:error, changeset} ->
50 Logger.error("Failed to optimistically insert status: #{inspect(changeset)}")
51 end
52
53 conn
54 |> Atex.XRPC.OAuthClient.update_plug(client)
55 |> redirect(to: ~p"/")
56 else
57 :error ->
58 conn
59 |> put_status(401)
60 |> html("<h1>Error: not logged in</h1>")
61
62 {:error, [_ | _]} ->
63 conn
64 |> put_status(400)
65 |> html("<h1>Error: invalid status</h1>")
66
67 {:error, err, client} ->
68 Logger.error("Failed to write record #{err}")
69
70 conn
71 |> Atex.XRPC.OAuthClient.update_plug(client)
72 |> put_status(500)
73 |> html("<h1>Error: failed to write record</h1>")
74 end
75 end
76end