BotKit 0.2.0 Released

We're pleased to announce the release of BotKit 0.2.0! For those new to our project, #BotKit is a #TypeScript framework for creating standalone #ActivityPub bots that can interact with Mastodon, Misskey, and other #fediverse platforms without the constraints of these existing platforms.

This release marks an important step in our journey to make fediverse bot development more accessible and powerful, introducing several features that our community has been requesting.

The Journey to Better Bot Interactions

In building BotKit, we've always focused on making bots more expressive and interactive. With version 0.2.0, we're taking this to the next level by bringing the social aspects of the fediverse to your bots.

Expressing Your Bot's Personality with Custom Emojis

One of the most requested features has been #custom_emoji support. Now your bots can truly express their personality with unique visuals that make their messages stand out.

// Define custom emojis for your bot const emojis = bot.addCustomEmojis({ botkit: { file: `${import.meta.dirname}/images/botkit.png`, type: "image/png" }, fedify: { url: "https://fedify.dev/logo.png", type: "image/png" } }); // Use these custom emojis in your messages await session.publish( text`BotKit ${customEmoji(emojis.botkit)} is powered by Fedify ${customEmoji(emojis.fedify)}` );

With this new API, you can:

Engaging Through Reactions

Communication isn't just about posting messagesโ€”it's also about responding to others. The new reaction system creates natural interaction points between your bot and its followers:

// React to a message with a standard Unicode emoji await message.react(emoji`๐Ÿ‘`); // Or use one of your custom emojis as a reaction await message.react(emojis.botkit); // Create a responsive bot that acknowledges reactions bot.onReact = async (session, reaction) => { await session.publish( text`Thanks for reacting with ${reaction.emoji} to my message, ${reaction.actor}!`, { visibility: "direct" } ); };

This feature allows your bot to:

Conversations Through Quotes

Discussions often involve referencing what others have said. Our new #quote support enables more cohesive conversation threads:

// Quote another message in your bot's post await session.publish( text`Responding to this interesting point...`, { quoteTarget: originalMessage } ); // Handle when users quote your bot's messages bot.onQuote = async (session, quoteMessage) => { await session.publish( text`Thanks for sharing my thoughts, ${quoteMessage.actor}!`, { visibility: "direct" } ); };

With quote support, your bot can:

Visual Enhancements

Because communication is visual too, we've improved how your bot presents itself:

  • Image attachments now properly display in the web interface
  • Your bot's content looks better and provides a richer experience

Behind the Scenes: Enhanced Activity Propagation

We've also improved how activities propagate through the fediverse:

  • More precise propagation of replies, shares, updates, and deletes
  • Activities are now properly sent to the original message authors

These improvements ensure your bot's interactions are consistent and reliable across different fediverse platforms.

Taking Your First Steps with BotKit 0.2.0

Ready to experience these new features? BotKit 0.2.0 is available on JSR and can be installed with a simple command:

deno add jsr:@fedify/botkit@0.2.0

Since BotKit uses the Temporal API (which is still evolving in JavaScript), remember to enable it in your deno.json:

{ "imports": { "@fedify/botkit": "jsr:@fedify/botkit@0.2.0" }, "unstable": ["temporal"] }

With these simple steps, you're ready to create or upgrade your fediverse bot with our latest features.

Looking Forward

BotKit 0.2.0 represents our ongoing commitment to making fediverse bot development accessible, powerful, and enjoyable. We believe these new features will help your bots become more engaging and interactive members of the fediverse community.

For complete docs and more examples, visit our docs site.

Thank you to everyone who contributed to this release through feedback, feature requests, and code contributions. The BotKit community continues to grow, and we're excited to see what you'll create!

BotKit is powered by Fedify, a lower-level framework for creating ActivityPub server applications.

#fedidev #emoji_reaction

BotKit by Fedify

A framework for creating your ActivityPub bots

BotKit 0.2.0 ๋ฆด๋ฆฌ์Šค

BotKit 0.2.0 ๋ฒ„์ „์ด ๋ฆด๋ฆฌ์Šค๋˜์—ˆ์Šต๋‹ˆ๋‹ค! BotKit์„ ์ฒ˜์Œ ์ ‘ํ•˜์‹œ๋Š” ๋ถ„๋“ค์„ ์œ„ํ•ด ๊ฐ„๋‹จํžˆ ์†Œ๊ฐœํ•˜์ž๋ฉด, BotKit์€ TypeScript๋กœ ๊ฐœ๋ฐœ๋œ ๋…๋ฆฝํ˜• #ActivityPub ๋ด‡ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. Mastodon, Misskey ๋“ฑ ๋‹ค์–‘ํ•œ #์—ฐํ•ฉ์šฐ์ฃผ(#fediverse) ํ”Œ๋žซํผ๊ณผ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ธฐ์กด ํ”Œ๋žซํผ์˜ ์ œ์•ฝ์—์„œ ๋ฒ—์–ด๋‚˜ ์ž์œ ๋กญ๊ฒŒ ๋ด‡์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ ๋ฆด๋ฆฌ์Šค๋Š” ์—ฐํ•ฉ์šฐ์ฃผ ๋ด‡ ๊ฐœ๋ฐœ์„ ๋” ์‰ฝ๊ณ  ๊ฐ•๋ ฅํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์—ฌ์ •์—์„œ ์ค‘์š”ํ•œ ๋ฐœ๊ฑธ์Œ์ž…๋‹ˆ๋‹ค. ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ์š”์ฒญํ•ด ์™”๋˜ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ๋“ค์„ ์ƒˆ๋กญ๊ฒŒ ์„ ๋ณด์ž…๋‹ˆ๋‹ค.

