Fedify: an ActivityPub server framework's avatar

Fedify: an ActivityPub server framework

@fedify@hollo.social · 8 following · 724 followers

:fedify: Fedify is a TypeScript library for building federated server apps powered by ActivityPub and other standards, so-called fediverse. It aims to eliminate the complexity and redundant boilerplate code when building a federated server app, so that you can focus on your business logic and user experience.

Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social

🎉 Excited to announce that is now on Open Collective! Support the project's development starting at:

  • Backer (from $5/mo)
  • Supporter (from $25/mo)
  • Sponsor (from $100/mo)
  • Corporate Sponsor (from $500/mo)
  • Custom donations welcome

Your support will help us maintain and improve Fedify. Check it out here:

https://opencollective.com/fedify

:fedify:

Fedify's Open Collective page showing the project logo, description as “A TypeScript library for building federated server apps powered by ActivityPub and other standards”, and five contribution tiers starting from $5/month Backer to $500/month Corporate Sponsor, with custom contribution options available.
ALT text detailsFedify's Open Collective page showing the project logo, description as “A TypeScript library for building federated server apps powered by ActivityPub and other standards”, and five contribution tiers starting from $5/month Backer to $500/month Corporate Sponsor, with custom contribution options available.
Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social

Fedify is an server framework in & . It aims to eliminate the complexity and redundant boilerplate code when building a federated server app, so that you can focus on your business logic and user experience.

The key features it provides currently are:

If you're curious, take a look at the website! There's comprehensive docs, a demo, a tutorial, example code, and more:

https://fedify.dev/

Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social · Reply to Chris​‌​‬ Hayes‌​​​'s post

@chris_hayes Thank you for letting us know! Fixed!

Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social · Reply to Fedify: an ActivityPub server framework's post

:botkit: スタンドアロンのActivityPubボットを作成するためのTypeScriptフレームワーク、BotKitを発表します!

一般的なMastodonボットとは異なり、BotKitで作成したボットは、プラットフォームの制約なく完全に独立して動作するFediverseボットです。シンプルで直感的なAPIにより、TypeScriptファイル1つでボットを作成できます。

現在はDenoのみの対応で、今後Node.jsとBunのサポートも予定しています。堅牢なFedifyをベースに開発されています。

https://botkit.fedify.dev/

Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social · Reply to Fedify: an ActivityPub server framework's post

:botkit: 독립형 ActivityPub 봇을 만들기 위한 TypeScript 프레임워크인 BotKit을 소개합니다!

일반적인 Mastodon 봇과 달리, BotKit으로 만든 봇은 플랫폼의 제약 없이 완전히 독립적으로 동작하는 연합우주(fediverse) 봇입니다. 간단하고 직관적인 API로 TypeScript 파일 하나만으로도 봇을 만들 수 있어요.

현재는 Deno만 지원하지만, Node.js와 Bun 지원도 계획하고 있습니다. 견고한 Fedify 기반으로 제작되었습니다.

https://botkit.fedify.dev/

Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social

:botkit: Introducing : A framework for creating truly standalone bots!

Unlike traditional Mastodon bots, BotKit lets you build fully independent bots that aren't constrained by platform limits. Create your entire bot in a single TypeScript file using our simple, expressive API.

Currently -only, with Node.js & Bun support planned. Built on the robust foundation.

https://botkit.fedify.dev/

import {
  createBot,
  InProcessMessageQueue,
  MemoryKvStore,
  mention,
  text,
} from "@fedify/botkit";

// Create a bot instance:
const bot = createBot<void>({
  // The bot will have fediverse handle "@greetbot@mydomain":
  username: "greetbot",
  // Set the display name:
  name: "Greet Bot",
  // Set the profile icon (avatar):
  icon: new URL("https://mydomain/icon.png"),
  // Set the bio:
  summary: text`Hi, there! I'm a simple fediverse bot created by ${
    mention("@hongminhee@hollo.social")}.`,
  // Store data in memory (for development):
  kv: new MemoryKvStore(),
  // Use in-process message queue (for development):
  queue: new InProcessMessageQueue(),
});

// A bot can respond to a mention:
bot.onMention = async (session, message) => {
  await message.reply(text`Hi, ${message.actor}!`);
};

// Or, a bot also can actively publish a post:
const session = bot.getSession("https://mydomain/");
setInterval(async () => {
  await session.publish(text`Hi, forks! It's an hourly greeting.`);
}, 1000 * 60 * 60);

