BlueSky: nodejs でOGP情報を埋め込む形の投稿法

April 19, 2025 – 5:54 pm

BlueSky にOGP情報を組み込んで投稿する方法をnodejsで作ってみた。

sampleとして、以下の形式で投稿:

const source = require('./source.js');

url = 'https://www.tokyo-np.co.jp/article/399555';
my_text ='リタイアした学者の仲良しクラブ化した学術会議になんの意義があるのか?';
source.ogp_out(url, my_text);

ここでは、東京新聞の記事にちょっとしたコメントを書いたものを添付している。
BlueSkyへの投稿画面は以下:

リタイアした学者の仲良しクラブ化した学術会議になんの意義があるのか?
https://www.tokyo-np.co.jp/article/399555

[image or embed]

— YamasNet (@yamasnet.com) 2025年4月19日 15:58

source.jsを以下に添付:

async function ogp_out(url, my_text) {

    const { BskyAgent } = require('@atproto/api');
    const agent = new BskyAgent({ service: "https://bsky.social" })

    require('dotenv').config();
    const { parse } = require('node-html-parser');
   
    await agent.login({
     identifier: process.env.BLUESKY_USERNAME,
     password: process.env.BLUESKY_PASSWORD
     });
    
    const resp = await fetch(url);
    const html = parse(await resp.text());
    const title = html.querySelector("title")?.innerText;
    const ogpText = html
        .querySelector("meta[name='description']")
        ?.getAttribute("content");
    const ogpImg = html
        .querySelector("meta[property='og:image']")
        ?.getAttribute("content");

    const encoder = new TextEncoder();
    //const plainText = `茨城の気温: ${temp} `.slice(0, 299);
    //const plainText = `羽田が便利になりそう!\n`.slice(0,299);
    const plainText = `${my_text}\n`.slice(0,299);
    const linkStart = encoder.encode(plainText).byteLength;
    const linkEnd = linkStart + encoder.encode(url).byteLength;
    const textParams = `${plainText}${url}`;
    const facetsParams= [
      {
        index: {
          byteStart: linkStart,
          byteEnd: linkEnd,
        },
        features: [{ $type: "app.bsky.richtext.facet#link", uri: url }],
      },
    ];

    const blob = await fetch(`${ogpImg}`);
    const buffer = await blob.arrayBuffer();
    const response = await agent.uploadBlob(new Uint8Array(buffer), {
      encoding: "image/jpeg",
    });

    const embedParams = {
      $type: "app.bsky.embed.external",
      external: {
        uri: url,
        thumb: {
          $type: "blob",
          ref: {
            $link: response.data.blob.ref.toString(),
          },
          mimeType: response.data.blob.mimeType,
          size: response.data.blob.size,
        },
        title: title,
        description: ogpText,
      },
    };

    const postParams = {
      $type: "app.bsky.feed.post",
      text: textParams,
      facets: facetsParams,
      embed: embedParams,
      createdAt: new Date().toISOString(),
    };
    
    await agent.post(postParams);

    console.log("Just posted!");
};

module.exports = {
    ogp_out,
};

参考:BlueskyでシンプルなBotを作る


Post a Comment