+46
-3
bap-bsky.sh
+46
-3
bap-bsky.sh
···
2
2
# SPDX-License-Identifier: MIT
3
3
# bap-bsky.sh: the bash-atproto functions pertaining to Bluesky Social.
4
4
if [ -z "$bap_internalVersion" ]; then >&2 echo "bash-atproto not loaded?"; return 127; fi
5
-
if [ "$bap_internalVersion" != "3" ] || ! [ "$bap_internalMinorVer" -ge "2" ]; then >&2 echo "Incorrect bash-atproto version"; return 1; fi
5
+
if [ "$bap_internalVersion" != "3" ] || ! [ "$bap_internalMinorVer" -ge "3" ]; then >&2 echo "Incorrect bash-atproto version"; return 1; fi
6
6
7
7
bapBsky_internalVersion=1
8
-
bapBsky_internalMinorVer=1
8
+
bapBsky_internalMinorVer=2
9
9
10
10
function bapBskyErr () {
11
11
>&2 echo "bap-bsky: $*"
···
55
55
56
56
# (porn, sexual, nudity), graphic-media
57
57
function bapBsky_cyorAddLabel () {
58
+
bapBskyErr "warn: function ${FUNCNAME[0]} is deprecated. use bapBsky_cyorAddSelfLabels instead"
58
59
if [ -z "$2" ]; then bapBskyErr "error: Required argument missing"; return 1; fi
59
60
bapCYOR_str \$type com.atproto.label.defs#selfLabels .labels
60
61
# can you use multiple labels like this?
···
85
86
return 0
86
87
}
87
88
89
+
function bapBsky_cyorAddLangs () {
90
+
if [ -z "$1" ]; then bapBskyErr "error: Required arugment missing"; return 1; fi
91
+
bapCYOR_rem langs
92
+
local iter=0
93
+
while [ -n "$1" ]; do
94
+
bapCYOR_arr "$1" .langs.["$iter"] || return $?
95
+
((iter++))
96
+
# lexicon limit 3
97
+
if [ "$iter" -gt "2" ]; then break; fi
98
+
shift
99
+
done
100
+
return 0
101
+
}
102
+
103
+
function bapBsky_cyorAddTags () {
104
+
if [ -z "$1" ]; then bapBskyErr "error: Required arugment missing"; return 1; fi
105
+
bapCYOR_rem tags
106
+
local iter=0
107
+
while [ -n "$1" ]; do
108
+
bapCYOR_arr "$1" .tags.["$iter"] || return $?
109
+
((iter++))
110
+
# lexicon limit 8
111
+
if [ "$iter" -gt "7" ]; then break; fi
112
+
shift
113
+
done
114
+
return 0
115
+
}
116
+
117
+
function bapBsky_cyorAddSelfLabels () {
118
+
if [ -z "$1" ]; then bapBskyErr "error: Required argument missing"; return 1; fi
119
+
bapCYOR_str \$type com.atproto.label.defs#selfLabels .labels
120
+
bapCYOR_rem labels.values
121
+
local iter=0
122
+
while [ -n "$1" ]; do
123
+
bapCYOR_str val "$1" .labels.values.["$iter"]
124
+
((iter++))
125
+
shift
126
+
done
127
+
return 0
128
+
}
129
+
88
130
function bapBsky_submitPost () {
89
131
bapCYOR_str createdAt $(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)
90
132
bap_postRecord "$bap_cyorRecord" || return $?
···
98
140
if [ -z "$1" ]; then bapBskyErr "fatal: No argument given to post"; return 1; fi
99
141
bapBsky_cyorInit
100
142
bapCYOR_str text "$1"
101
-
if [ -n "$2" ]; then bapCYOR_add langs "[\"$2\"]"; fi
143
+
if [ -n "$2" ]; then bapBsky_cyorAddLangs $2; fi
102
144
bapBsky_submitPost || return $?
103
145
bapBskyEcho "Posted record at $uri"
104
146
return 0
···
178
220
179
221
function bapBsky_stubWarn () {
180
222
bapBskyErr "warn: function ${FUNCNAME[1]} was renamed. call $1 instead"
223
+
if [ "${FUNCNAME[1]}" != "bap_postToBluesky" ]; then bapBskyErr "warn: this compatibility stub is deprecated and will be removed in a future version"; fi
181
224
}
182
225
183
226
function bapCYOR_bskypost () {
+20
-6
bash-atproto.sh
+20
-6
bash-atproto.sh
···
1
1
#!/bin/bash
2
2
# SPDX-License-Identifier: MIT
3
3
bap_internalVersion=3
4
-
bap_internalMinorVer=2
4
+
bap_internalMinorVer=3
5
5
6
6
# you can change these
7
7
bap_plcDirectory=https://plc.directory
···
139
139
# for quotes
140
140
if [ -z "$1" ]; then baperr "nothing to add"; return 1; fi
141
141
if [ -z "$bap_cyorRecord" ]; then bap_cyorRecord="{}"; fi
142
-
bap_temp=$2
143
-
bap_cyorRecord=$(echo "$bap_cyorRecord" | jq -c "$3.[\"$1\"]=\"$bap_temp\"")
142
+
local bap_temp
143
+
bap_temp=$(echo "$bap_cyorRecord" | jq -c "$3.[\"$1\"]=\"$2\"") || return $?
144
+
bap_cyorRecord=$bap_temp
144
145
return $?
145
146
}
146
147
···
148
149
# for things that shouldn't be in quotes
149
150
if [ -z "$1" ]; then baperr "nothing to add"; return 1; fi
150
151
if [ -z "$bap_cyorRecord" ]; then bap_cyorRecord="{}"; fi
151
-
bap_temp=$2
152
-
bap_cyorRecord=$(echo "$bap_cyorRecord" | jq -c "$3.[\"$1\"]=$bap_temp")
152
+
local bap_temp
153
+
bap_temp=$(echo "$bap_cyorRecord" | jq -c "$3.[\"$1\"]=$2") || return $?
154
+
bap_cyorRecord=$bap_temp
155
+
return $?
156
+
}
157
+
158
+
function bapCYOR_arr () {
159
+
# arrays
160
+
if [ -z "$1" ]; then baperr "nothing to add"; return 1; fi
161
+
if [ -z "$bap_cyorRecord" ]; then bap_cyorRecord="{}"; fi
162
+
local bap_temp
163
+
bap_temp=$(echo "$bap_cyorRecord" | jq -c "$2=\"$1\"") || return $?
164
+
bap_cyorRecord=$bap_temp
153
165
return $?
154
166
}
155
167
156
168
function bapCYOR_rem () {
157
169
# doesn't handle special names atm
158
170
if [ -z "$1" ] || [ -z "$bap_cyorRecord" ]; then baperr "nothing to remove"; return 1; fi
159
-
bap_cyorRecord=$(echo $bap_cyorRecord | jq -c "del(.$1)")
171
+
local bap_temp
172
+
bap_temp=$(echo $bap_cyorRecord | jq -c "del(.$1)") || return $?
173
+
bap_cyorRecord=$bap_temp
160
174
return $?
161
175
}
162
176
+19
-4
docs/HOWTO.md
+19
-4
docs/HOWTO.md
···
29
29
30
30
This is the manual way to create a Bluesky post with bap-bsky. You can use `bapBsky_createPost`, `bapBsky_postImage` and `bapBsky_postVideo` for basic posts, but manually writing the JSON with the CYOR commands allows for much more flexibility.
31
31
32
+
To create a simple post in English:
33
+
32
34
1. `source bap-bsky.sh`
33
35
2. `bapBsky_cyorInit`
34
-
3. `bapCYOR_str text "It's my first post!" en`
35
-
4. `bapBsky_submitPost`
36
+
3. `bapCYOR_str text "It's my first post!"`
37
+
4. `bapBsky_cyorAddLangs en`
38
+
5. `bapBsky_submitPost`
39
+
40
+
### Adding languages
41
+
42
+
`bapBsky_cyorAddLangs` can add language tags to your post. You can specify up to 3 (per the lexicon rules), separating additional tags as separate parameters:
43
+
44
+
* `bapBsky_cyorAddLangs en ja pt` to mark a post as having English, Japanese and Portuguese.
36
45
37
46
### Adding an image
38
47
···
57
66
58
67
This can be done any time before submission, but ideally you'd do it after adding the embed.
59
68
60
-
1. `bapBsky_cyorAddLabel # <label>`
61
-
1. `#` is the label number, in most cases you will only need one. Like `bapBsky_cyorAddImage` it counts from zero.
69
+
1. `bapBsky_cyorAddSelfLabels <labels>`
70
+
1. You can specify multiple labels as separate parameters.
62
71
2. The official Bluesky app maps the self-labels with these names:
63
72
* Suggestive - `sexual`
64
73
* Nudity - `nudity`
···
72
81
* `bapBsky_cyorAddReply at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3l6ovsdood32z`
73
82
74
83
This will also fetch the appropriate root post if it hasn't been added already.
84
+
85
+
### Adding (hidden hash)tags
86
+
87
+
A little known feature of the Bluesky post lexicon is the ability to add hidden hashtags. These don't appear in the post body, but they still work for discovery and search just like normal hashtags that are added with a facet. You can add up to 8 (again, lexicon limit) tags to your post with `bapBsky_cyorAddTags`:
88
+
89
+
* `bapBsky_cyorAddTags Bluesky ATProto`
75
90
76
91
### Other things
77
92
+4
-6
docs/MISSING.md
+4
-6
docs/MISSING.md
···
3
3
## bap-bsky
4
4
5
5
* Communication with Lumi (Bluesky video service)
6
-
7
-
* Tags (the element, not the facet)
8
-
9
6
* External embeds
10
-
11
7
* Facets
12
-
13
-
* I'm not doing this lol
8
+
* Mentions
9
+
* URLs
10
+
* Hashtags
11
+
* All functions unrelated to creating posts (low priority)
14
12
15
13
## bap-sprk
16
14