export default bot;
ALT text detailsimport { createBot, InProcessMessageQueue, MemoryKvStore, mention, text, } from "@fedify/botkit"; // Create a bot instance: const bot = createBot<void>({ // The bot will have fediverse handle "@greetbot@mydomain": username: "greetbot", // Set the display name: name: "Greet Bot", // Set the profile icon (avatar): icon: new URL("https://mydomain/icon.png"), // Set the bio: summary: text`Hi, there! I'm a simple fediverse bot created by ${ mention("@hongminhee@hollo.social")}.`, // Store data in memory (for development): kv: new MemoryKvStore(), // Use in-process message queue (for development): queue: new InProcessMessageQueue(), }); // A bot can respond to a mention: bot.onMention = async (session, message) => { await message.reply(text`Hi, ${message.actor}!`); }; // Or, a bot also can actively publish a post: const session = bot.getSession("https://mydomain/"); setInterval(async () => { await session.publish(text`Hi, forks! It's an hourly greeting.`); }, 1000 * 60 * 60); export default bot;
Julian Fietkau's avatar
Julian Fietkau

@julian@fietkau.social

The last "big" code thing I need to get done before the alpha test of my current @fedify project is the task queue - make sure routine data updates happen, consider individual importance and urgency, respect external API rate limits, etc.

But that's super intimidating so I'm currently procrastinating by making it a cute lil home page instead. 🙃

Photo of a monitor showing some CSS code. The code hints at a website where images are animated and zoomed.
ALT text detailsPhoto of a monitor showing some CSS code. The code hints at a website where images are animated and zoomed.
Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social · Reply to Fedify: an ActivityPub server framework's post

Okay, the patch was merged today, and the fix will be shipped in Akkoma's next release!

ssig33's avatar
ssig33

@ssig33@hollo.ssig33.com

あんま人の悪口言いたくないけど「なんか起きても読む気になれない」みたいなコードを運用していたので、この点においてfedifyは最高

ssig33's avatar
ssig33

@ssig33@hollo.ssig33.com

fedifyつかって自分もミニマムななにかを作ってみる必要がある気がするし、それは正月の遊びとして最高に楽しそうだな

Alejandro Baez's avatar
Alejandro Baez

@zeab@fosstodon.org

Now that I got some fond memories of (read: Stockholm Syndrome), I sort of want to build stuff with . 😅

Though what I *really* want is an option like it for . Maybe a project for the new year. 🤔

Not like we don't have , , , and as examples of what could be a standard library. 😄

fedify.dev/

Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social

Are you getting the following error when trying to look up any Activity Streams objects from that contain custom emojis?

jsonld.SyntaxError: Invalid JSON-LD syntax; "@id" value must a string.

This is because they represent an Emoji object as an invalid JSON-LD object. Fortunately, this patch fixes that issue, so keep an eye out for it.

Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social

Since 1.4.0, Object will have the emojiReactions property, which corresponds to the fedibird:emojiReactions property extended by .

洪 民憙 (Hong Minhee)'s avatar
洪 民憙 (Hong Minhee)

@hongminhee@hollo.social

I'm currently brainstorming a framework for creating fediverse bots called , based on . It's less flexible than Fedify, but the goal is to make it possible to create simple fediverse bots with much less code. What do you think?

import { createBot, mention, text } from "@fedify/botkit";
import { RedisKvStore } from "@fedify/redis";
import { Redis } from "ioredis";

// Create a bot instance:
const bot = createBot({
  // The bot will have fediverse handle "@greetbot@mydomain":
  username: "greetbot",
  // Set the profile icon (avatar):
  icon: new URL("https://mydomain/icon.png"),
  // Set the bio:
  bio: text`Hi, there! I'm a simple fediverse bot created by ${
    mention("@hongminhee@hollo.social").}`,
  // Use Redis as a key-value store:
  kv: new RedisKvStore(new Redis()),
  // Use Redis as a message queue:
  queue: new RedisMessageQueue(() => new Redis()),
});

// A bot can respond to a mention:
bot.on(/hi|hello|what'?s\s+up/i, (ctx) => {
  return ctx.reply(text`Hi, ${ctx.actor}!`);
});

// Or, a bot also can actively publish a post:
setInterval(async () => {
  await bot.publish(text`Hi, forks! It's an hourly greeting.`);
}, 1000 * 60 * 60);

export default bot;
ALT text detailsimport { createBot, mention, text } from "@fedify/botkit"; import { RedisKvStore } from "@fedify/redis"; import { Redis } from "ioredis"; // Create a bot instance: const bot = createBot({ // The bot will have fediverse handle "@greetbot@mydomain": username: "greetbot", // Set the profile icon (avatar): icon: new URL("https://mydomain/icon.png"), // Set the bio: bio: text`Hi, there! I'm a simple fediverse bot created by ${ mention("@hongminhee@hollo.social").}`, // Use Redis as a key-value store: kv: new RedisKvStore(new Redis()), // Use Redis as a message queue: queue: new RedisMessageQueue(() => new Redis()), }); // A bot can respond to a mention: bot.on(/hi|hello|what'?s\s+up/i, (ctx) => { return ctx.reply(text`Hi, ${ctx.actor}!`); }); // Or, a bot also can actively publish a post: setInterval(async () => { await bot.publish(text`Hi, forks! It's an hourly greeting.`); }, 1000 * 60 * 60); export default bot;
Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social · Reply to silverpill's post

