Search results

We're excited to announce the release of 1.6.1, which marks the beginning of the 1.6 series following the retraction of version 1.6.0. This release introduces significant new capabilities that expand Fedify's deployment options and enhance security compatibility across the .

๐ŸŒ Cloudflare Workers support

Fedify 1.6 introduces first-class support for Cloudflare Workers, enabling deployment of applications at the edge.

New components

Key features

  • Seamless integration with 's serverless runtime
  • Automatic handling of queue message processing through Workers' queue() method
  • Support for Node.js compatibility flag required for Fedify's cryptographic operations
  • Manual queue processing via Federation.processQueuedTask() method

For a complete working example, see the Cloudflare Workers example in the Fedify repository.

๐Ÿ—๏ธ Federation builder pattern

Fedify 1.6 introduces the FederationBuilder class and createFederationBuilder() function to support deferred federation instantiation. This pattern provides several benefits:

  • Deferred instantiation: Set up dispatchers and listeners before creating the federation object
  • Better code organization: Avoid circular dependencies and improve project structure
  • Cloudflare compatibility: Accommodates binding-based architectures where resources are passed as arguments rather than globals
  • Modular setup: Build complex federations piece by piece before instantiation

The builder pattern is particularly useful for large applications and environments like Cloudflare Workers where configuration data is only available at runtime.

๐Ÿ” HTTP Message Signatures (RFC 9421)

Fedify 1.6 implements the official HTTP Message Signatures standard (RFC 9421) specification, the final revision of the HTTP Signatures specification.

Double-knocking mechanism

To ensure maximum compatibility across the fediverse, Fedify 1.6 introduces an intelligent double-knocking mechanism:

  1. Primary attempt: RFC 9421 (HTTP Message Signatures) for modern implementations
  2. Fallback: Draft cavage version for legacy compatibility
  3. Adaptive caching: The system remembers which version each server supports to optimize future requests

This approach ensures seamless communication with both modern and legacy ActivityPub implementations while positioning Fedify at the forefront of security standards.

Interoperability testing

The RFC 9421 implementation has been thoroughly tested for interoperability with existing ActivityPub implementations that support RFC 9421 signature verification:

  • Mitra 4.4.0: Successfully verified Fedify-generated RFC 9421 signatures
  • Mastodon 4.4.0 development version: Tested RFC 9421 signature verification against Fedify's implementation (refer to Mastodon PR #34814, though Mastodon 4.4.0 has not yet been released)

These tests confirm that other ActivityPub implementations can successfully verify RFC 9421 signatures generated by Fedify, ensuring proper federation as the ecosystem gradually adopts the official specification. While these implementations currently support verification of RFC 9421 signatures, they do not yet generate RFC 9421 signatures themselvesโ€”making Fedify one of the first ActivityPub implementations to support both generation and verification of the modern standard.

๐Ÿ” WebFinger enhancements

Dedicated WebFinger lookup

The new Context.lookupWebFinger() method provides direct access to WebFinger data, offering developers more granular control over account discovery and resource resolution beyond the higher-level Context.lookupObject() method.

๐Ÿ›  Context API improvements

Context data replacement

The new Context.clone() method enables dynamic context data replacement, providing greater flexibility in request processing and data flow management. This is particularly useful for middleware implementations and complex request routing scenarios.

๐Ÿš€ Migration considerations

Backward compatibility

Fedify 1.6 maintains full backward compatibility with existing applications. The new HTTP Message Signatures and double-knocking mechanisms work transparently without requiring any code changes.

Node.js version requirement

Important: Fedify 1.6 requires Node.js 22.0.0 or later for Node.js environments. This change does not affect applications using Deno or Bun runtimes. If you're currently using Node.js, please ensure your environment meets this requirement before upgrading.

New deployment options

For new deployments, consider leveraging Cloudflare Workers support for:

  • Global edge deployment with low latency
  • Serverless scaling and automatic resource management
  • Integration with Cloudflare's ecosystem of services

๐ŸŽฏ Looking forward

Fedify 1.6 represents a significant expansion of deployment possibilities while maintaining the framework's commitment to broad compatibility across the fediverse. The addition of Cloudflare Workers support opens new architectural patterns for federated applications, while the RFC 9421 implementation ensures Fedify stays current with emerging ActivityPub security standards.


For detailed migration guides, API documentation, and examples, please visit the Fedify documentation. Join our community on Matrix or Discord for support and discussions.

2
0
2

