What is Hackers' Pub?

Hackers' Pub is a place for software engineers to share their knowledge and experience with each other. It's also an ActivityPub-enabled social network, so you can follow your favorite hackers in the fediverse and get their latest posts in your feed.

OpenAI 要辦社群媒體很自然,像馬斯克有X既可以訓練Grok也可以推銷Grok,簡直永動機一樣的生態循環,Altman羨慕得不得了,那就自己也辦一個。

0
0
3

OpenAI 要辦社群媒體很自然,像馬斯克有X既可以訓練Grok也可以推銷Grok,簡直永動機一樣的生態循環,Altman羨慕得不得了,那就自己也辦一個。

0
0
2
0
0
0
0
0
0
0
0

[오그랲] "요즘 챗GPT가 제일 다정함" AI와의 대화에 빠진 사람들
혹시 여러분은 학교나 회사에서 받은 스트레스를 AI에게 털어놓은 적이 있나요? 최근 유튜브에서는 AI와 대화하는 영상이 인기를 끌고, 주변에서도 AI에게 마음속 이야기를 나누는 사람들이 늘어나고 있습니다.
news.sbs.co.kr/news/endPage.do

0
0
0

Ricardo Zylbergeld⁂ shared the below article:

Ditch the DIY Drama: Why Use Fedify Instead of Building ActivityPub from Scratch?

洪 民憙 (Hong Minhee) @hongminhee@hackers.pub

So, you're captivated by the fediverse—the decentralized social web powered by protocols like ActivityPub. Maybe you're dreaming of building the next great federated app, a unique space connected to Mastodon, Lemmy, Pixelfed, and more. The temptation to dive deep and implement ActivityPub yourself, from the ground up, is strong. Total control, right? Understanding every byte? Sounds cool!

But hold on a sec. Before you embark on that epic quest, let's talk reality. Implementing ActivityPub correctly isn't just one task; it's like juggling several complex standards while riding a unicycle… blindfolded. It’s hard.

That's where Fedify comes in. It's a TypeScript framework designed to handle the gnarliest parts of ActivityPub development, letting you focus on what makes your app special, not reinventing the federation wheel.

This post will break down the common headaches of DIY ActivityPub implementation and show how Fedify acts as the super-powered pain reliever, starting with the very foundation of how data is represented.

Challenge #1: Data Modeling—Speaking ActivityStreams & JSON-LD Fluently

At its core, ActivityPub relies on the ActivityStreams 2.0 vocabulary to describe actions and objects, and it uses JSON-LD as the syntax to encode this vocabulary. While powerful, this combination introduces significant complexity right from the start.

First, understanding and correctly using the vast ActivityStreams vocabulary itself is a hurdle. You need to model everything—posts (Note, Article), profiles (Person, Organization), actions (Create, Follow, Like, Announce)—using the precise terms and properties defined in the specification. Manual JSON construction is tedious and prone to errors.

Second, JSON-LD, the encoding layer, has specific rules that make direct JSON manipulation surprisingly tricky:

  • Missing vs. Empty Array: In JSON-LD, a property being absent is often semantically identical to it being present with an empty array. Your application logic needs to treat these cases equally when checking for values. For example, these two Note objects mean the same thing regarding the name property:
    // No name property
    {
      "@context": "https://www.w3.org/ns/activitystreams",
      "type": "Note",
      "content": ""
    }
    // Equivalent to:
    {
      "@context": "https://www.w3.org/ns/activitystreams",
      "type": "Note",
      "name": [],
      "content": ""
    }
  • Single Value vs. Array: Similarly, a property holding a single value directly is often equivalent to it holding a single-element array containing that value. Your code must anticipate both representations for the same meaning, like for the content property here:
    // Single value
    {
      "@context": "https://www.w3.org/ns/activitystreams",
      "type": "Note",
      "content": "Hello"
    }
    // Equivalent to:
    {
      "@context": "https://www.w3.org/ns/activitystreams",
      "type": "Note",
      "content": ["Hello"]
    }
  • Object Reference vs. Embedded Object: Properties can contain either the full JSON-LD object embedded directly or just a URI string referencing that object. Your application needs to be prepared to fetch the object's data if only a URI is given (a process called dereferencing). These two Announce activities are semantically equivalent (assuming the URIs resolve correctly):
    {
      "@context": "https://www.w3.org/ns/activitystreams",
      "type": "Announce",
      // Embedded objects:
      "actor": {
        "type": "Person",
        "id": "http://sally.example.org/",
        "name": "Sally"
      },
      "object": {
        "type": "Arrive",
        "id": "https://sally.example.com/arrive",
        /* ... */
      }
    }
    // Equivalent to:
    {
      "@context":
      "https://www.w3.org/ns/activitystreams",
      "type": "Announce",
      // URI references:
      "actor": "http://sally.example.org/",
      "object": "https://sally.example.com/arrive"
    }

