#!/bin/env tclsh
# A rough copy of <https://github.com/bluesky-social/feed-generator/blob/main/scripts/publishFeedGen.ts>
package require json
package require json::write
package require http
package require tls
::http::register https 443 ::tls::socket
cd [file dirname [file dirname [dict get [info frame [info frame]] file]]]
source lib/prompt.tcl
source lib/atpagent.tcl
input "Enter your bsky handle:" conf(handle)
paswd "Enter your Bluesky password (preferably an App Password):" conf(password)
input "Optionally, enter a custom PDS service to sign in with:" conf(service) https://bsky.social
input "Enter the host where the feed is available:" conf(feedHost)
input "Enter a short name or the record. This will be shown in the feed's URL:" conf(recordName)
input "Enter a display name for your feed:" conf(displayName)
inopt "Optionally, enter a brief description of your feed:" conf(description)
inopt "Optionally, enter a local path to an avatar that will be used for the feed:" conf(avatar)
atpagent agent $conf(service)
agent login $conf(handle) $conf(password)
if {$conf(description) == ""} {
set description null
} else {
set description [::json::write string $conf(description)]
}
set avatarRef {}
if {$conf(avatar) != {}} {
switch -glob -- $conf(avatar) {
*.png {
set mime image/png
}
*.{jpg,jpeg} {
set mime image/jpeg
}
default {
return -code error "expected png or jpeg avatar"
}
}
set fd [open $conf(avatar) r]
fconfigure $fd -translation binary
set avatar [read $fd]
close $fd
unset fd
lassign [agent xrpc com.atproto.repo.uploadBlob -type $mime $avatar] av_ncode av_data
puts "upload: $av_data"
if {$av_ncode != 200} { return -code error "got $av_ncode uploading avatar!\n$av_data" }
set avatarRef [list avatar [::json::write string $av_data]]
puts $avatarRef
}
lassign [agent xrpc com.atproto.repo.putRecord \
repo [::json::write string [agent state did]] \
collection {"app.bsky.feed.generator"} \
rkey [::json::write string $conf(recordName)] \
record [::json::write object \
did [::json::write string did:web:$conf(feedHost)] \
displayName [::json::write string $conf(displayName)] \
description $description \
createdAt [::json::write string [clock format [clock seconds] -format "%Y-%m-%dT%T.000Z"]] \
{*}$avatarRef]] pr_ncode pr_data
if {$pr_ncode != 200} { return -code error "got $pr_ncode putting feed record!\n$pr_data" }
puts "All done 🎉"