Did you know? provides optimized for LLMs through the llms.txt standard.

Available endpoints:

Useful for training assistants on / development, building documentation chatbots, or -powered dev tools.

0

1.6 is approaching with three major enhancements: RFC 9421 HTTP Message Signatures support with double-knocking for seamless backward compatibility, a new builder pattern for better code organization in large applications, and native support for serverless deployments. These additions strengthen Fedify's standards compliance while expanding deployment flexibility across different environments. Stay tuned for the official release! ๐Ÿš€

2
0
0

Good news! We've officially added support to the roadmap. We've created a detailed issue to track our implementation plan: https://github.com/fedify-dev/fedify/issues/233.

The effort will be tackled in phases, including compatibility assessment, core adaptations for Workers' environment, KV store and message queue implementations, and finally integration with Cloudflare's ecosystem. This will be a substantial project that we'll break down into several sub-issues.

If you're interested in contributing to any specific aspect of Workers support, please comment on the main issue to coordinate efforts.

๐ŸŽ‰ support is now complete! After implementing the test infrastructure, core module, examples, and comprehensive documentation, can now run on Cloudflare Workers.

What's included:

Try it now: Available in the development release v1.6.1-dev.876+7b07d213:

This will be included in the upcoming Fedify 1.6 stable release. Thank you to everyone who requested this feature and provided feedback throughout the implementation!

1
0

If you're interested in building your own server but don't know where to start, I recommend checking out 's Creating your own federated microblog. It provides a comprehensive, step-by-step guide that walks you through building a fully functional federated application. Perfect for developers who want to dive into the !

0
3
0

This is how I am thinking about pointing to the GreatApe WebSocket API in the activity file.

The GreatApe WebSocket API โ€” ActivitySocket ? โ€” is sending ActivityPub activities over a WebSocket, along with some other stuff (such a queries, and commands).

Right now, I am using the "endpoints" field with the sub-field "inoutbox" to point to the WebSockets API end-point.

RE: mastodon.social/@reiver/114590

    {
      "type": "Conference",
      "actor": "acct:reiver@mastodon.social",
      "endpoints": {
        "inoutbox": "wss://greatape.social/@reiver@mastodon.social/conf"
      },
      "id": "https://greatape.social/@reiver@mastodon.social/conf",
      "name": "@reiver@mastodon.social โ€” GreatApe"
    }
0

1/

GreatApe is a conferencing platform for the Fediverse and the Social Web โ€” where an audience can listen & watch live, and can be invited to join the speakers on the stage.

GreatApe makes use of a WebSocket for communications.

I am working on turning the WebSocket API that @muhammadzaidali and @benyamin0Ben created into something more ActivityPub / ActivityStreams like.

Interestingly โ€”

RE: mastodon.social/@reiver/114585

0

1/

GreatApe is a conferencing platform for the Fediverse and the Social Web โ€” where an audience can listen & watch live, and can be invited to join the speakers on the stage.

GreatApe makes use of a WebSocket for communications.

I am working on turning the WebSocket API that @muhammadzaidali and @benyamin0Ben created into something more ActivityPub / ActivityStreams like.

Interestingly โ€”

RE: mastodon.social/@reiver/114585

0

We're planning to reorganize our labels to better reflect 's project structure! ๐Ÿท๏ธ

Currently using GitHub's default labels, but we want something more tailored to our needsโ€”like component-specific labels (vocab, federation, actor, etc.), runtime tags (Deno/Node/Bun), and compatibility tracking.

The proposal includes hierarchical labeling with categories like:

  • type/ for bug, feature, documentation
  • component/ for different parts of Fedify
  • activitypub/ for interop issues with Mastodon, Misskey, etc.

We'd love your thoughts! What labels would be most helpful for contributors and maintainers?

Check out the full proposal: https://github.com/fedify-dev/fedify/issues/238.

0

While 's API provides comprehensive support for and major vendor extensions, its code-generation approach makes runtime extensions challenging. However, the project welcomes contributions to expand the supported types and properties.

Fedify accepts vocabulary contributions when they meet any of these criteria:

  • Documented in FEP (Fediverse Enhancement Proposals) or equivalent specification
  • Already adopted by widely-used implementations like Mastodon or Pleroma
  • Thoroughly discussed within the Fedify community (Discord, Matrix, GitHub Discussions)

Contributing new vocabulary is straightforward. The vocabulary definitions live in YAML files within the fedify/vocab/ directory. To add a new type, create a new .yaml file. To add properties to existing types, extend the properties section in the relevant .yaml file.