@silverpill It looks great! Could it be applied to likes and emoji reactions?

silverpill's avatar
silverpill

@silverpill@mitra.social · Reply to Fedify: an ActivityPub server framework's post

@fedify

I am going to implement Conversation Containers instead of inbox forwarding. This mechanism keeps conversations synchronized, but also enables backfilling and moderation of replies.

Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social

A Call for Better Activity Signatures in the Fediverse

Why Major ActivityPub Implementations Should Adopt Object Integrity Proofs

Let's say you have accounts named alice@bar and bob@baz that don't follow each other, but they both follow john@foo. When alice@bar replies to john@foo's post, how can bob@baz see this reply?

This problem applies not only to replies, but also to things like likes and emoji reactions. One of the ways that ActivityPub implementations solve this problem is through inbox forwarding. The idea is to forward the reply received by john@foo to bob@baz as well.

Fedify makes inbox forwarding easy and convenient with its forwardActivity() method. But the question is, can bob@baz trust the activity forwarded by john@foo?

Because HTTP Signatures sign the HTTP request that contains the activity, not the activity itself, john@foo can't sign an activity created by alice@bar when it's forwarded by him, because forwarding requires creating a new HTTP request. (The HTTP request includes things like the Host header, so a new signature is required for each new recipient.)

So, alice@bar needs to sign her activity in a way that allows john@foo to forward it. In the fediverse, there are two ways to do this: Linked Data Signatures and Object Integrity Proofs. Fedify automatically attaches all three types of signatures (HTTP Signatures, Linked Data Signatures, and Object Integrity Proofs) to every activity it sends, so activities are free to be forwarded between ActivityPub software created with Fedify.

However, major ActivityPub implementations such as Mastodon and Misskey still sign activities with HTTP Signatures only, or only some activities with Linked Data Signatures. (Note that Linked Data Signatures is an outdated standard, and Object Integrity Proofs are recommended.)

So, why are we talking about this at length? We strongly urge major ActivityPub implementations to adopt Object Integrity Proofs, or at minimum Linked Data Signatures, for activity signing!

Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social

A Call for Better Activity Signatures in the Fediverse

Why Major ActivityPub Implementations Should Adopt Object Integrity Proofs

Let's say you have accounts named alice@bar and bob@baz that don't follow each other, but they both follow john@foo. When alice@bar replies to john@foo's post, how can bob@baz see this reply?

This problem applies not only to replies, but also to things like likes and emoji reactions. One of the ways that ActivityPub implementations solve this problem is through inbox forwarding. The idea is to forward the reply received by john@foo to bob@baz as well.

Fedify makes inbox forwarding easy and convenient with its forwardActivity() method. But the question is, can bob@baz trust the activity forwarded by john@foo?

Because HTTP Signatures sign the HTTP request that contains the activity, not the activity itself, john@foo can't sign an activity created by alice@bar when it's forwarded by him, because forwarding requires creating a new HTTP request. (The HTTP request includes things like the Host header, so a new signature is required for each new recipient.)

So, alice@bar needs to sign her activity in a way that allows john@foo to forward it. In the fediverse, there are two ways to do this: Linked Data Signatures and Object Integrity Proofs. Fedify automatically attaches all three types of signatures (HTTP Signatures, Linked Data Signatures, and Object Integrity Proofs) to every activity it sends, so activities are free to be forwarded between ActivityPub software created with Fedify.

However, major ActivityPub implementations such as Mastodon and Misskey still sign activities with HTTP Signatures only, or only some activities with Linked Data Signatures. (Note that Linked Data Signatures is an outdated standard, and Object Integrity Proofs are recommended.)

So, why are we talking about this at length? We strongly urge major ActivityPub implementations to adopt Object Integrity Proofs, or at minimum Linked Data Signatures, for activity signing!

Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social

Did you know? Fedify allows you to customize the links in WebFinger responses. Just put your Link objects in the urls property of the Actor object returned by the actor dispatcher!

https://unstable.fedify.dev/manual/actor#webfinger-links

The related section of the Fedify docs. See also the link.
ALT text detailsThe related section of the Fedify docs. See also the link.
Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social · Reply to Fedify: an ActivityPub server framework's post

年末にやってみたいサイドプロジェクトをお探しですか?Fedifyを使って自分だけのActivityPubサーバーを作ってみてはいかがですか?

https://github.com/dahlia/fedify-microblog-tutorial-ja

Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social · Reply to Fedify: an ActivityPub server framework's post

연말에 할 사이드 프로젝트를 찾고 계신가요? Fedify를 이용해 여러분만의 ActivityPub 서버를 만들어 보는 것은 어떠세요?