๋” ๋‚˜์€ ๋ด‡ ์ƒํ˜ธ์ž‘์šฉ์„ ์œ„ํ•œ ์—ฌ์ •

BotKit์„ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ์šฐ๋ฆฌ๋Š” ํ•ญ์ƒ ๋ด‡์ด ๋” ํ‘œํ˜„๋ ฅ ์žˆ๊ณ  ์ƒํ˜ธ์ž‘์šฉ์ด ํ’๋ถ€ํ•˜๋„๋ก ๋งŒ๋“œ๋Š” ๋ฐ ์ง‘์ค‘ํ•ด ์™”์Šต๋‹ˆ๋‹ค. 0.2.0 ๋ฒ„์ „์—์„œ๋Š” ์—ฐํ•ฉ์šฐ์ฃผ์˜ ์‚ฌํšŒ์  ์ธก๋ฉด์„ ๋ด‡์— ์ ‘๋ชฉ์‹œ์ผœ ํ•œ ๋‹จ๊ณ„ ๋” ๋ฐœ์ „์‹œ์ผฐ์Šต๋‹ˆ๋‹ค.

์ปค์Šคํ…€ ์—๋ชจ์ง€๋กœ ๋ด‡์˜ ๊ฐœ์„ฑ ํ‘œํ˜„ํ•˜๊ธฐ

๊ฐ€์žฅ ๋งŽ์ด ์š”์ฒญ๋ฐ›์•˜๋˜ ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๊ฐ€ #์ปค์Šคํ…€_์—๋ชจ์ง€ ์ง€์›์ž…๋‹ˆ๋‹ค. ์ด์ œ ๋ด‡์€ ๋…ํŠนํ•œ ์‹œ๊ฐ์  ์š”์†Œ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋‹๋ณด์ด๊ฒŒ ํ•˜๋ฉฐ ์ž์‹ ๋งŒ์˜ ๊ฐœ์„ฑ์„ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// ๋ด‡์˜ ์ปค์Šคํ…€ ์—๋ชจ์ง€ ์ •์˜ํ•˜๊ธฐ const emojis = bot.addCustomEmojis({ botkit: { file: `${import.meta.dirname}/images/botkit.png`, type: "image/png" }, fedify: { url: "https://fedify.dev/logo.png", type: "image/png" } }); // ๋ฉ”์‹œ์ง€์— ์ปค์Šคํ…€ ์—๋ชจ์ง€ ์‚ฌ์šฉํ•˜๊ธฐ await session.publish( text`BotKit ${customEmoji(emojis.botkit)}์€ Fedify ${customEmoji(emojis.fedify)}์˜ ์ง€์›์„ ๋ฐ›์Šต๋‹ˆ๋‹ค` );

์ด ์ƒˆ๋กœ์šด API๋ฅผ ํ†ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘์„ ํ†ตํ•œ ์†Œํ†ต

์†Œํ†ต์€ ๋‹จ์ˆœํžˆ ๋ฉ”์‹œ์ง€๋ฅผ ๊ฒŒ์‹œํ•˜๋Š” ๊ฒƒ๋งŒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‚ฌ๋žŒ์˜ ๋ฉ”์‹œ์ง€์— ๋ฐ˜์‘ํ•˜๋Š” ๊ฒƒ๋„ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๋ฐ˜์‘ ์‹œ์Šคํ…œ์€ ๋ด‡๊ณผ ํŒ”๋กœ์›Œ ์‚ฌ์ด์— ์ž์—ฐ์Šค๋Ÿฌ์šด ์ƒํ˜ธ์ž‘์šฉ ์ง€์ ์„ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

// ํ‘œ์ค€ ์œ ๋‹ˆ์ฝ”๋“œ ์—๋ชจ์ง€๋กœ ๋ฉ”์‹œ์ง€์— ๋ฐ˜์‘ํ•˜๊ธฐ await message.react(emoji`๐Ÿ‘`); // ๋˜๋Š” ์ •์˜ํ•œ ์ปค์Šคํ…€ ์—๋ชจ์ง€๋กœ ๋ฐ˜์‘ํ•˜๊ธฐ await message.react(emojis.botkit); // ๋ฐ˜์‘์„ ์ธ์‹ํ•˜๊ณ  ์‘๋‹ตํ•˜๋Š” ๋ด‡ ๋งŒ๋“ค๊ธฐ bot.onReact = async (session, reaction) => { await session.publish( text`${reaction.actor}๋‹˜, ์ œ ๋ฉ”์‹œ์ง€์— ${reaction.emoji} ๋ฐ˜์‘์„ ๋‚จ๊ฒจ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!`, { visibility: "direct" } ); };