This approach ensures Fedify's vocabulary coverage grows with the fediverse ecosystem while maintaining type safety and comprehensive documentation. If you're working with custom ActivityPub extensions, consider contributing them upstream to benefit the entire community.

For detailed guidance on the contribution process, see the Extending the vocabulary section in Fedify's docs.

1

Link rot kept biting me on big sites, so I built Broken-Links Scanner.
Highlight any part of a page, hit scan, and it checks just those links. Free, no tracking.

Chrome Web Store โ†’ chromewebstore.google.com/deta
More info โ†’ linkscan.app/ ยท dev log โ†’ koval.dev/blog/broken-links-sc

Give it a spin and let me know what you find.

0

Had a wonderful time today at our second FediDev KR (@sprints.fedidev.krํ•œ๊ตญ ํŽ˜๋””๋ฒ„์Šค ๊ฐœ๋ฐœ์ž ๋ชจ์ž„) gathering at Turing's Apple (@TuringAppleDevํŠœ๋ง์˜ ์‚ฌ๊ณผ) in !

We spent the day contributing to various open source projects including @fedifyFedify: an ActivityPub server framework, @holloHollo :hollo:, and Hackers' Pub. It was fantastic to see the community come together to build and improve tools for the decentralized social web.

Our participants made some great contributions, and you can read all about what we accomplished in today's blog post.

Looking forward to our next sprint!

A hand holding a 3D-printed keychain featuring the Fedify dinosaur mascot logo in blue and white colors. The keychain is packaged in a clear plastic bag with Korean text indicating it's from the FediDev KR Second Sprint on May 24, 2025. The background shows laptops and stickers on a table, suggesting a coding workspace at the sprint event.A bright green poster for FediDev KR #2 sprint event, showing the date 2025-05-24 Sat 13:00โ€“18:00. The poster features Korean text announcing a FediDev KR sprint session, with the Turing's Apple logo and a circular blue logo with wave-like design. The poster is displayed on a TV at the entrance of the venue.
3
0
0

Exciting update ๐Ÿ‘‰ We're inviting a handful of select users to Channel.org now ๐ŸŽ‰

Channel.org aims to bring together knowledge across the open social web, whilst offering organisations the ability to build a social home instead of renting from Big Tech dictators.

If you'd like to join the beta waitlist, let us know at support@channel.org

A graphic alert reading: Channel.org BETA release. Invite only access now live
0

I've been thinking about adding a debug dashboard to that shows all activities being sent and received in real-time. This would include filters by activity type, detailed inspection of JSON-LD content, signature verification details, and retry management for failed deliveries.

As a , would you find this useful for troubleshooting federation issues? Any other features that would be helpful in such a debugging tool?

1
0
0
0

I've been thinking about client-server interactions in the . isn't widely used, and most clients rely on Mastodon-compatible APIs instead.

What if we created a new standardized API based on GraphQL + Relay for client-server communication, while keeping ActivityPub for server-to-server federation?

The Mastodon-compatible API lacks formal schema definitions for code generation and type checking, which hurts developer productivity. And ActivityPub C2S is honestly too cumbersome to use directly from client apps.

would give us type safety, efficient data fetching (only get what you need), and the ability to evolve the API without breaking clients. 's features for pagination, caching, and optimistic updates seem perfect for social apps.

Would this be valuable to our community? What challenges do you see? How might we handle backward compatibility? And should this be formalized as an FEP?

Curious what others think about this approach.

3
8
0

Looking for implementations with support! ๐Ÿ”

As mentioned in the Fedify announcement below, I've implemented RFC 9421 (HTTP Message Signatures) and need to verify its interoperability with other ActivityPub implementations.

The challenge is that most major ActivityPub projects don't seem to have full RFC 9421 implementations in production yet. If you're working on an ActivityPub project that:

  • has implemented RFC 9421 (even in a development branch)
  • is currently implementing it
  • has plans to implement it soon

Please reach out! I'd love to collaborate on interoperability testing to ensure our implementations work properly with each other before merging this into 's main branch.

Any leads or connections would be greatly appreciated! ๐Ÿ™

2

Looking for implementations with support! ๐Ÿ”

As mentioned in the Fedify announcement below, I've implemented RFC 9421 (HTTP Message Signatures) and need to verify its interoperability with other ActivityPub implementations.