Attempting to manually handle all these vocabulary rules and JSON-LD variations consistently across your application inevitably leads to verbose, complex, and fragile code, ripe for subtle bugs that break federation.

Fedify tackles this entire data modeling challenge with its comprehensive, type-safe Activity Vocabulary API. It provides TypeScript classes for ActivityStreams types and common extensions, giving you autocompletion and compile-time safety. Crucially, these classes internally manage all the tricky JSON-LD nuances. Fedify's property accessors present a consistent interface—non-functional properties (like tags) always return arrays, functional properties (like content) always return single values or null. It handles object references versus embedded objects seamlessly through dereferencing accessors (like activity.getActor()) which automatically fetch remote objects via URI when needed—a feature known as property hydration. With Fedify, you work with a clean, predictable TypeScript API, letting the framework handle the messy details of AS vocabulary and JSON-LD encoding.

Challenge #2: Discovery & Identity—Finding Your Actors

Once you can model data, you need to make your actors discoverable. This primarily involves the WebFinger protocol (RFC 7033). You'd need to build a server endpoint at /.well-known/webfinger capable of parsing resource queries (like acct: URIs), validating the requested domain against your server, and responding with a precisely formatted JSON Resource Descriptor (JRD). This JRD must include specific links, like a self link pointing to the actor's ActivityPub ID using the correct media type. Getting any part of this wrong can make your actors invisible.

Fedify simplifies this significantly. It automatically handles WebFinger requests based on the actor information you provide through its setActorDispatcher() method. Fedify generates the correct JRD response. If you need more advanced control, like mapping user-facing handles to internal identifiers, you can easily register mapHandle() or mapAlias() callbacks. You focus on defining your actors; Fedify handles making them discoverable.

// Example: Define how to find actors
federation.setActorDispatcher(
  "/users/{username}",
  async (ctx, username) => { /* ... */ }
);
// Now GET /.well-known/webfinger?resource=acct:username@your.domain just works!

Challenge #3: Core ActivityPub Mechanics—Handling Requests and Collections

Serving actor profiles requires careful content negotiation. A request for an actor's ID needs JSON-LD for machine clients (Accept: application/activity+json) but HTML for browsers (Accept: text/html). Handling incoming activities at the inbox endpoint involves validating POST requests, verifying cryptographic signatures, parsing the payload, preventing duplicates (idempotency), and routing based on activity type. Implementing collections (outbox, followers, etc.) with correct pagination adds another layer.

Fedify streamlines all of this. Its core request handler (via Federation.fetch() or framework adapters like @fedify/express) manages content negotiation. You define actors with setActorDispatcher() and web pages with your framework (Hono, Express, SvelteKit, etc.)—Fedify routes appropriately. For the inbox, setInboxListeners() lets you define handlers per activity type (e.g., .on(Follow, ...)), while Fedify automatically handles validation, signature verification, parsing, and idempotency checks using its KV Store. Collection implementation is simplified via dispatchers (e.g., setFollowersDispatcher()); you provide logic to fetch a page of data, and Fedify constructs the correct Collection or CollectionPage with pagination.