์ด ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ๋ด‡์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Message.react()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์œ ๋‹ˆ์ฝ”๋“œ ์—๋ชจ์ง€๋กœ ๋ฉ”์‹œ์ง€์— ๋ฐ˜์‘ํ•˜๊ธฐ
  • ์ •์˜ํ•œ ์ปค์Šคํ…€ ์—๋ชจ์ง€๋กœ ๋ฐ˜์‘ํ•˜๊ธฐ
  • Bot.onReact์™€ Bot.onUnreact ํ•ธ๋“ค๋Ÿฌ๋กœ ๋ฐ˜์‘ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌํ•˜๊ธฐ

์ธ์šฉ์„ ํ†ตํ•œ ๋Œ€ํ™”

ํ† ๋ก ์—์„œ๋Š” ์ข…์ข… ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๋งํ•œ ๋‚ด์šฉ์„ ์ฐธ์กฐํ•ด์•ผ ํ•  ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด #์ธ์šฉ ๊ธฐ๋Šฅ์€ ๋” ์‘์ง‘๋ ฅ ์žˆ๋Š” ๋Œ€ํ™” ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

// ๋ด‡์˜ ๊ฒŒ์‹œ๋ฌผ์—์„œ ๋‹ค๋ฅธ ๋ฉ”์‹œ์ง€ ์ธ์šฉํ•˜๊ธฐ await session.publish( text`์ด ํฅ๋ฏธ๋กœ์šด ๊ด€์ ์— ๋Œ€ํ•œ ๋‹ต๋ณ€์ž…๋‹ˆ๋‹ค...`, { quoteTarget: originalMessage } ); // ์‚ฌ์šฉ์ž๊ฐ€ ๋ด‡์˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ธ์šฉํ•  ๋•Œ ์ฒ˜๋ฆฌํ•˜๊ธฐ bot.onQuote = async (session, quoteMessage) => { await session.publish( text`${quoteMessage.actor}๋‹˜, ์ œ ์ƒ๊ฐ์„ ๊ณต์œ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!`, { visibility: "direct" } ); };

์ธ์šฉ ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ๋ด‡์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • quoteTarget ์˜ต์…˜์œผ๋กœ ๋ฉ”์‹œ์ง€ ์ธ์šฉํ•˜๊ธฐ
  • Message.quoteTarget์„ ํ†ตํ•ด ์ธ์šฉ๋œ ๋ฉ”์‹œ์ง€์— ์ ‘๊ทผํ•˜๊ธฐ
  • ์ƒˆ๋กœ์šด Bot.onQuote ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋กœ ์ธ์šฉ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌํ•˜๊ธฐ

์‹œ๊ฐ์  ๊ฐœ์„ 

์†Œํ†ต์€ ์‹œ๊ฐ์ ์ธ ์š”์†Œ๋„ ์ค‘์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ด‡์˜ ํ‘œํ˜„ ๋ฐฉ์‹์„ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ์›น ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์ด๋ฏธ์ง€ ์ฒจ๋ถ€ํŒŒ์ผ์ด ์ œ๋Œ€๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค
  • ๋ด‡์˜ ์ฝ˜ํ…์ธ ๊ฐ€ ๋” ๋ณด๊ธฐ ์ข‹์•„์ง€๊ณ  ํ’๋ถ€ํ•œ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค

๋‚ด๋ถ€ ๊ฐœ์„ : ํ–ฅ์ƒ๋œ ์•กํ‹ฐ๋น„ํ‹ฐ ์ „ํŒŒ

์—ฐํ•ฉ์šฐ์ฃผ์—์„œ ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ์ „ํŒŒ๋˜๋Š” ๋ฐฉ์‹๋„ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ๋‹ต๊ธ€, ๊ณต์œ , ์—…๋ฐ์ดํŠธ, ์‚ญ์ œ์˜ ๋” ์ •ํ™•ํ•œ ์ „ํŒŒ
  • ์›๋ณธ ๋ฉ”์‹œ์ง€ ์ž‘์„ฑ์ž์—๊ฒŒ ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ์ œ๋Œ€๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค

์ด๋Ÿฌํ•œ ๊ฐœ์„  ์‚ฌํ•ญ์€ ๋‹ค์–‘ํ•œ ์—ฐํ•ฉ์šฐ์ฃผ ํ”Œ๋žซํผ์—์„œ ๋ด‡์˜ ์ƒํ˜ธ์ž‘์šฉ์ด ์ผ๊ด€๋˜๊ณ  ์•ˆ์ •์ ์œผ๋กœ ์ด๋ฃจ์–ด์ง€๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

BotKit 0.2.0์œผ๋กœ ์ฒซ ๊ฑธ์Œ ๋–ผ๊ธฐ

์ด๋Ÿฌํ•œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ๊ฒฝํ—˜ํ•ด ๋ณด๊ณ  ์‹ถ์œผ์‹ ๊ฐ€์š”? BotKit 0.2.0์€ JSR์—์„œ ๋ฐ›์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฐ„๋‹จํ•œ ๋ช…๋ น์–ด๋กœ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

