An example AT Protocol application, written in Elixir using atex and Drinkup.
at main 75 lines 1.9 kB view raw
1defmodule StatusphereWeb.PageController do 2 alias Statusphere.Repo 3 alias Statusphere.Status 4 require Logger 5 import Ecto.Query, only: [from: 2] 6 use StatusphereWeb, :controller 7 8 def home(conn, _params) do 9 query = 10 from u in Status, 11 order_by: [desc: u.indexed_at], 12 limit: 10 13 14 statuses = Repo.all(query) 15 16 status_identities = 17 statuses 18 |> Enum.map(fn %{author_did: did} -> 19 case Atex.IdentityResolver.resolve(did) do 20 {:ok, identity} -> {identity.did, identity.handle} 21 {:error, _} -> {did, did} 22 end 23 end) 24 |> Enum.into(%{}) 25 26 with {:ok, client} <- Atex.XRPC.OAuthClient.from_conn(conn), 27 {:ok, %{body: %{value: profile}}, client} <- 28 Atex.XRPC.get(client, %Com.Atproto.Repo.GetRecord{ 29 params: %{ 30 repo: client.did, 31 collection: "app.bsky.actor.profile", 32 rkey: "self" 33 } 34 }) do 35 conn 36 |> Atex.XRPC.OAuthClient.update_plug(client) 37 |> render(:home, 38 profile: profile, 39 did: client.did, 40 statuses: statuses, 41 status_identities: status_identities 42 ) 43 else 44 {:error, err, client} -> 45 Logger.error("Failed to fetch Bluesky profile for #{client.did}: #{inspect(err)}") 46 47 conn 48 |> Atex.XRPC.OAuthClient.update_plug(client) 49 |> render(:home, 50 profile: %{}, 51 did: client.did, 52 statuses: statuses, 53 status_identities: status_identities 54 ) 55 56 _err -> 57 render(conn, :home, 58 profile: nil, 59 did: nil, 60 statuses: statuses, 61 status_identities: status_identities 62 ) 63 end 64 end 65 66 def login(conn, _params) do 67 render(conn, :login) 68 end 69 70 def logout(conn, _params) do 71 conn 72 |> delete_session(:atex_oauth) 73 |> redirect(to: "/") 74 end 75end