// Define inbox handlers
federation.setInboxListeners("/inbox", "/users/{handle}/inbox")
  .on(Follow, async (ctx, follow) => { /* Handle follow */ })
  .on(Undo, async (ctx, undo) => { /* Handle undo */ });

// Define followers collection logic
federation.setFollowersDispatcher(
  "/users/{handle}/followers",
  async (ctx, handle, cursor) => { /* ... */ }
);

Challenge #4: Reliable Delivery & Asynchronous Processing—Sending Activities Robustly

Sending an activity requires more than a simple POST. Networks fail, servers go down. You need robust failure handling and retry logic (ideally with backoff). Processing incoming activities synchronously can block your server. Efficiently broadcasting to many followers (fan-out) requires background processing and using shared inboxes where possible.

Fedify addresses reliability and scalability using its MessageQueue abstraction. When configured (highly recommended), Context.sendActivity() enqueues delivery tasks. Background workers handle sending with automatic retries based on configurable policies (like outboxRetryPolicy). Fedify supports various queue backends (Deno KV, Redis, PostgreSQL, AMQP). For high-traffic fan-out, Fedify uses an optimized two-stage mechanism to distribute the load efficiently.

// Configure Fedify with a persistent queue (e.g., Deno KV)
const federation = createFederation({
  queue: new DenoKvMessageQueue(/* ... */),
  // ...
});
// Sending is now reliable and non-blocking
await ctx.sendActivity({ handle: "myUser" }, recipient, someActivity);

Challenge #5: Security—Avoiding Common Pitfalls

Securing an ActivityPub server is critical. You need to implement HTTP Signatures (draft-cavage-http-signatures-12) for server-to-server authentication—a complex process. You might also need Linked Data Signatures (LDS) or Object Integrity Proofs (OIP) based on FEP-8b32 for data integrity and compatibility. Managing cryptographic keys securely is essential. Lastly, fetching remote resources risks Server-Side Request Forgery (SSRF) if not validated properly.

Fedify is designed with security in mind. It automatically handles the creation and verification of HTTP Signatures, LDS, and OIP, provided you supply keys via setKeyPairsDispatcher(). It includes key management utilities. Crucially, Fedify's default document loader includes built-in SSRF protection, blocking requests to private IPs unless explicitly allowed.

Challenge #6: Interoperability & Maintenance—Playing Nicely with Others

The fediverse is diverse. Different servers have quirks. Ensuring compatibility requires testing and adaptation. Standards evolve with new Federation Enhancement Proposals (FEPs). You also need protocols like NodeInfo to advertise server capabilities.

Fedify aims for broad interoperability and is actively maintained. It includes features like ActivityTransformers to smooth over implementation differences. NodeInfo support is built-in via setNodeInfoDispatcher().

Challenge #7: Developer Experience—Actually Building Your App

Beyond the protocol, building any server involves setup, testing, and debugging. With federation, debugging becomes harder—was the message malformed? Was the signature wrong? Is the remote server down? Is it a compatibility quirk? Good tooling is essential.

Fedify enhances the developer experience significantly. Being built with TypeScript, it offers excellent type safety and editor auto-completion. The fedify CLI is a powerful companion designed to streamline common development tasks.

You can quickly scaffold a new project tailored to your chosen runtime and web framework using fedify init.

For debugging interactions and verifying data, fedify lookup is invaluable. It lets you inspect how any remote actor or object appears from the outside by performing WebFinger discovery and fetching the object's data. Fedify then displays the parsed object structure and properties directly in your terminal. For example, running:

$ fedify lookup @fedify-example@fedify-blog.deno.dev

Will first show progress messages and then output the structured representation of the actor, similar to this:

// Output of fedify lookup command (shows parsed object structure)
Person {
  id: URL "https://fedify-blog.deno.dev/users/fedify-example",
  name: "Fedify Example Blog",
  published: 2024-03-03T13:18:11.857Z, // Simplified timestamp
  summary: "This blog is powered by Fedify, a fediverse server framework.",
  url: URL "https://fedify-blog.deno.dev/",
  preferredUsername: "fedify-example",
  publicKey: CryptographicKey {
    id: URL "https://fedify-blog.deno.dev/users/fedify-example#main-key",
    owner: URL "https://fedify-blog.deno.dev/users/fedify-example",
    publicKey: CryptoKey { /* ... CryptoKey details ... */ }
  },
  // ... other properties like inbox, outbox, followers, endpoints ...
}