deno add jsr:@fedify/botkit@0.2.0

BotKit์€ Temporal API(JavaScript์—์„œ ์•„์ง ์‹œ๋ฒ”์ ์ธ ๊ธฐ๋Šฅ)๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ deno.json์—์„œ ์ด๋ฅผ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

{ "imports": { "@fedify/botkit": "jsr:@fedify/botkit@0.2.0" }, "unstable": ["temporal"] }

์ด ๊ฐ„๋‹จํ•œ ๋‹จ๊ณ„๋ฅผ ํ†ตํ•ด ์ตœ์‹  ๊ธฐ๋Šฅ์œผ๋กœ ์—ฐํ•ฉ์šฐ์ฃผ ๋ด‡์„ ๋งŒ๋“ค๊ฑฐ๋‚˜ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ค€๋น„๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์•ž์œผ๋กœ์˜ ์ „๋ง

BotKit 0.2.0์€ ์—ฐํ•ฉ์šฐ์ฃผ ๋ด‡ ๊ฐœ๋ฐœ์„ ์ ‘๊ทผํ•˜๊ธฐ ์‰ฝ๊ณ , ๊ฐ•๋ ฅํ•˜๋ฉฐ, ์ฆ๊ฒ๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์šฐ๋ฆฌ์˜ ์ง€์†์ ์ธ ๋…ธ๋ ฅ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์ด ์—ฌ๋Ÿฌ๋ถ„์˜ ๋ด‡์ด ์—ฐํ•ฉ์šฐ์ฃผ ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ๋” ๋งค๋ ฅ์ ์ด๊ณ  ์ƒํ˜ธ์ž‘์šฉ์ด ํ’๋ถ€ํ•œ ๊ตฌ์„ฑ์›์ด ๋˜๋Š” ๋ฐ ๋„์›€์ด ๋  ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์Šต๋‹ˆ๋‹ค.

์ „์ฒด ๋ฌธ์„œ์™€ ๋” ๋งŽ์€ ์˜ˆ์ œ๋Š” ์ €ํฌ ๋ฌธ์„œ ์‚ฌ์ดํŠธ์—์„œ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”ผ๋“œ๋ฐฑ, ๊ธฐ๋Šฅ ์š”์ฒญ, ์ฝ”๋“œ ๊ธฐ์—ฌ๋ฅผ ํ†ตํ•ด ์ด๋ฒˆ ๋ฆด๋ฆฌ์Šค์— ๋„์›€์„ ์ฃผ์‹  ๋ชจ๋“  ๋ถ„๋“ค๊ป˜ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. BotKit ์ปค๋ฎค๋‹ˆํ‹ฐ๋Š” ๊ณ„์† ์„ฑ์žฅํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์—ฌ๋Ÿฌ๋ถ„์ด ๋งŒ๋“ค์–ด๋‚ผ ์ž‘ํ’ˆ๋“ค์„ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค!

BotKit์€ ActivityPub ์„œ๋ฒ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ํ•˜์œ„ ๋ ˆ๋ฒจ ํ”„๋ ˆ์ž„์›Œํฌ์ธ Fedify์˜ ์ง€์›์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

#fedidev #์ปค๋ชจ์ง€ #์ปค์Šคํ…€_์ด๋ชจ์ง€ #์—๋ชจ์ง€_๋ฐ˜์‘ #์ด๋ชจ์ง€_๋ฐ˜์‘ #์—๋ชจ์ง€_๋ฆฌ์•ก์…˜ #์ด๋ชจ์ง€_๋ฆฌ์•ก์…˜

BotKit by Fedify

A framework for creating your ActivityPub bots

BotKit 0.2.0ใฎใƒชใƒชใƒผใ‚น

BotKit 0.2.0ใ‚’ใƒชใƒชใƒผใ‚นใ—ใพใ—ใŸ๏ผBotKitใ‚’ๅˆใ‚ใฆ็Ÿฅใ‚‹ๆ–นใฎใŸใ‚ใซ็ฐกๅ˜ใซ่ชฌๆ˜Žใ™ใ‚‹ใจใ€BotKitใฏTypeScriptใง้–‹็™บใ•ใ‚ŒใŸใ‚นใ‚ฟใƒณใƒ‰ใ‚ขใƒญใƒณใฎActivityPubใƒœใƒƒใƒˆใƒ•ใƒฌใƒผใƒ ใƒฏใƒผใ‚ฏใงใ™ใ€‚Mastodonใ€Misskeyใชใฉใ•ใพใ–ใพใชใƒ•ใ‚งใƒ‡ใ‚ฃใƒใƒผใ‚น๏ผˆ#fediverse๏ผ‰ใฎใƒ—ใƒฉใƒƒใƒˆใƒ•ใ‚ฉใƒผใƒ ใจ้€ฃๆบใงใใ€ๆ—ขๅญ˜ใƒ—ใƒฉใƒƒใƒˆใƒ•ใ‚ฉใƒผใƒ ใฎๅˆถ็ด„ใชใ—ใซ่‡ช็”ฑใซใƒœใƒƒใƒˆใ‚’ไฝœๆˆใงใใพใ™ใ€‚