The challenge is that most major ActivityPub projects don't seem to have full RFC 9421 implementations in production yet. If you're working on an ActivityPub project that:

  • has implemented RFC 9421 (even in a development branch)
  • is currently implementing it
  • has plans to implement it soon

Please reach out! I'd love to collaborate on interoperability testing to ensure our implementations work properly with each other before merging this into 's main branch.

Any leads or connections would be greatly appreciated! ๐Ÿ™

1
5
1

We're excited to announce that we've implemented RFC 9421 (HTTP Message Signatures) in , complete with our double-knocking mechanism to maintain backward compatibility with the draft cavage version.

This implementation includes both signature generation and verification, meaning is used when both sending and receiving activities. While we haven't merged the RFC 9421 implementation branch yet, we're currently conducting interoperability tests with development versions of Mastodon and other implementations. Once these tests confirm compatibility, we'll proceed with the merge.

As noted in the attached docs, although RFC 9421 is the final and official standard for HTTP Signatures, the draft cavage version remains widely used across the . Our double-knocking mechanism ensures maximum compatibility by trying the RFC 9421 version first, then falling back to draft cavage if needed.

Currently, we support RSA-PKCS-v1.5 key pairs for generating HTTP Message Signatures, with plans to expand to other signature types in future releases.

We look forward to contributing to a more standardized and secure fediverse!

HTTP Message Signatures

This API is available since Fedify 1.6.0.

RFC 9421, also known as HTTP Message Signatures, is the final revision of the HTTP Signatures specification. Although it is the official standard, it is not widely used in the fediverse yet. As of May 2025, major ActivityPub implementations, such as Mastodon, et al., still rely on the draft cavage version of HTTP Signatures for signing portable activities.

Fedify automatically signs activities with the sender's private key if the actor keys dispatcher is set and the actor has any RSA-PKCS#1-v1.5 key pair. If there are multiple key pairs, Fedify selects the first RSA-PKCS#1-v1.5 key pair among them.

NOTE

Although HTTP Message Signatures support other than RSA-PKCS#1-v1.5, Fedify currently supports only RSA-PKCS#1-v1.5 key pairs for generating HTTP Message Signatures. This limitation will be lifted in the future releases.Double-knocking HTTP Signatures

This API is available since Fedify 1.6.0.

As you read above, there are two revisions of HTTP Signatures: the draft cavage version and the RFC 9421 version. The draft cavage version is declared as obsolete, but it is still widely used in the fediverse, and many ActivityPub implementations still rely on it. On the other hand, the RFC 9421 version is the official standard, but it is not widely used yet.

To support both versions of HTTP Signatures, Fedify uses the double-knocking mechanism: trying one version, then falling back to another if rejected. If it's the first encounter with the recipient server, Fedify tries the RFC 9421 version first, and if it fails, it falls back to the draft cavage version. If the recipient server accepts the RFC 9421 version, Fedify remembers it and uses the RFC 9421 version for the next time. If the recipient server rejects the RFC 9421 version, Fedify falls back to the draft cavage version and remembers it for the next time.
1
0
1
0

2/

I remember some people years ago saying that โ€” they wanted to "subscribe" to the "server live feeds" on community servers different from the one that they are on

This is a way of following & perhaps even joining a community without necessarily being on that server

Which for example is useful if you wanted to be part of more than one community but use the same account

0

2/

I remember some people years ago saying that โ€” they wanted to "subscribe" to the "server live feeds" on community servers different from the one that they are on

This is a way of following & perhaps even joining a community without necessarily being on that server

Which for example is useful if you wanted to be part of more than one community but use the same account

0
0

Great news for the wafrn app !!

As a culmination of the big journey of the past weeks, the Wafrn App is now listed in the official @unifiedpush documentation as one of the apps that support UnifiedPush

Check it at https://unifiedpush.org/users/apps/


#WafrnDev #FediDev #UnifiedPush #Degoogle #FreeServices

Apps using UnifiedPush

