+59
auth/server.go
+59
auth/server.go
···
1
+
package auth
2
+
3
+
import (
4
+
"context"
5
+
"encoding/json"
6
+
"fmt"
7
+
"net/http"
8
+
"os"
9
+
10
+
"github.com/bluesky-social/indigo/atproto/auth/oauth"
11
+
)
12
+
13
+
var oAuthApp *oauth.ClientApp = nil
14
+
15
+
func OauthCallback(authChannel chan *oauth.ClientSession) http.HandlerFunc {
16
+
return func(w http.ResponseWriter, r *http.Request) {
17
+
ctx := r.Context()
18
+
sessData, err := oAuthApp.ProcessCallback(ctx, r.URL.Query())
19
+
if err != nil {
20
+
http.Error(w, err.Error(), http.StatusInternalServerError)
21
+
authChannel <- nil
22
+
}
23
+
24
+
sess, err := oAuthApp.ResumeSession(context.Background(), sessData.AccountDID, sessData.SessionID)
25
+
if err != nil {
26
+
http.Error(w, err.Error(), http.StatusInternalServerError)
27
+
authChannel <- nil
28
+
}
29
+
30
+
authChannel <- sess
31
+
}
32
+
}
33
+
34
+
func ClientMetadata(w http.ResponseWriter, r *http.Request) {
35
+
doc := oAuthApp.Config.ClientMetadata()
36
+
w.Header().Set("Content-Type", "application/json")
37
+
if err := json.NewEncoder(w).Encode(doc); err != nil {
38
+
http.Error(w, err.Error(), http.StatusInternalServerError)
39
+
}
40
+
}
41
+
42
+
func askAuth(oauthApp *oauth.ClientApp) {
43
+
flow, err := oauthApp.StartAuthFlow(context.Background(), os.Getenv("HANDLE"))
44
+
if err != nil {
45
+
panic(err)
46
+
}
47
+
fmt.Printf("Please connect to your PDS using this link : %s\n", flow)
48
+
}
49
+
50
+
func StartServer(authChannel chan *oauth.ClientSession) {
51
+
config := oauth.NewLocalhostConfig("http://127.0.0.1:3000/oauth/callback", []string{"atproto", "repo:fm.teal.alpha.feed.play"})
52
+
oAuthApp = oauth.NewClientApp(&config, oauth.NewMemStore())
53
+
54
+
http.HandleFunc("GET /client-metadata.json", ClientMetadata)
55
+
http.HandleFunc("/oauth/callback", OauthCallback(authChannel))
56
+
57
+
askAuth(oAuthApp)
58
+
http.ListenAndServe("127.0.0.1:3000", http.DefaultServeMux)
59
+
}
+7
-2
go.mod
+7
-2
go.mod
···
3
3
go 1.25.1
4
4
5
5
require (
6
+
github.com/bluesky-social/indigo v0.0.0-20250922154404-cbaa8d37ca48
7
+
github.com/teal-fm/piper v0.0.0-20250922170002-9420ff6dc552
8
+
)
9
+
10
+
require (
6
11
github.com/beorn7/perks v1.0.1 // indirect
7
-
github.com/bluesky-social/indigo v0.0.0-20250922154404-cbaa8d37ca48 // indirect
8
12
github.com/carlmjohnson/versioninfo v0.22.5 // indirect
9
13
github.com/cespare/xxhash/v2 v2.2.0 // indirect
10
14
github.com/felixge/httpsnoop v1.0.4 // indirect
11
15
github.com/go-logr/logr v1.4.2 // indirect
12
16
github.com/go-logr/stdr v1.2.2 // indirect
13
17
github.com/gogo/protobuf v1.3.2 // indirect
18
+
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
19
+
github.com/google/go-querystring v1.1.0 // indirect
14
20
github.com/google/uuid v1.6.0 // indirect
15
21
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
16
22
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
···
46
52
github.com/prometheus/common v0.45.0 // indirect
47
53
github.com/prometheus/procfs v0.12.0 // indirect
48
54
github.com/spaolacci/murmur3 v1.1.0 // indirect
49
-
github.com/teal-fm/piper v0.0.0-20250922170002-9420ff6dc552 // indirect
50
55
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e // indirect
51
56
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect
52
57
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect
+31
-2
go.sum
+31
-2
go.sum
···
2
2
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
3
3
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
4
4
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
5
-
github.com/bluesky-social/indigo v0.0.0-20250506174012-7075cf22f63e h1:yEW1njmALj7i1AjLhq6Lsxts48JUCTT+wpM9m7GNLVY=
6
-
github.com/bluesky-social/indigo v0.0.0-20250506174012-7075cf22f63e/go.mod h1:ovyxp8AMO1Hoe838vMJUbqHTZaAR8ABM3g3TXu+A5Ng=
7
5
github.com/bluesky-social/indigo v0.0.0-20250922154404-cbaa8d37ca48 h1:3ZVua3u0huLK2VwKJ5ubmSf8jajApWT7RZPE8nMYxEo=
8
6
github.com/bluesky-social/indigo v0.0.0-20250922154404-cbaa8d37ca48/go.mod h1:n6QE1NDPFoi7PRbMUZmc2y7FibCqiVU4ePpsvhHUBR8=
9
7
github.com/carlmjohnson/versioninfo v0.22.5 h1:O00sjOLUAFxYQjlN/bzYTuZiS0y6fWDQjMRvwtKgwwc=
···
12
10
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
13
11
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
14
12
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
13
+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
15
14
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
16
15
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
17
16
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
···
23
22
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
24
23
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
25
24
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
25
+
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
26
+
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
27
+
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
28
+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
29
+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
30
+
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
31
+
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
26
32
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
27
33
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
28
34
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
35
+
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
29
36
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
30
37
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
31
38
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
39
+
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
32
40
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
33
41
github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M=
34
42
github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
···
44
52
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
45
53
github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk=
46
54
github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8=
55
+
github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=
56
+
github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps=
47
57
github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7PTTDQNsQ=
48
58
github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE=
49
59
github.com/ipfs/go-ipfs-ds-help v1.1.1 h1:B5UJOH52IbcfS56+Ul+sv8jnIV10lbjLF5eOO0C66Nw=
···
64
74
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
65
75
github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o=
66
76
github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
77
+
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
67
78
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
68
79
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
69
80
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
70
81
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
71
82
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
72
83
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
84
+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
85
+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
73
86
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
74
87
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
88
+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
89
+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
75
90
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
76
91
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
77
92
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
···
94
109
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
95
110
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
96
111
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
112
+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
97
113
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
98
114
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f h1:VXTQfuJj9vKR4TCkEuWIckKvdHFeJH/huIFJ9/cXOB0=
99
115
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw=
···
106
122
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
107
123
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
108
124
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
125
+
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
126
+
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
109
127
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
110
128
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
129
+
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
111
130
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
131
+
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
112
132
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
113
133
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
114
134
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
···
117
137
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
118
138
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
119
139
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
140
+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
141
+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
120
142
github.com/teal-fm/piper v0.0.0-20250922170002-9420ff6dc552 h1:dHroQmsDE14EYxTfPCyKzd2HD9AZkOCL46nyoFjRgrM=
121
143
github.com/teal-fm/piper v0.0.0-20250922170002-9420ff6dc552/go.mod h1:T4s0uuV1isetJS7RMSDrPUBUpgnfmLO1Sn1WeoYOMS8=
122
144
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
145
+
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
123
146
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
124
147
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e h1:28X54ciEwwUxyHn9yrZfl5ojgF4CBNLWX7LR0rvBkf4=
125
148
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so=
···
143
166
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
144
167
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
145
168
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
169
+
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
170
+
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
146
171
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
147
172
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
148
173
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
···
209
234
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
210
235
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
211
236
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
237
+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
238
+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
212
239
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
213
240
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
214
241
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
215
242
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
216
243
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
244
+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
245
+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
217
246
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
218
247
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
219
248
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
+42
-38
main.go
+42
-38
main.go
···
7
7
"io"
8
8
"net/http"
9
9
"os"
10
+
"teal-cider/auth"
10
11
"teal-cider/types"
11
12
"time"
12
13
13
14
"github.com/bluesky-social/indigo/api/atproto"
15
+
"github.com/bluesky-social/indigo/atproto/auth/oauth"
14
16
"github.com/bluesky-social/indigo/atproto/client"
15
-
"github.com/bluesky-social/indigo/atproto/identity"
16
-
"github.com/bluesky-social/indigo/atproto/syntax"
17
17
"github.com/bluesky-social/indigo/lex/util"
18
18
"github.com/teal-fm/piper/api/teal"
19
19
)
···
22
22
23
23
var ENV_DATA envData = envData{}
24
24
25
-
func getCurrentSong() types.NowPlaying {
25
+
func getCurrentSong() (types.NowPlaying, error) {
26
26
r := types.NowPlaying{}
27
27
req, err := http.NewRequest("GET", "http://localhost:10767/api/v1/playback/now-playing", nil)
28
28
if err != nil {
29
-
panic(err)
29
+
return r, err
30
30
}
31
31
32
32
ENV_DATA.AddCiderHeader(req)
33
33
34
34
res, err := http.DefaultClient.Do(req)
35
35
if err != nil {
36
-
panic(err)
36
+
return r, fmt.Errorf("Cannot connect to the Cider API, make sure Cider is launched and that the API is enabled")
37
37
}
38
38
39
39
if res.StatusCode != 200 {
40
40
b, err := io.ReadAll(res.Body)
41
41
if err != nil {
42
-
panic(err)
42
+
return r, err
43
43
}
44
-
panic(string(b))
44
+
return r, fmt.Errorf("An error occured : %s", b)
45
45
}
46
46
47
-
json.NewDecoder(res.Body).Decode(&r)
48
-
return r
47
+
err = json.NewDecoder(res.Body).Decode(&r)
48
+
if err != nil {
49
+
return r, err
50
+
}
51
+
52
+
return r, nil
49
53
}
50
54
51
-
func getInfos(song types.NowPlaying) types.MBRecord {
55
+
func getInfos(song types.NowPlaying) (types.MBRecord, error) {
56
+
r := types.MBRecord{}
57
+
52
58
req, err := http.NewRequest("GET", "https://musicbrainz.org/ws/2/release", nil)
53
59
if err != nil {
54
-
panic(err)
60
+
return r, err
55
61
}
56
62
57
63
query := fmt.Sprintf("recording:\"%s\" AND artist:\"%s\" AND date:\"%s\"", song.Info.Name, song.Info.ArtistName, song.Info.ReleaseDate)
···
66
72
67
73
res, err := http.DefaultClient.Do(req)
68
74
if err != nil {
69
-
panic(err)
75
+
return r, err
70
76
}
71
77
72
78
record := types.MBRecord{}
73
79
err = json.NewDecoder(res.Body).Decode(&record)
74
80
if err != nil {
75
-
panic(err)
81
+
return r, err
76
82
}
77
83
78
-
return record
84
+
return record, nil
79
85
}
80
86
81
87
func recordToTeal(records types.MBRecord, s types.NowPlaying) teal.AlphaFeedPlay {
···
126
132
}
127
133
128
134
type envData struct {
129
-
handle string
130
-
password string
131
135
ciderToken string
132
136
}
133
137
134
138
func getEnvData() envData {
135
139
return envData{
136
-
handle: os.Getenv("HANDLE"),
137
-
password: os.Getenv("PASSWORD"),
138
140
ciderToken: os.Getenv("CIDER_TOKEN"),
139
141
}
140
142
}
···
145
147
}
146
148
}
147
149
148
-
func (e envData) Login() (*client.APIClient, error) {
149
-
150
-
return client.LoginWithPassword(
151
-
context.Background(),
152
-
identity.DefaultDirectory(), syntax.AtIdentifier{Inner: syntax.Handle(e.handle)}, e.password, "", nil)
153
-
154
-
}
155
-
156
-
func createPlay(client *client.APIClient, playRecord teal.AlphaFeedPlay) atproto.RepoCreateRecord_Output {
150
+
func createPlay(client *client.APIClient, playRecord teal.AlphaFeedPlay) error {
157
151
entry := atproto.RepoCreateRecord_Input{
158
152
Collection: "fm.teal.alpha.feed.play",
159
153
Repo: string(*client.AccountDID),
···
161
155
}
162
156
163
157
a := atproto.RepoCreateRecord_Output{}
164
-
165
158
err := client.Post(context.Background(), "com.atproto.repo.createRecord", entry, &a)
166
159
if err != nil {
167
-
panic(err)
160
+
return err
168
161
}
169
162
170
-
return a
163
+
return nil
171
164
}
172
165
173
166
func main() {
174
167
ENV_DATA = getEnvData()
175
-
client, err := ENV_DATA.Login()
176
-
if err != nil {
177
-
panic(err)
168
+
169
+
authChan := make(chan *oauth.ClientSession)
170
+
go auth.StartServer(authChan)
171
+
session := <-authChan
172
+
if session == nil {
173
+
panic("Could not connect to ATProto")
178
174
}
175
+
client := session.APIClient()
179
176
177
+
// LOGIC
180
178
var lastPlaying string
181
179
for {
182
-
s := getCurrentSong()
183
-
if lastPlaying != s.Info.PlayParams.ID {
180
+
s, err := getCurrentSong()
181
+
if err != nil {
182
+
fmt.Fprintln(os.Stderr, err.Error())
183
+
} else if lastPlaying != s.Info.PlayParams.ID {
184
184
lastPlaying = s.Info.PlayParams.ID
185
-
r := getInfos(s)
186
-
t := recordToTeal(r, s)
185
+
r, err := getInfos(s)
187
186
188
-
createPlay(client, t)
187
+
if err == nil {
188
+
t := recordToTeal(r, s)
189
+
createPlay(client, t)
190
+
} else {
191
+
fmt.Fprintln(os.Stderr, err.Error())
192
+
}
189
193
}
190
194
time.Sleep(10 * time.Second)
191
195
}
+2
-3
readme.md
+2
-3
readme.md
···
11
11
## Environment Variables
12
12
13
13
- `HANDLE` : Your ATProto Handle [alice.bsky.social]
14
-
- `PASSWORD` : An APP Password for your ATProto Account
15
-
- `CIDER_TOKEN` : An APP_TOKEN from the Cider app [https://cider.sh/docs/client/rpc#authentication]
14
+
- `CIDER_TOKEN` : An APP_TOKEN from the Cider app (See the [Docs](https://cider.sh/docs/client/rpc#authentication))
16
15
17
16
## Running
18
17
19
18
```sh
20
19
$ go build .
21
-
$ HANDLE="" PASSWORD="" CIDER_TOKEN="" ./teal-cider
20
+
$ HANDLE="" CIDER_TOKEN="" ./teal-cider
22
21
```