ใ“ใฎใƒชใƒชใƒผใ‚นใฏใ€ใƒ•ใ‚งใƒ‡ใ‚ฃใƒใƒผใ‚นใซใŠใ‘ใ‚‹ใƒœใƒƒใƒˆ้–‹็™บใ‚’ใ‚ˆใ‚Š็ฐกๅ˜ใงๅผทๅŠ›ใซใ™ใ‚‹ใŸใ‚ใฎๆ—…ใฎ้‡่ฆใชไธ€ๆญฉใงใ‚ใ‚Šใ€ใ‚ณใƒŸใƒฅใƒ‹ใƒ†ใ‚ฃใ‹ใ‚‰่ฆๆœ›ใฎใ‚ใฃใŸๆฉŸ่ƒฝใ‚’ๅคšๆ•ฐๅฐŽๅ…ฅใ—ใฆใ„ใพใ™ใ€‚

ใ‚ˆใ‚Š่‰ฏใ„ใƒœใƒƒใƒˆใ‚คใƒณใ‚ฟใƒฉใ‚ฏใ‚ทใƒงใƒณใธใฎๆ—…

BotKitใฎ้–‹็™บใซใŠใ„ใฆใ€็งใŸใกใฏๅธธใซใƒœใƒƒใƒˆใ‚’ใ‚ˆใ‚Š่กจ็พๅŠ›่ฑŠใ‹ใงใ‚คใƒณใ‚ฟใƒฉใ‚ฏใƒ†ใ‚ฃใƒ–ใซใ™ใ‚‹ใ“ใจใซ็„ฆ็‚นใ‚’ๅฝ“ใฆใฆใใพใ—ใŸใ€‚ใƒใƒผใ‚ธใƒงใƒณ0.2.0ใงใฏใ€ใƒ•ใ‚งใƒ‡ใ‚ฃใƒใƒผใ‚นใฎ็คพไผš็š„ๅด้ขใ‚’ใƒœใƒƒใƒˆใซๅ–ใ‚Šๅ…ฅใ‚Œใ‚‹ใ“ใจใงใ€ใ•ใ‚‰ใซไธ€ๆญฉๅ‰้€ฒใ—ใพใ—ใŸใ€‚

ใ‚ซใ‚นใ‚ฟใƒ ็ตตๆ–‡ๅญ—ใงใƒœใƒƒใƒˆใฎๅ€‹ๆ€งใ‚’่กจ็พ

ๆœ€ใ‚‚่ฆๆœ›ใฎๅคšใ‹ใฃใŸๆฉŸ่ƒฝใฎไธ€ใคใŒใ‚ซใ‚นใ‚ฟใƒ ็ตตๆ–‡ๅญ—ใฎใ‚ตใƒใƒผใƒˆใงใ™ใ€‚ใ“ใ‚Œใซใ‚ˆใ‚Šใ€ใƒœใƒƒใƒˆใฏ็‹ฌ่‡ชใฎ่ฆ–่ฆš่ฆ็ด ใงใƒกใƒƒใ‚ปใƒผใ‚ธใ‚’็›ฎ็ซ‹ใŸใ›ใ€่‡ชๅˆ†ใ ใ‘ใฎๅ€‹ๆ€งใ‚’่กจ็พใงใใ‚‹ใ‚ˆใ†ใซใชใ‚Šใพใ—ใŸใ€‚

// ใƒœใƒƒใƒˆ็”จใฎใ‚ซใ‚นใ‚ฟใƒ ็ตตๆ–‡ๅญ—ใ‚’ๅฎš็พฉ const emojis = bot.addCustomEmojis({ botkit: { file: `${import.meta.dirname}/images/botkit.png`, type: "image/png" }, fedify: { url: "https://fedify.dev/logo.png", type: "image/png" } }); // ใƒกใƒƒใ‚ปใƒผใ‚ธใซใ‚ซใ‚นใ‚ฟใƒ ็ตตๆ–‡ๅญ—ใ‚’ไฝฟ็”จ await session.publish( text`BotKit ${customEmoji(emojis.botkit)}ใฏใ€Fedify ${customEmoji(emojis.fedify)}ใซใ‚ˆใฃใฆๆ”ฏใˆใ‚‰ใ‚Œใฆใ„ใพใ™` );

ใ“ใฎๆ–ฐใ—ใ„APIใงใฏใ€ๆฌกใฎใ“ใจใŒๅฏ่ƒฝใซใชใ‚Šใพใ—ใŸใ€‚

ใƒชใ‚ขใ‚ฏใ‚ทใƒงใƒณใซใ‚ˆใ‚‹ใ‚ณใƒŸใƒฅใƒ‹ใ‚ฑใƒผใ‚ทใƒงใƒณ