This is a non-exhaustive list of the first few end-user applications that use UnifiedPush. Android Name Description Date Since version Docsยน FluffyChat Matrix chat January 2021 v0.26.1 FluffyChat push notificationsยฒ Fedilab Mastodon/Fediverse March 2021 v2.39.0 Fedilab push notificationsยฒ Tox Push Message App Tox chat May 2021 v1.0.3 generic SchildiChat Matrix chat September 2021 v1.2.0.sc42 generic FindMyDevice Find your device November 2021 v0.2.2 generic Element Matrix chat June 2022 v1.4.26 generic Tusky Mastodon/Fediverse July 2022 v19.0 generic Neon Nextcloud July 2022 Unreleased generic Jami Jami March 2023 v361 generic Goguma IRC client March 2023 v0.5.0 generic Circles Social Network (matrix) June 2023 v1.0.11 generic Databag Messaging Service July 2023 v1.5.0 generic Podverse (beta) Podcast Manager July 2023 v4.13.1 generic Moshidon Mastodon August 2023 v2.0.3+fork.98 generic Trรคwelldroid Traewelling client September 2023 v2.0.0 generic Pachli Mastodon September 2023 v1.0.0 generic Molly Signal client October 2023 v6.35.3-1.up1 mollysocket Amethyst Nostr client October 2023 v0.80.1 generic Ltt.rs Mail (JMAP) client December 2023 0.4.0 generic Mercurygram Telegram client December 2023 v10.3.2.1 generic Element-X Matrix chat January 2024 v0.4.2 generic SchildiChat Next Matrix chat January 2024 v0.4.2.sc1 generic Nagram Telegram client April 2024 10.9.1.1165 generic DAVxโต CalDAV/CardDAV/WebDAV September 2024 v4.4.2-ose Nextcloud extension for WebDAV-Push Momogram Telegram client December 2024 v11.4.2-1 generic FOSS Warn Emergency alerts December 2024 1.0.0 alpha0 FOSS Warn Wiki Wafrn App Social Network (Fediverse + Bluesky) May 2025 v1.3.0 generic ยน App-specific documentation should not be needed. Compatible apps should just work after installing a UnifiedPush distributor.

unifiedpush.org ยท UnifiedPush

0
0

After reviewing FEP-5624: Per-object reply control policies and GoToSocial's interaction policy spec, I find myself leaning toward the latter for long-term considerations, though both have merit.

FEP-5624 is admirably focused and simpler to implement, which I appreciate. However, 's approach seems to offer some architectural advantages:

  1. The three-tier permission model (allow/require approval/deny) feels more flexible than binary allow/deny
  2. Separating approval objects from interactions appears more secure against forgery
  3. The explicit handling of edge cases (mentioned users, post authors) provides clearer semantics
  4. The extensible framework allows for handling diverse interaction types, not just replies

I wonder if creating an that extracts GoToSocial's interaction policy design into a standalone standard might be worthwhile. It could potentially serve as a more comprehensive foundation for access control in .

This is merely my initial impression though. I'd be curious to hear other developers' perspectives on these approaches.

4

Soโ€ฆ I did a thing: https://github.com/juandjara/expo-unified-push
This library will help everybody developing React Native apps to use the Unified Push Android library, so they can have native notifications without depending on Google and Firebase systems.

Next step, integrating it into wafrn


#wafrnDev #fediDev #react-native
0

Hey fedi devss! (Hints & boosts appreciated)

Mastodon API question โ€” which instance/server API says where the URL redirects when there is no signed in user?

For example:
1. social.ayco.io goes to my profile; but
2. fosstodon.org goes to the explore tab

I am looking for the info via REST API

0

I'm exploring a new idea called FediOTP (codename): an authentication system that uses DMs to deliver one-time passwords, allowing any account to authenticate with web services. Unlike current solutions that rely on specific APIs (, ), this would work with any ActivityPub-compatible server, increasing interoperability across the fediverse. Would love to hear your thoughts on potential challenges or use cases for this approach.

For those skeptical of DMs in : I'm also considering an alternative verification approach using ActivityPub's Question feature. Instead of sending numeric codes, the system could send a poll with several emoji options, and the user would select the one that matches what's displayed on their login screen. This visual authentication method might offer better security against certain automated attacks while still leveraging federation rather than platform-specific APIs. Would this approach address some of the privacy concerns around DM-based verification?

0

I'm exploring a new idea called FediOTP (codename): an authentication system that uses DMs to deliver one-time passwords, allowing any account to authenticate with web services. Unlike current solutions that rely on specific APIs (, ), this would work with any ActivityPub-compatible server, increasing interoperability across the fediverse. Would love to hear your thoughts on potential challenges or use cases for this approach.

1
5
0
0

Hey folks! We're excited to share a preview of a new API coming in 1.6 that should make structuring larger federated apps much cleaner: FederationBuilder.

As your Fedify applications grow, you might encounter circular dependency issues when registering dispatchers and listeners across multiple files. The new FederationBuilder pattern helps solve this by separating the configuration phase from instantiation.

Instead of this:

