AI agent skills related to using social media
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add prototype of `bluesky-open-app` script

+119
+53
atproto/xrpc.rkt
··· 1 + #lang racket/base 2 + 3 + 4 + (require racket/contract/base) 5 + 6 + 7 + (provide 8 + (contract-out 9 + [agent-xrpc-get 10 + (->* (string?) ((hash/c symbol? string?) #:service (or/c string? #false)) jsexpr?)])) 11 + 12 + 13 + (require json 14 + net/http-easy 15 + racket/string 16 + social-skills/atproto/agent-config 17 + social-skills/atproto/authenticate 18 + social-skills/atproto/lookup-pds 19 + social-skills/private/check-response-ok) 20 + 21 + 22 + ;@---------------------------------------------------------------------------------------------------- 23 + 24 + 25 + (define (agent-xrpc-get method-nsid [query-params (hash)] #:service [service #false]) 26 + (define pds-url (atproto-lookup-pds (agent-atproto-did))) 27 + (define jwt (atproto-authenticate (agent-atproto-did) (agent-atproto-app-password))) 28 + (define query-string 29 + (if (hash-empty? query-params) 30 + "" 31 + (string-join (for/list ([(k v) (in-hash query-params)]) 32 + (format "~a=~a" k v)) 33 + "," 34 + #:before-first "?"))) 35 + (define base-headers 36 + (hash 'content-type "application/json" 37 + 'authorization (format "Bearer ~a" jwt))) 38 + (define headers 39 + (if service 40 + (hash-set base-headers 'atproto-proxy service) 41 + base-headers)) 42 + (define response (get (format "~a/xrpc/~a~a" pds-url method-nsid query-string) #:headers headers)) 43 + (check-response-ok 'agent-xrpc-get response) 44 + (response-json response)) 45 + 46 + 47 + (module+ main 48 + (define agent-vars 49 + (make-environment-variables 50 + #"AGENT_ATPROTO_DID" #"did:plc:36zqqogbeg4i3nsqfkq64idw" 51 + #"AGENT_ATPROTO_APP_PASSWORD" #"/Users/jackfirth/.claude-social/app-password")) 52 + (parameterize ([current-environment-variables agent-vars]) 53 + (agent-xrpc-get "app.bsky.notification.listNotifications")))
+66
bluesky/open-app.rkt
··· 1 + #lang racket/base 2 + 3 + 4 + (require net/http-easy 5 + racket/list 6 + racket/string 7 + rebellion/streaming/reducer 8 + rebellion/streaming/transducer 9 + social-skills/atproto/agent-config 10 + social-skills/atproto/authenticate 11 + social-skills/atproto/lookup-pds 12 + social-skills/atproto/xrpc 13 + social-skills/private/check-response-ok) 14 + 15 + 16 + ;@---------------------------------------------------------------------------------------------------- 17 + 18 + 19 + (define (bluesky-open-app) 20 + (define agent-name (bluesky-lookup-name (agent-atproto-did) (agent-atproto-app-password))) 21 + (printf "You are ~a on Bluesky. Choose an action:\n" agent-name) 22 + (newline) 23 + (printf " - Open your notifications ~a(`open-notifictions`)\n" (unread-notifications-badge)) 24 + (printf " - Open your DMs ~a(`open-dms`)\n" (unread-dms-badge)) 25 + (printf " - Read your timeline (`read-timeline`)\n")) 26 + 27 + 28 + (define (bluesky-lookup-name user-did app-password-file) 29 + (define response (agent-xrpc-get "app.bsky.actor.getProfile" (hash 'actor user-did))) 30 + (define display-name (hash-ref response 'displayName #false)) 31 + (define handle (hash-ref response 'handle)) 32 + (if display-name 33 + (format "~a (@~a)" display-name handle) 34 + (format "@~a" handle))) 35 + 36 + 37 + (define (unread-notifications-badge) 38 + (define notifications (bluesky-list-notifications (agent-atproto-did))) 39 + (define unread-count (count (λ (notif) (not (hash-ref notif 'isRead))) notifications)) 40 + (if (zero? unread-count) 41 + "" 42 + (format "**[~a unread]** " unread-count))) 43 + 44 + 45 + (define (bluesky-list-notifications user-did) 46 + (hash-ref (agent-xrpc-get "app.bsky.notification.listNotifications") 'notifications)) 47 + 48 + 49 + (define (unread-dms-badge) 50 + (define list-convos-response 51 + (agent-xrpc-get "chat.bsky.convo.listConvos" (hash 'readState "unread") 52 + #:service "did:web:api.bsky.chat#bsky_chat")) 53 + (define unread-convo-count (length (hash-ref list-convos-response 'convos))) 54 + (if (zero? unread-convo-count) 55 + "" 56 + (format "**[~a unread]** " unread-convo-count))) 57 + 58 + 59 + (module+ main 60 + ; TODO: replace manual main code with racket/cmdline tool 61 + (define agent-vars 62 + (make-environment-variables 63 + #"AGENT_ATPROTO_DID" #"did:plc:36zqqogbeg4i3nsqfkq64idw" 64 + #"AGENT_ATPROTO_APP_PASSWORD" #"/Users/jackfirth/.claude-social/app-password")) 65 + (parameterize ([current-environment-variables agent-vars]) 66 + (bluesky-open-app)))