ใ‚ณใƒŸใƒฅใƒ‹ใ‚ฑใƒผใ‚ทใƒงใƒณใฏๅ˜ใซใƒกใƒƒใ‚ปใƒผใ‚ธใ‚’ๆŠ•็จฟใ™ใ‚‹ใ ใ‘ใงใฏใ‚ใ‚Šใพใ›ใ‚“ใ€‚ไป–ใฎไบบใฎใƒกใƒƒใ‚ปใƒผใ‚ธใซๅๅฟœใ™ใ‚‹ใ“ใจใ‚‚้‡่ฆใงใ™ใ€‚ๆ–ฐใ—ใ„ใƒชใ‚ขใ‚ฏใ‚ทใƒงใƒณใ‚ทใ‚นใƒ†ใƒ ใฏใ€ใƒœใƒƒใƒˆใจใƒ•ใ‚ฉใƒญใƒฏใƒผใฎ้–“ใซ่‡ช็„ถใชไบคๆตใƒใ‚คใƒณใƒˆใ‚’ไฝœใ‚Šๅ‡บใ—ใพใ™ใ€‚

// ๆจ™ๆบ–ใฎUnicode็ตตๆ–‡ๅญ—ใงใƒกใƒƒใ‚ปใƒผใ‚ธใซใƒชใ‚ขใ‚ฏใ‚ทใƒงใƒณ await message.react(emoji`๐Ÿ‘`); // ใพใŸใฏๅฎš็พฉใ—ใŸใ‚ซใ‚นใ‚ฟใƒ ็ตตๆ–‡ๅญ—ใงใƒชใ‚ขใ‚ฏใ‚ทใƒงใƒณ await message.react(emojis.botkit); // ใƒชใ‚ขใ‚ฏใ‚ทใƒงใƒณใ‚’่ช่ญ˜ใ—ใฆๅฟœ็ญ”ใ™ใ‚‹ใƒœใƒƒใƒˆใ‚’ไฝœๆˆ bot.onReact = async (session, reaction) => { await session.publish( text`${reaction.actor}ใ•ใ‚“ใ€็งใฎใƒกใƒƒใ‚ปใƒผใ‚ธใซ${reaction.emoji}ใงใƒชใ‚ขใ‚ฏใ‚ทใƒงใƒณใ—ใฆใใ‚Œใฆใ‚ใ‚ŠใŒใจใ†ใ”ใ–ใ„ใพใ™๏ผ`, { visibility: "direct" } ); };

ใ“ใฎๆฉŸ่ƒฝใซใ‚ˆใ‚Šใ€ใƒœใƒƒใƒˆใฏๆฌกใฎใ“ใจใŒใงใใ‚‹ใ‚ˆใ†ใซใชใ‚Šใพใ—ใŸใ€‚

  • Message.react()ใ‚’ไฝฟ็”จใ—ใฆUnicode็ตตๆ–‡ๅญ—ใงใƒกใƒƒใ‚ปใƒผใ‚ธใซใƒชใ‚ขใ‚ฏใ‚ทใƒงใƒณ
  • ๅฎš็พฉใ—ใŸใ‚ซใ‚นใ‚ฟใƒ ็ตตๆ–‡ๅญ—ใงใƒชใ‚ขใ‚ฏใ‚ทใƒงใƒณ
  • Bot.onReactใจBot.onUnreactใƒใƒณใƒ‰ใƒฉใƒผใงใƒชใ‚ขใ‚ฏใ‚ทใƒงใƒณใ‚คใƒ™ใƒณใƒˆใ‚’ๅ‡ฆ็†

ๅผ•็”จใซใ‚ˆใ‚‹ไผš่ฉฑ

่ญฐ่ซ–ใงใฏใ€ไป–ใฎไบบใŒ่จ€ใฃใŸใ“ใจใ‚’ๅ‚็…งใ™ใ‚‹ๅฟ…่ฆใŒใ—ใฐใ—ใฐใ‚ใ‚Šใพใ™ใ€‚ๆ–ฐใ—ใ„ๅผ•็”จๆฉŸ่ƒฝใซใ‚ˆใ‚Šใ€ใ‚ˆใ‚Š็ตๆŸๅŠ›ใฎใ‚ใ‚‹ไผš่ฉฑใ‚นใƒฌใƒƒใƒ‰ใ‚’ไฝœๆˆใงใใพใ™ใ€‚

// ใƒœใƒƒใƒˆใฎๆŠ•็จฟใงไป–ใฎใƒกใƒƒใ‚ปใƒผใ‚ธใ‚’ๅผ•็”จ await session.publish( text`ใ“ใฎ่ˆˆๅ‘ณๆทฑใ„่ฆ–็‚นใซใคใ„ใฆ็ญ”ใˆใพใ™...`, { quoteTarget: originalMessage } ); // ใƒฆใƒผใ‚ถใƒผใŒใƒœใƒƒใƒˆใฎใƒกใƒƒใ‚ปใƒผใ‚ธใ‚’ๅผ•็”จใ—ใŸๅ ดๅˆใฎๅ‡ฆ็† bot.onQuote = async (session, quoteMessage) => { await session.publish( text`${quoteMessage.actor}ใ•ใ‚“ใ€็งใฎ่€ƒใˆใ‚’ๅ…ฑๆœ‰ใ—ใฆใใ‚Œใฆใ‚ใ‚ŠใŒใจใ†ใ”ใ–ใ„ใพใ™๏ผ`, { visibility: "direct" } ); };

