diff --git a/server/src/at_record_server/discogs_client.gleam b/server/src/at_record_server/discogs_client.gleam index fa79f4c..2552d85 100644 --- a/server/src/at_record_server/discogs_client.gleam +++ b/server/src/at_record_server/discogs_client.gleam @@ -3,6 +3,7 @@ //// into a flat shape the frontend can drop straight into the add form. import at_record/gen/defs +import at_record_server/user_agent import gleam/dynamic/decode import gleam/http import gleam/http/request.{type Request} @@ -17,8 +18,6 @@ import wisp const host = "api.discogs.com" -const user_agent = "at-record/0.1" - pub type Release { Release( discogs_id: Int, @@ -104,7 +103,7 @@ pub fn search( |> request.set_host(host) |> request.set_path("/database/search") |> request.set_query(params) - |> request.set_header("user-agent", user_agent) + |> request.set_header("user-agent", user_agent.value) let req = case auth { Some(Auth(key, secret)) -> request.set_header( @@ -140,7 +139,7 @@ pub fn search_by_barcode( |> request.set_host(host) |> request.set_path("/database/search") |> request.set_query([#("barcode", barcode), #("per_page", "5")]) - |> request.set_header("user-agent", user_agent) + |> request.set_header("user-agent", user_agent.value) let req = case auth { Some(Auth(key, secret)) -> request.set_header( @@ -309,7 +308,7 @@ pub fn release_details( |> request.set_scheme(http.Https) |> request.set_host(host) |> request.set_path("/releases/" <> int.to_string(discogs_id)) - |> request.set_header("user-agent", user_agent) + |> request.set_header("user-agent", user_agent.value) let req = case auth { Some(Auth(key, secret)) -> request.set_header( @@ -447,7 +446,7 @@ pub fn collection_page( #("per_page", "100"), #("page", int.to_string(page)), ]) - |> request.set_header("user-agent", user_agent) + |> request.set_header("user-agent", user_agent.value) |> request.set_header("authorization", authorization) case send(req) { @@ -521,7 +520,7 @@ pub fn wantlist_page( #("per_page", "100"), #("page", int.to_string(page)), ]) - |> request.set_header("user-agent", user_agent) + |> request.set_header("user-agent", user_agent.value) |> request.set_header("authorization", authorization) case send(req) { diff --git a/server/src/at_record_server/discogs_oauth.gleam b/server/src/at_record_server/discogs_oauth.gleam index ff328dc..6c0ce74 100644 --- a/server/src/at_record_server/discogs_oauth.gleam +++ b/server/src/at_record_server/discogs_oauth.gleam @@ -4,6 +4,7 @@ import at_record_server/clock import at_record_server/discogs_client.{type Auth, type Sender, Auth} +import at_record_server/user_agent import gleam/bit_array import gleam/crypto import gleam/dynamic/decode @@ -19,8 +20,6 @@ import gleam/uri const api_host = "api.discogs.com" -const user_agent = "at-record/0.1" - pub type TokenPair { TokenPair(token: String, secret: String) } @@ -155,7 +154,7 @@ pub fn api_request( |> request.set_scheme(http.Https) |> request.set_host(api_host) |> request.set_path(path) - |> request.set_header("user-agent", user_agent) + |> request.set_header("user-agent", user_agent.value) case query { [] -> base _ -> request.set_query(base, query) diff --git a/server/src/at_record_server/musicbrainz_client.gleam b/server/src/at_record_server/musicbrainz_client.gleam index 05f0c8d..d9844a4 100644 --- a/server/src/at_record_server/musicbrainz_client.gleam +++ b/server/src/at_record_server/musicbrainz_client.gleam @@ -8,6 +8,7 @@ import at_record_server/catalog_deps.{ type MbArtistCredit, type MbRelease, MbArtistCredit, MbRelease, } import at_record_server/discogs_client +import at_record_server/user_agent import atproto/xrpc.{type Client} import gleam/dynamic/decode import gleam/erlang/process @@ -23,8 +24,6 @@ import wisp const host = "musicbrainz.org" -const user_agent = "at-record/0.1 (https://tangled.org/@mokkenstorm.dev/at-record)" - /// A resolved MusicBrainz release plus whatever artist credits rode along in /// the same response, so artist minting can source MBIDs without a second /// MB call. @@ -220,7 +219,7 @@ fn barcode_request(barcode: String) -> Request(String) { #("fmt", "json"), #("limit", "1"), ]) - |> request.set_header("user-agent", user_agent) + |> request.set_header("user-agent", user_agent.value) } fn url_relation_request(discogs_id: Int) -> Request(String) { @@ -236,7 +235,7 @@ fn url_relation_request(discogs_id: Int) -> Request(String) { #("inc", "release-rels+artist-credits"), #("fmt", "json"), ]) - |> request.set_header("user-agent", user_agent) + |> request.set_header("user-agent", user_agent.value) } /// The first exact-match (`score` 100) release in a barcode search response, diff --git a/server/src/at_record_server/user_agent.gleam b/server/src/at_record_server/user_agent.gleam new file mode 100644 index 0000000..c5a69f2 --- /dev/null +++ b/server/src/at_record_server/user_agent.gleam @@ -0,0 +1,5 @@ +//// The outbound User-Agent for third-party APIs (Discogs, MusicBrainz), with +//// contact info per their etiquette guidelines. One source of truth so the +//// clients never drift. + +pub const value = "at-record/0.1 (https://tangled.org/@mokkenstorm.dev/at-record; niels@mokkenstorm.dev; https://bsky.app/profile/mokkenstorm.dev)"