// federation.ts
import { createFederation } from "@fedify/fedify";

export const federation = createFederation<AppContext>({
  kv: new DbKvStore(), 
  queue: new RedisMessageQueue(),
  // Other options...
});

// Now we need to import this federation instance in other files
// to register dispatchers and listeners...

You can now do this:

// builder.ts
import { createFederationBuilder } from "@fedify/fedify";

export const builder = createFederationBuilder<AppContext>();

// other files can import and configure this builder...
// actors.ts
import { builder } from "./builder.ts";
import { Person } from "@fedify/fedify";

builder.setActorDispatcher("/users/{handle}", async (ctx, handle) => {
  // Actor implementation
});
// inbox.ts
import { builder } from "./builder.ts";
import { Follow } from "@fedify/fedify";

builder.setInboxListeners("/users/{handle}/inbox", "/inbox")
  .on(Follow, async (ctx, follow) => {
    // Follow handling
  });
// main.ts โ€” Only create the Federation instance at startup
import { builder } from "./builder.ts";

// Build the Federation object with actual dependencies
export const federation = await builder.build({
  kv: new DbKvStore(),
  queue: new RedisMessageQueue(),
  // Other options...
});

This pattern helps avoid circular dependencies and makes your code more modular. Each part of your app can configure the builder without needing the actual Federation instance.

The full documentation will be available when 1.6 is released, but we wanted to share this early with our community. Looking forward to your feedback when it lands!

Want to try it right now? You can install the development version from JSR or npm:

# Deno
deno add jsr:@fedify/fedify@1.6.0-dev.777+1206cb01

# Node.js
npm add @fedify/fedify@1.6.0-dev.777

# Bun
bun add @fedify/fedify@1.6.0-dev.777

0
0
0

I've been reflecting lately on projects like @fedifyFedify: an ActivityPub server framework, @holloHollo :hollo:, and @botkitBotKit by Fedify :botkit:. Sometimes I wonder if I'm solving problems that very few people actually need solved. How many developers truly want to build their own server from scratch?

It feels a bit like inventing shoes that let people walk on their hands all day. Would there be a viable market? How many would actually buy them?

That's the sense I get with these projects. They do have users who find them tremendously valuable, but the total user base is inherently limited. The tools serve an important function for a small audience of specialized developers.

There are moments when my motivation wavers. When the user community consists of just a handful of enthusiastic supporters, it's sometimes difficult to maintain momentum and justify the ongoing investment of time and energy.

And yet, there's something meaningful about creating specialized tools that solve complex problems well, even if they're only used by a few. Perhaps that's enough.

0

A lot of Fediverse software has a HEALTH-CHECK URL.

But not all Fediverse does.

It would be better if ALL Fediverse software had a HEALTH-CHECK URL.

...

A HEALTH-CHECK URL is a special URL that tell others if the system is running properly.

It would return "200 OK" if everything is fine. And return "500 Internal Server Error" if there is a problem

...

A HEALTH-CHECK URL is important to those who actual run and administrate Fediverse servers

A HEALTH-CHECK URL would, for example, make sure:

โ€ข the web-server is up,
โ€ข the database connection is fine,
โ€ข maybe query one or more important tables to make sure that still works,
โ€ข make sure any 3rd party APIs are working,
โ€ข etc.

If any of those things has a problem, then it would return "500 Internal Server Error".

Else (if everything was fine then) it would return "200 OK".

0

A lot of Fediverse software has a HEALTH-CHECK URL.

But not all Fediverse does.

It would be better if ALL Fediverse software had a HEALTH-CHECK URL.

...

A HEALTH-CHECK URL is a special URL that tell others if the system is running properly.

It would return "200 OK" if everything is fine. And return "500 Internal Server Error" if there is a problem

...

A HEALTH-CHECK URL is important to those who actual run and administrate Fediverse servers

0

BotKit 0.2.0 ๋ฆด๋ฆฌ์Šค

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

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

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

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์˜ ์ง€์›์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

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

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

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

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

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"]
}

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

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

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

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

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


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

3

BotKit 0.2.0 Released

We're pleased to announce the release of BotKit 0.2.0! For those new to our project, is a framework for creating standalone bots that can interact with Mastodon, Misskey, and other 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 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 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.

BotKit 0.2.0 ๋ฆด๋ฆฌ์Šค

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

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

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

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์˜ ์ง€์›์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

0

BotKit 0.2.0 Released