ๅผ•็”จๆฉŸ่ƒฝใซใ‚ˆใ‚Šใ€ใƒœใƒƒใƒˆใฏๆฌกใฎใ“ใจใŒใงใใ‚‹ใ‚ˆใ†ใซใชใ‚Šใพใ—ใŸใ€‚

  • quoteTargetใ‚ชใƒ—ใ‚ทใƒงใƒณใงใƒกใƒƒใ‚ปใƒผใ‚ธใ‚’ๅผ•็”จ
  • Message.quoteTargetใ‚’้€šใ˜ใฆๅผ•็”จใ•ใ‚ŒใŸใƒกใƒƒใ‚ปใƒผใ‚ธใซใ‚ขใ‚ฏใ‚ปใ‚น
  • ๆ–ฐใ—ใ„Bot.onQuoteใ‚คใƒ™ใƒณใƒˆใƒใƒณใƒ‰ใƒฉใƒผใงๅผ•็”จใ‚คใƒ™ใƒณใƒˆใ‚’ๅ‡ฆ็†

่ฆ–่ฆš็š„ใชๆ”นๅ–„

ใ‚ณใƒŸใƒฅใƒ‹ใ‚ฑใƒผใ‚ทใƒงใƒณใซใฏ่ฆ–่ฆš็š„่ฆ็ด ใ‚‚้‡่ฆใชใŸใ‚ใ€ใƒœใƒƒใƒˆใฎ่กจ็พๆ–นๆณ•ใ‚’ๆ”นๅ–„ใ—ใพใ—ใŸใ€‚

  • ใ‚ฆใ‚งใƒ–ใ‚คใƒณใ‚ฟใƒผใƒ•ใ‚งใƒผใ‚นใง็”ปๅƒๆทปไป˜ใƒ•ใ‚กใ‚คใƒซใŒๆญฃใ—ใ่กจ็คบใ•ใ‚Œใ‚‹ใ‚ˆใ†ใซใชใ‚Šใพใ—ใŸ
  • ใƒœใƒƒใƒˆใฎใ‚ณใƒณใƒ†ใƒณใƒ„ใŒใ‚ˆใ‚Š่ฆ‹ใ‚„ใ™ใใชใ‚Šใ€่ฑŠใ‹ใชไฝ“้จ“ใ‚’ๆไพ›ใ—ใพใ™

ๅ†…้ƒจๆ”นๅ–„๏ผšๆดปๅ‹•ใฎไผๆ’ญใฎๅผทๅŒ–

ใƒ•ใ‚งใƒ‡ใ‚ฃใƒใƒผใ‚นใงใฎๆดปๅ‹•ใŒไผๆ’ญใ™ใ‚‹ๆ–นๆณ•ใ‚‚ๆ”นๅ–„ใ•ใ‚Œใพใ—ใŸใ€‚

  • ่ฟ”ไฟกใ€ๅ…ฑๆœ‰ใ€ๆ›ดๆ–ฐใ€ๅ‰Š้™คใฎใ‚ˆใ‚Šๆญฃ็ขบใชไผๆ’ญ
  • ๅ…ƒใฎใƒกใƒƒใ‚ปใƒผใ‚ธไฝœๆˆ่€…ใซๆดปๅ‹•ใŒ้ฉๅˆ‡ใซ้€ไฟกใ•ใ‚Œใพใ™

ใ“ใ‚Œใ‚‰ใฎๆ”นๅ–„ใซใ‚ˆใ‚Šใ€ๆง˜ใ€…ใชใƒ•ใ‚งใƒ‡ใ‚ฃใƒใƒผใ‚นใƒ—ใƒฉใƒƒใƒˆใƒ•ใ‚ฉใƒผใƒ ใงใฎใƒœใƒƒใƒˆใฎ็›ธไบ’ไฝœ็”จใŒไธ€่ฒซๆ€งใจไฟก้ ผๆ€งใ‚’ๆŒใคใ‚ˆใ†ใซใชใ‚Šใพใ™ใ€‚

BotKit 0.2.0ใงๆœ€ๅˆใฎไธ€ๆญฉใ‚’่ธใฟๅ‡บใ™

ใ“ใ‚Œใ‚‰ใฎๆ–ฐๆฉŸ่ƒฝใ‚’ไฝ“้จ“ใ—ใฆใฟใŸใ„ใงใ™ใ‹๏ผŸBotKit 0.2.0ใฏJSRใงๅˆฉ็”จๅฏ่ƒฝใงใ€็ฐกๅ˜ใชใ‚ณใƒžใƒณใƒ‰ใงใ‚คใƒณใ‚นใƒˆใƒผใƒซใงใใพใ™ใ€‚

deno add jsr:@fedify/botkit@0.2.0

