もくじ
画像を添付する
画像を添付する場合は当然画像のアップロード処理が必要になるのでPostするときのJSONを以下のように変更する。画像は最大4枚まで送れるのでimages
は配列。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "repo": "DIDを指定", "collection": "app.bsky.feed.post", "record": { "text": "投稿文", "createdAt": "ISO 8601フォーマットの投稿日時", "facets": [], "embed": { "$type": "app.bsky.embed.images", "images": [], } } } |
ところが、com.atproto.repo.createRecord
が受け付けているContent-Typeはapplication/json
なのでこれで直接バイナリデータは送れない。
実際にrecord.embed.images
に設定するべきデータは以下のようになっていて(alt
とaspectRatio
は任意)、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "image": { "$type": "blob", "ref": { "$link": "アップロードした画像の参照情報" }, "mimeType": "画像のMIMEタイプ", "size": 画像のファイルサイズ }, "alt": "文字列", "aspectRatio": { "width": 幅, "height": 高さ } } |
参照情報って何?と思うけど要するに「先に画像をアップロードして、その戻り値として参照情報(文字列型)を受け取れるので、それを設定する」という流れで処理をしなければならない。
なのでまずはcom.atproto.repo.createRecord
で送る前にcom.atproto.repo.uploadBlob
を使用して画像をアップロードする。
※ 以前は以下の仕様でしたが、2024/2/22頃から前述の新仕様でないとエラーになるように変更されたようです。
1 2 3 4 5 6 7 |
{ "image": { "cid": "アップロードした画像の参照情報", "mimeType": "画像のMIMEタイプ" }, "alt": "文字列" } |
画像をアップロードする
今回作成するWebサービスは外部連携を想定していて、他サービスからの情報を受け取る際は画像に関してはURLで渡されてくるはずなので、「画像のURLを受け取ってそれをBLOBとして取得し、uploadBlob
に送信する」ような処理にした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
let imagesURLs = ["画像URL1", "画像URL2", "画像URL3", "画像URL4"] let url = "https://bsky.social/xrpc/com.atproto.repo.uploadBlob"; let imagesArr: Object[] = []; if (imagesURLs != null && 0 < imagesURLs.length) { for (let i = 0; i < imagesURLs.length && i < 4; ++i) { let imgURL = imagesURLs[i]; let blob = UrlFetchApp.fetch(imageURL).getBlob(); const options: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions & { method: GoogleAppsScript.URL_Fetch.HttpMethod } = { "method": "post", "headers": { "Authorization": `Bearer ${accessJwt}` }, "payload": blob, }; let response = UrlFetchApp.fetch(url, options); let responseJSON = JSON.parse(response.getContentText()); imagesArr.push({ "image": { "$type": "blob", "ref": { "$link": responseJSON.blob.ref.$link }, "mimeType": responseJSON.blob.mimeType, "size": responseJSON.blob.size }, "alt": "" }); } } |
投稿する
取得した画像参照情報をJSONに加えてPostする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
{ "repo": did, "collection": "app.bsky.feed.post", "record": { "text": "New blog posts: https://nigauri.me/everyone-in-2023/", "createdAt": (new Date()).toISOString(), "facets": [ { "index": { "byteStart": 16, "byteEnd": 52 }, "features": [ { "$type": "app.bsky.richtext.facet#link", "uri": "https://nigauri.me/everyone-in-2023/" } ] } ], "embed": { "$type": "app.bsky.embed.images", "images": [ { "image": { "$type": "blob", "ref": { "$link": "アップロードした画像の参照情報" }, "mimeType": "画像のMIMEタイプ", "size": 画像のファイルサイズ }, "alt": "" } ] }, } } |
リンクカードを設定する
リンクカードを設定する場合は以下のように…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
{ "repo": "DIDを指定", "collection": "app.bsky.feed.post", "record": { "text": "投稿文", "createdAt": "ISO 8601フォーマットの投稿日時", "facets": [], "embed": { "$type": "app.bsky.embed.external", "external": { "uri": "URL", "title": "タイトル", "description": "説明文", "thumb": { "image": { "$type": "blob", "ref": { "$link": "アップロードした画像の参照情報" }, "mimeType": "画像のMIMEタイプ", "size": 画像のファイルサイズ }, "alt": "文字列" } } } } } |
あれ?record.embed
は配列じゃないんだけど…画像とリンクカードを同時に設定したい場合はどうすれば?
答えは画像とリンクカードを同時には指定できない。なのでどっちかにしてください。
サムネイル画像のアップロード方法とかは普通の画像添付のやつと一緒。