https://hackmd.io/@hongminhee/fedify-tutorial-ko

Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social

Looking for a side project to do over the holidays? Why not create your own server with ?

https://fedify.dev/tutorial/microblog

洪 民憙 (Hong Minhee)'s avatar
洪 民憙 (Hong Minhee)

@hongminhee@hollo.social · Reply to るみ㌨Да's post

@Rumisan 私はChatGPTではなくClaudeを使っていますが、Claudeのプロジェクト機能を活用して、プロジェクトにFedifyのドキュメントを全て入れて質問しています。実際にチュートリアルやサンプルコードをそうやって生成した事も有ります!

Claudeを使ってFedifyとHonoを連動させた簡単なActivityPubアプリを作った様子
ALT text detailsClaudeを使ってFedifyとHonoを連動させた簡単なActivityPubアプリを作った様子
Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social

Since 1.4.0, our next release, the fedify lookup command will have the -t/--traverse option! It takes a URL of the collection, and traverse its items from the beginning to the end. Here's a demo:

The demo session of the -t/--traverse option which will be introduced to the fedify lookup command since Fedify 1.4.0.
ALT text detailsThe demo session of the -t/--traverse option which will be introduced to the fedify lookup command since Fedify 1.4.0.
S.H.@Haloはいいぞ's avatar
S.H.@Haloはいいぞ

@S_H_@gamelinks007.net

とりあえず、最近fedifyでDevContainer経由で建てたローカルのリレーサーバとMastodonでリレーの処理が確認できそうなことがわかったんで動作確認手順まとめてます

S.H.@Haloはいいぞ's avatar
S.H.@Haloはいいぞ

@S_H_@gamelinks007.net

そういやリレーサーバの疎通確認、fedify tunnel使ってできたよ

S.H.@Haloはいいぞ's avatar
S.H.@Haloはいいぞ

@S_H_@gamelinks007.net · Reply to 洪 民憙 (Hong Minhee)'s post

@hongminhee
Yay!

발리스네리아's avatar
발리스네리아

@vallis_neria@bakedbean.xyz

fedify 튜토리얼 읽어봐야지..

洪 民憙 (Hong Minhee)'s avatar
洪 民憙 (Hong Minhee)

@hongminhee@hollo.social

「Fedifyの長所:Denoで動くけど、DenoはRustコードに埋め込みやすい(??)」

https://mitir.social/notes/a1loh2gwn3

Chris​‌​‬ Hayes‌​​​'s avatar
Chris​‌​‬ Hayes‌​​​

@chris_hayes@fosstodon.org

I made a thing. You can put a Mastodon post URL in the search box and it will show the post.

fediverse.hayes.software

I was learning and I wanted to make a minimal Next.js example of a "read-only" app that was for consuming the Fediverse and didn't mess with interactions. It started as a boilerplate to benefit other devs, but the act of making it forced me to learn a lot more about Fedify and ActivityPub.

A screenshot showing 2 browser windows, one in landscape format, one in portrait format, to represent desktop and mobile viewports. The design is very yellow and sepia-ish showing a toot and an image next to it. A lot of brush and marker strokes are incorporated into the design. Otherwise the design is minimal.
ALT text detailsA screenshot showing 2 browser windows, one in landscape format, one in portrait format, to represent desktop and mobile viewports. The design is very yellow and sepia-ish showing a toot and an image next to it. A lot of brush and marker strokes are incorporated into the design. Otherwise the design is minimal.
Fedify: an ActivityPub server framework's avatar
Fedify: an ActivityPub server framework

@fedify@hollo.social · Reply to Chris​‌​‬ Hayes‌​​​'s post

@chris_hayes Yes, it corresponds to the misskey:isCat property! According to the docs:

Used on actors to indicate that they in some way identify as a cat, expressed as a boolean value. If this property is set to true, displaying the actor or their notes will have some special effects attached in some clients.

Chris​‌​‬ Hayes‌​​​'s avatar
Chris​‌​‬ Hayes‌​​​

@chris_hayes@fosstodon.org

I was looking at the properties on the Person object implemented by , and wasn't expecting this one, haha!

I'm presuming this is related? The quirks of having to implement many different versions of a spec!

A screenshot of a code editor showing a TypeScript class Person with a property get cat(): boolean | null. The accompanying comment explains that the property is "used on actors to indicate that they in some way identify as a cat, expressed as a boolean value. If this property is set to true, displaying the actor or their notes will have some special effects attached in some clients."
ALT text detailsA screenshot of a code editor showing a TypeScript class Person with a property get cat(): boolean | null. The accompanying comment explains that the property is "used on actors to indicate that they in some way identify as a cat, expressed as a boolean value. If this property is set to true, displaying the actor or their notes will have some special effects attached in some clients."
← Newer
Older →