We're pleased to announce the release of BotKit 0.2.0! For those new to our project, is a framework for creating standalone bots that can interact with Mastodon, Misskey, and other 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 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 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.

1
1
0

Coming soon in 0.2.0: Native post support!

We're excited to share a preview of the upcoming quoting features in BotKit 0.2.0. This update will make it easier for your bots to engage with quoted content across the fediverse.

The quoting feature set includes:

Here's a quick example of how you can use the quote detection:

bot.onQuote = async (session, quote) => {
  // The quote parameter is a Message object representing the post that quoted your bot
  await quote.reply(text`Thanks for quoting my post, ${quote.actor}!`);
  
  // You can access the original quoted message
  const originalPost = quote.quoteTarget;
  console.log(`Original message: ${originalPost?.text}`);
};

And creating quote posts is just as simple:

// Quote in a new post
await session.publish(
  text`I'm quoting this interesting message!`,
  { quoteTarget: someMessage }
);

// Or quote in a reply
await message.reply(
  text`Interesting point! I'm quoting another relevant post here.`,
  { quoteTarget: anotherMessage }
);

Remember that quoting behavior may vary across different implementationsโ€”some platforms like Misskey display quotes prominently, while others like Mastodon might implement them differently.

Want to try these features right now? You can install the development version from JSR:

deno add jsr:@fedify/botkit@0.2.0-dev.90+d6ab4bdc

We're looking forward to seeing how you use these quoting capabilities in your bots!

0

We're excited to introduce emoji reactions in the upcoming 0.2.0 release!

With the new Message.react() method, your bot can now react to messages using standard Unicode :

await message.react(emoji`๐Ÿ‘`);

support is also included, allowing your bot to react with server-specific emojis:

const emojis = bot.addCustomEmojis({
  // Use a remote image URL:
  yesBlob: {
    url: "https://cdn3.emoji.gg/emojis/68238-yesblob.png",
    mediaType: "image/png",
  },
  // Use a local image file:
  noBlob: {
    file: `${import.meta.dirname}/emojis/no_blob.png`,
    mediaType: "image/webp",
  },
});

await message.react(emojis.yesBlob);

Reactions can be removed using the AuthorizedReaction.unreact() method:

const reaction = await message.react(emoji`โค๏ธ`);
await reaction.unreact();

Want to try these features now? You can install the development version from JSR today:

deno add jsr:@fedify/botkit@0.2.0-dev.84+c997c6a6

We're looking forward to seeing how your bots express themselves with this new feature!

1

We're excited to announce that 0.2.0 will introduce custom emoji support! This feature allows your bots to express themselves with more personality and engagement.

What's included:

  • Add custom emojis to your bot with Bot.addCustomEmojis()
  • Use emoji in messages with the customEmoji() function
  • Support for both local image files and remote URLs as emoji sources
  • Full integration with BotKit's text formatting system

Simple example:

// Define custom emojis
const emojis = bot.addCustomEmojis({
  botkit: { file: "./botkit.png", type: "image/png" },
  fedify: { url: "https://fedify.dev/logo.png", type: "image/png" }
});

// Use in messages
await session.publish(
  text`Hello world! ${customEmoji(emojis.botkit)}`
);

Want to try it early? You can install the development version from JSR today:

deno add jsr:@fedify/botkit@0.2.0-dev.82+8a0438e6

1