This allows you to easily check how data is structured or troubleshoot why an interaction might be failing by seeing the actual properties Fedify parsed.

Testing outgoing activities from your application during development is made much easier with fedify inbox. Running the command starts a temporary local server that acts as a publicly accessible inbox, displaying key information about the temporary actor it creates for receiving messages:

$ fedify inbox
✔ The ephemeral ActivityPub server is up and running: https://<unique_id>.lhr.life/
✔ Sent follow request to @<some_test_account>@activitypub.academy.
╭───────────────┬─────────────────────────────────────────╮
│ Actor handle: │ i@<unique_id>.lhr.life                  │
├───────────────┼─────────────────────────────────────────┤
│   Actor URI:  │ https://<unique_id>.lhr.life/i          │
├───────────────┼─────────────────────────────────────────┤
│  Actor inbox: │ https://<unique_id>.lhr.life/i/inbox    │
├───────────────┼─────────────────────────────────────────┤
│ Shared inbox: │ https://<unique_id>.lhr.life/inbox      │
╰───────────────┴─────────────────────────────────────────╯

Web interface available at: http://localhost:8000/

You then configure your developing application to send an activity to the Actor inbox or Shared inbox URI provided. When an activity arrives, fedify inbox only prints a summary table to your console indicating that a request was received:

╭────────────────┬─────────────────────────────────────╮
│     Request #: │ 2                                   │
├────────────────┼─────────────────────────────────────┤
│ Activity type: │ Follow                              │
├────────────────┼─────────────────────────────────────┤
│  HTTP request: │ POST /i/inbox                       │
├────────────────┼─────────────────────────────────────┤
│ HTTP response: │ 202                                 │
├────────────────┼─────────────────────────────────────┤
│       Details  │ https://<unique_id>.lhr.life/r/2    │
╰────────────────┴─────────────────────────────────────╯

Crucially, the detailed information about the received request—including the full headers (like Signature), the request body (the Activity JSON), and the signature verification status—is only available in the web interface provided by fedify inbox. This web UI allows you to thoroughly inspect incoming activities during development.

Screenshot of the Fedify Inbox web interface showing received activities and their details.
The Fedify Inbox web UI is where you view detailed activity information.

When you need to test interactions with the live fediverse from your local machine beyond just sending, fedify tunnel can securely expose your entire local development server temporarily. This suite of tools significantly eases the process of building and debugging federated applications.

Conclusion: Build Features, Not Plumbing

Implementing the ActivityPub suite of protocols from scratch is an incredibly complex and time-consuming undertaking. It involves deep dives into multiple technical specifications, cryptographic signing, security hardening, and navigating the nuances of a diverse ecosystem. While educational, it dramatically slows down the process of building the actual, unique features of your federated application.

Fedify offers a well-architected, secure, and type-safe foundation, handling the intricacies of federation for you—data modeling, discovery, core mechanics, delivery, security, and interoperability. It lets you focus on your application's unique value and user experience. Stop wrestling with low-level protocol details and start building your vision for the fediverse faster and more reliably. Give Fedify a try!

Getting started is straightforward. First, install the Fedify CLI using your preferred method. Once installed, create a new project template by running fedify init your-project-name.

Check out the Fedify tutorials and Fedify manual to learn more. Happy federating!

Read more →
13
0
3
0
0

Rijmpjes, of spreekwoorden uit de familie? Sommige zijn volgens mij bekender, anderen wellicht niet. Vooral aan de kant van mijn moeders vader zijn er wat juweeltjes.