BotKitใฏTemporal API๏ผˆJavaScriptใงใฏใพใ ่ฉฆ้จ“็š„ใชๆฉŸ่ƒฝ๏ผ‰ใ‚’ไฝฟ็”จใ™ใ‚‹ใŸใ‚ใ€deno.jsonใงใ“ใ‚Œใ‚’ๆœ‰ๅŠนใซใ™ใ‚‹ๅฟ…่ฆใŒใ‚ใ‚Šใพใ™ใ€‚

{ "imports": { "@fedify/botkit": "jsr:@fedify/botkit@0.2.0" }, "unstable": ["temporal"] }

ใ“ใ‚Œใ‚‰ใฎ็ฐกๅ˜ใชใ‚นใƒ†ใƒƒใƒ—ใงใ€ๆœ€ๆ–ฐๆฉŸ่ƒฝใ‚’ไฝฟใฃใฆใƒ•ใ‚งใƒ‡ใ‚ฃใƒใƒผใ‚นใƒœใƒƒใƒˆใ‚’ไฝœๆˆใพใŸใฏใ‚ขใƒƒใƒ—ใ‚ฐใƒฌใƒผใƒ‰ใ™ใ‚‹ๆบ–ๅ‚™ใŒๆ•ดใ„ใพใ—ใŸใ€‚

ไปŠๅพŒใฎๅฑ•ๆœ›

#BotKit 0.2.0ใฏใ€ใƒ•ใ‚งใƒ‡ใ‚ฃใƒใƒผใ‚นใƒœใƒƒใƒˆ้–‹็™บใ‚’ใ‚ขใ‚ฏใ‚ปใ‚นใ—ใ‚„ใ™ใใ€ๅผทๅŠ›ใ‹ใคๆฅฝใ—ใ„ใ‚‚ใฎใซใ™ใ‚‹ใŸใ‚ใฎ็งใŸใกใฎ็ถ™็ถš็š„ใชๅ–ใ‚Š็ต„ใฟใ‚’็คบใ—ใฆใ„ใพใ™ใ€‚ใ“ใ‚Œใ‚‰ใฎๆ–ฐๆฉŸ่ƒฝใŒใ€็š†ใ•ใ‚“ใฎใƒœใƒƒใƒˆใ‚’ใƒ•ใ‚งใƒ‡ใ‚ฃใƒใƒผใ‚นใ‚ณใƒŸใƒฅใƒ‹ใƒ†ใ‚ฃใงใ‚ˆใ‚Š้ญ…ๅŠ›็š„ใงใ‚คใƒณใ‚ฟใƒฉใ‚ฏใƒ†ใ‚ฃใƒ–ใชใƒกใƒณใƒใƒผใซใ™ใ‚‹ใฎใซๅฝน็ซ‹ใคใจไฟกใ˜ใฆใ„ใพใ™ใ€‚

ๅฎŒๅ…จใชใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใจ่ฉณ็ดฐใชไพ‹ใซใคใ„ใฆใฏใ€็งใŸใกใฎใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใ‚ตใ‚คใƒˆใ‚’ใ”่ฆงใใ ใ•ใ„ใ€‚

ใƒ•ใ‚ฃใƒผใƒ‰ใƒใƒƒใ‚ฏใ€ๆฉŸ่ƒฝใƒชใ‚ฏใ‚จใ‚นใƒˆใ€ใ‚ณใƒผใƒ‰่ฒข็Œฎใ‚’้€šใ˜ใฆใ“ใฎใƒชใƒชใƒผใ‚นใซ่ฒข็Œฎใ—ใฆใใ ใ•ใฃใŸใ™ในใฆใฎๆ–นใ€…ใซๆ„Ÿ่ฌใ—ใพใ™ใ€‚BotKitใ‚ณใƒŸใƒฅใƒ‹ใƒ†ใ‚ฃใฏๆˆ้•ทใ‚’็ถšใ‘ใฆใŠใ‚Šใ€็š†ใ•ใ‚“ใŒไฝœๆˆใ™ใ‚‹ใ‚‚ใฎใ‚’ๆฅฝใ—ใฟใซใ—ใฆใ„ใพใ™๏ผ

BotKitใฏใ€ActivityPubใ‚ตใƒผใƒใƒผใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใ‚’ไฝœๆˆใ™ใ‚‹ใŸใ‚ใฎไฝŽใƒฌใƒ™ใƒซใƒ•ใƒฌใƒผใƒ ใƒฏใƒผใ‚ฏFedifyใซใ‚ˆใฃใฆๆ”ฏใˆใ‚‰ใ‚Œใฆใ„ใพใ™ใ€‚

#fedidev #ใƒ•ใ‚งใƒ‡ใ‚ฃใƒใƒผใ‚น #ใ‚ซใ‚นใ‚ฟใƒ ็ตตๆ–‡ๅญ— #็ตตๆ–‡ๅญ—ใƒชใ‚ขใ‚ฏใ‚ทใƒงใƒณ #็ตตๆ–‡ๅญ—ๅๅฟœ #ๅผ•็”จ

BotKit by Fedify

A framework for creating your ActivityPub bots