ํ˜น์‹œ ๋ชจ๋ฅด๊ณ  ๊ณ„์…จ๋‹ค๋ฉด, Fedify๋Š” Discord์™€ Matrix ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ์šด์˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ณณ์—์„œ ๋„์›€์„ ๋ฐ›๊ฑฐ๋‚˜, ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜๊ฑฐ๋‚˜, ActivityPub์™€ ์—ฐํ•ฉ ์†Œ์…œ ๋„คํŠธ์›Œํฌ์— ๋Œ€ํ•ด ๋Œ€ํ™”๋ฅผ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ๋ถ„์˜ ์„ ํ˜ธ๋„์— ๋”ฐ๋ผ ์–ด๋А ์ปค๋ฎค๋‹ˆํ‹ฐ๋“  ์ฐธ์—ฌํ•ด ์ฃผ์„ธ์š”. ๋‘ ์ฑ„๋„ ๋ชจ๋‘ Fedify์™€ ์—ฐํ•ฉ ๊ด€๋ จ ์ฃผ์ œ์— ๋Œ€ํ•œ ํ™œ๋ฐœํ•œ ๋…ผ์˜๊ฐ€ ์ด๋ฃจ์–ด์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ใ‚‚ใ—ใ‹ใ—ใŸใ‚‰ใ”ๅญ˜ใ˜ใชใ„ใ‹ใ‚‚ใ—ใ‚Œใพใ›ใ‚“ใŒใ€Fedifyใซใฏ DiscordใจMatrixใฎใ‚ณใƒŸใƒฅใƒ‹ใƒ†ใ‚ฃใŒใ‚ใ‚Šใพใ™ใ€‚ใ“ใ“ใงใฏใ€ใ‚ตใƒใƒผใƒˆใ‚’ๅ—ใ‘ใŸใ‚Šใ€ๆฉŸ่ƒฝใซใคใ„ใฆ่ญฐ่ซ–ใ—ใŸใ‚Šใ€ActivityPubใ‚„ใƒ•ใ‚งใƒ‡ใƒฌใƒผใƒ†ใƒƒใƒ‰ใ‚ฝใƒผใ‚ทใƒฃใƒซใƒใƒƒใƒˆใƒฏใƒผใ‚ฏใซใคใ„ใฆ่ฉฑใ—ๅˆใ†ใ“ใจใŒใงใใพใ™ใ€‚

ใŠๅฅฝใฟใฎใ‚ณใƒŸใƒฅใƒ‹ใƒ†ใ‚ฃใซใ”ๅ‚ๅŠ ใใ ใ•ใ„ใ€‚ใฉใกใ‚‰ใฎใƒใƒฃใƒณใƒใƒซใงใ‚‚ใ€Fedifyใ‚„ใƒ•ใ‚งใƒ‡ใƒฌใƒผใ‚ทใƒงใƒณ้–ข้€ฃใฎใƒˆใƒ”ใƒƒใ‚ฏใซใคใ„ใฆๆดป็™บใช่ญฐ่ซ–ใŒ่กŒใ‚ใ‚Œใฆใ„ใพใ™ใ€‚

0

In case you weren't aware, has both and communities where you can get help, discuss features, or just chat about and federated social networks.

Feel free to join either community based on your preference. Both channels have active discussions about Fedify and federation topics.

ํ˜น์‹œ ๋ชจ๋ฅด๊ณ  ๊ณ„์…จ๋‹ค๋ฉด, Fedify๋Š” Discord์™€ Matrix ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ์šด์˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ณณ์—์„œ ๋„์›€์„ ๋ฐ›๊ฑฐ๋‚˜, ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ๋…ผ์˜ํ•˜๊ฑฐ๋‚˜, ActivityPub์™€ ์—ฐํ•ฉ ์†Œ์…œ ๋„คํŠธ์›Œํฌ์— ๋Œ€ํ•ด ๋Œ€ํ™”๋ฅผ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ๋ถ„์˜ ์„ ํ˜ธ๋„์— ๋”ฐ๋ผ ์–ด๋А ์ปค๋ฎค๋‹ˆํ‹ฐ๋“  ์ฐธ์—ฌํ•ด ์ฃผ์„ธ์š”. ๋‘ ์ฑ„๋„ ๋ชจ๋‘ Fedify์™€ ์—ฐํ•ฉ ๊ด€๋ จ ์ฃผ์ œ์— ๋Œ€ํ•œ ํ™œ๋ฐœํ•œ ๋…ผ์˜๊ฐ€ ์ด๋ฃจ์–ด์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

0

In case you weren't aware, has both and communities where you can get help, discuss features, or just chat about and federated social networks.

Feel free to join either community based on your preference. Both channels have active discussions about Fedify and federation topics.

0
0

As someone who has developed several software implementations (Fedify, Hollo, BotKit, and Hackers' Pub), I believe one of the most frustrating features to implement in the is .

The challenges are numerous:

First, there's no standardization. ActivityPub specifications don't define how custom emoji should work, leading to inconsistent implementations across different servers like Mastodon and Misskey.

Rendering is particularly problematic. Emojis must display properly across different contexts (in text, as reactions, in emoji pickers) while maintaining quality at various sizes. Animated emojis add another layer of complexity.

Perhaps most concerning is the poor . Most implementations simply use the emoji code (like :party_blob:) as the alt text, which provides no meaningful information to screen reader users (in particular, non-English speakers) about what the emoji actually depicts or means.

What really dampens my motivation to implement this feature is knowing I'm investing significant effort into something that ultimately creates accessibility barriers. It's disheartening to work hard on a feature that excludes part of the community.

3
6
1