Ik ben ze in de afgelopen tijd gaan verzamelen, want ik wil deze graag bewaren (al kan je ze niet altijd meer zeggen):

  • Men lijdt het meest voor het lijden dat men vreest.
  • Als alles meeloopt dan heb je optocht.
  • Dat lusten de zieke vrouwen van Scheveningen ook.
  • Als dat hoofd op een varkentje stond dan zou je zeggen dat beestje is ziek.
  • Steek je haar op en ga dienen. (over vrouwen met lang los haar)
  • Wie niet komt is vrij van heen gaan.
  • Die is als een dubbeltje geboren en zal nooit een kwartje worden.
  • Dat is als oude wijn in nieuwe zakken.

(update)

  • Met nieuwe moed en oude hekel.

(n.a.v. mstdn.social/@fonolog/11434644)

0
0
1
0
3

Yesterday at ICT.OPEN I also attended a panel discussion on "Bridging the Gap between Research and Industry through Application-Oriented AI Innovations"

It was mostly academics in the room, but I had an interesting chat with Dr. Floor Campfens and my colleague Dr. Anna Lukina afterwards, where we talked about the research done at RIWO, and of course our research at TU Delft.











Screenshot of an ongoing poll on the question "Academic focus on AI research and innovation is out of touch with the real-world problems faced by industry and public sector organisations."

The votes are as follows:

1. "Total Nonsense - academia is leading where it matters": 0 votes
2. "Mostly Untrue - there are real efforts to stay relevant": 6 votes
3. "Meh - hit or miss depending on the case": 25 votes
4. "Pretty accurate - ivory towers don't solve real problems": 5 votes
5. "Absolutely - academics are busy chasing citations, not impact": 1 votesSlide that introduces the panel: 
- Prof. dr. Anthony Thornton: Professor, University of Twente, CEO of MercuryLab
- Dr. Jeroen Linssen: Lector, Saxion University of Applied Sciences
- Dr. Floor Campfens: R&D Manager, project lead, Innovation RIWO
0
0
0
0
0
0
0
0
0

High Wind Warning, Delta Junction, 2025-04-15 23:57 AKDT.

WHAT...Southeast winds 40 to 60 mph with gusts up to 80 mph expected Delta Junction.

WHERE...Delta Junction.

WHEN...From 4 AM Wednesday to 1 PM AKDT Thursday.

IMPACTS...High winds may move loose debris, damage property and cause power outages. Travel could be difficult, especially for high profile vehicles.

https://forecast.weather.gov/MapClick.php?zoneid=AKZ837


0

트러스트 AI는
엄밀히 말하면 .. 그냥 경우의 수가 정해져있는 긴 자동 전투 프로그램일겁니다

우리가 생각하는... 그... 실시간으로 연산하고 변화가 반영되는 챗지피티같은 고능한 AI가 아니라 더더더더욱 유도리가 없읍니다

0

High Wind Warning, Northern Denali Borough, 2025-04-15 23:57 AKDT.

WHAT...Southeast winds 40 to 50 mph with gusts up to 80 mph expected.

WHERE...Northern Denali Borough.

WHEN...From 4 AM Wednesday to 10 AM AKDT Thursday.

IMPACTS...High winds may move loose debris, damage property and cause power outages. Travel could be difficult, especially for high profile vehicles.

https://forecast.weather.gov/MapClick.php?zoneid=AKZ847


0

High Wind Warning, Eastern Alaska Range North of Trims Camp, 2025-04-15 23:57 AKDT.

WHAT...South winds 40 to 60 mph with gusts up to 90 mph expected.

WHERE...Eastern Alaska Range North of Trims Camp.

WHEN...From 4 AM Wednesday to 10 AM AKDT Thursday.

IMPACTS...High winds may move loose debris, damage property and cause power outages. Travel could be difficult, especially for high profile vehicles.

https://forecast.weather.gov/MapClick.php?zoneid=AKZ849


0
0
0
0

트위터에서 돌던 자영업 당사자/가족의 지도 플로우에서 내가 가장 많이 느꼈던 건, 한국에서 너무나도 공격받기 쉬운 소수자성(성소수자, 이주민 2세 등)을 가진 사람들이 자신의 신원이 얼마나 퍼질지 모르는 공개된 SNS 공간에서 신원이 특정 될 수 있는데도 불구하고 가게를 홍보하고 나선다는 게 쉬운 일이 아니란 말이죠
그런데도 자신의 신원이 특정될 각오를 하고 홍보를 나서야 할 만큼 많이 불경기구나. 라는 생각에 씁쓸하기도 했고요…
동시에 자신의 소수자성이 공격 받을까 봐 계속 고민하다가 게시물을 올리지 못한 지인들의 고민을 보았기에 더더욱 가게 홍보를 올린 사람들이 공격 받지 않을 수 있도록 주의 깊게 봐야겠다는 생각까지 들었습니다

자신의 신원이 특정될 위험을 부담하면서까지 글을 게시하게 된 상황에 모두가 공감하며 분위기가 확장된 거였는데, 그런 가게에서 모두가 좋은 경험 만을 겪을 수는 없잖아요
음식이 입에 안 맞는다거나 아니면 사장님이 불친절했다거나 여타 일이 생겼을 때 발생하는 상황들. 그런 상황들에 대한 우려는 당연히 생길 수밖에 없고, 위 지도를 만들어주신 분들이 지도 설명에 모든 업체가 무조건 좋은 가게라 보장할 수는 없으니 사전에 가게 정보를 충분히 찾아보고 방문하기를 권유한 이유를 각자 한 번씩 생각해보는 것 또한 중요하겠다고도 생각합니다

0

영어로 대한민국 이름 찾을 때 난감하긴 함.

Korea / South Korea / Republic of Korea / Korea, Republic of / Korea (South) 까지가 일반적?인 표기들.

그리고...

Daehanminguk 은 도대체가 이해가 안 가지만 실제로 있었습니다. ㅋㅋㅋ

0
0

트위터에서 돌던 자영업 당사자/가족의 지도 플로우에서 내가 가장 많이 느꼈던 건, 한국에서 너무나도 공격받기 쉬운 소수자성(성소수자, 이주민 2세 등)을 가진 사람들이 자신의 신원이 얼마나 퍼질지 모르는 공개된 SNS 공간에서 신원이 특정 될 수 있는데도 불구하고 가게를 홍보하고 나선다는 게 쉬운 일이 아니란 말이죠
그런데도 자신의 신원이 특정될 각오를 하고 홍보를 나서야 할 만큼 많이 불경기구나. 라는 생각에 씁쓸하기도 했고요…
동시에 자신의 소수자성이 공격 받을까 봐 계속 고민하다가 게시물을 올리지 못한 지인들의 고민을 보았기에 더더욱 가게 홍보를 올린 사람들이 공격 받지 않을 수 있도록 주의 깊게 봐야겠다는 생각까지 들었습니다

자신의 신원이 특정될 위험을 부담하면서까지 글을 게시하게 된 상황에 모두가 공감하며 분위기가 확장된 거였는데, 그런 가게에서 모두가 좋은 경험 만을 겪을 수는 없잖아요
음식이 입에 안 맞는다거나 아니면 사장님이 불친절했다거나 여타 일이 생겼을 때 발생하는 상황들. 그런 상황들에 대한 우려는 당연히 생길 수밖에 없고, 위 지도를 만들어주신 분들이 지도 설명에 모든 업체가 무조건 좋은 가게라 보장할 수는 없으니 사전에 가게 정보를 충분히 찾아보고 방문하기를 권유한 이유를 각자 한 번씩 생각해보는 것 또한 중요하겠다고도 생각합니다

0
0

경제 / 추측을 담고 있으니 참조로만 하십시요.

조금씩 조금씩 🇯🇵의 기관(금융)들이 지수 매물 정리중 입니다.
일본은행 총재가 오늘 미국 관세를 언급하고 일본 금리를 올릴 수 있을지도 모른다고 합니다.
그 이후 USD-JYP Pair 가 내려가는 것으로 보아 큰 사건의 전조로 보입니다.
앤 캐리 청산보다 무서운게 올 수 있다는 의미
꽉 잡으십시요.

0
0
1
0