1
0
Fork
You've already forked hatter
0
A project to learn Elixir Phoenix
  • Elixir 81.4%
  • HTML 15.7%
  • JavaScript 2.4%
  • CSS 0.5%
ilja space 1ba6c456b1 go to /bots/:id after service bot creation
I also added some extra things who should be implemented after initial scope is done
2025年07月26日 08:43:25 +02:00
analysis go to /bots/:id after service bot creation 2025年07月26日 08:43:25 +02:00
assets Close the flash message using CSS 2025年05月18日 09:10:17 +02:00
config implement GET /accounts/reset_password/:token 2025年06月29日 12:35:02 +02:00
lib go to /bots/:id after service bot creation 2025年07月26日 08:43:25 +02:00
priv Creating a service bot handles errors 2025年07月10日 21:43:29 +02:00
test go to /bots/:id after service bot creation 2025年07月26日 08:43:25 +02:00
.formatter.exs Initial commit 2025年04月21日 18:43:29 +02:00
.gitignore ignore files from IDEs 2025年06月22日 09:13:49 +02:00
mix.exs Add ability to debug 2025年06月22日 19:44:06 +02:00
mix.lock Rename Repo module 2025年05月05日 08:44:04 +02:00
READING.md Bring READING.md somewhat up-to-date 2025年06月16日 06:01:50 +02:00
README.md go to /bots/:id after service bot creation 2025年07月26日 08:43:25 +02:00

Hatter

The goal of this repo is for me to gain some experience with a Phoenix project. Functionally I'd like this to be a fedi server, aimed at making service bots.

I want to focus mostly on the back-end work, and not so much on front-end. An instance for service bots seems to be a good fit for this.

Besides this, it seems like a fun idea to think about specifics a software with such aim would need.

For good practices I want to follow, see what I've learned in Movielounge, Mastermind and Yurt.

Starting Hatter

To setup or upgrade Hatter, you first need to get the latest code, then do the following;

# Update dependencies and database schema
mix deps.get
mix ecto.migrate
# Start Phoenix
mix phx.server
# For development, it may be handy to run in an `iex` shell
iex -S mix phx.server
# Or as a one-liner
mix deps.get; mix ecto.migrate; iex -S mix phx.server

Then visit localhost:4000 from the browser.

Note that this is only for development.

Problem solving

  • The database is the files in /db/, there is currently no guarantee that the schema is stable. It may be needed to remove the db files between updates (data will be lost).
  • To clear site data, you can go to localhost:4000/dev/clear-site-data, which will return a response header asking the browser to clear all data from the site. This can be useful if you develop applications who store data in browser cache, and they happen to use the same host:port as your hatter development setup.

Scope

Initial scope

  • Use separate parts for "web", "core", and "repo"
  • Create account
    • Has a fedi contact
      • instead of email
      • freeform string for now (later maybe ap_id or @-tag)
      • This must be assumed public information on the bot profile
      • redirect to login screen
  • Log in flow (everything created with mix phx.gen.auth Accounts Account accounts --hashing-lib argon2 --no-live, but rewritten to form I prefer)
    • get("/accounts/register", AccountRegistrationController, :new)
    • post("/accounts/register", AccountRegistrationController, :create)
    • get("/accounts/log_in", AccountSessionController, :new)
    • post("/accounts/log_in", AccountSessionController, :create)
    • get("/accounts/reset_password", AccountResetPasswordController, :new)
      • This has a text explaining where to get a link instead of a form. The reason is that we currently don't have a way to send the link.
    • post("/accounts/reset_password", AccountResetPasswordController, :create)
      • We currently do not have a way to deliver it to the person asking
      • In an iex session you can do for e.g. login_name "alice" and base url http://localhost:4000,
        • %{id: account_id} = HatterRepo.fetch_account_by_login_name("alice")
        • HatterRepo.all(HatterRepo.AccountToken, account_id: account_id) |> Enum.map(fn e -> "http:/localhost:4000/" <> Base.url_encode64(e.token) end)
    • get("/accounts/reset_password/:token", AccountResetPasswordController, :edit)
      • This is the password reset link. It either shows a page to reset the password, or it gives a notification that the token isn't valid (anymore)
    • put("/accounts/reset_password/:token", AccountResetPasswordController, :update)
      • It has a password reset field, which does a Put here. It then resets the password.
    • get("/accounts/settings", AccountSettingsController, :edit)
    • put("/accounts/settings", AccountSettingsController, :update)
    • get("/accounts/settings/confirm_email/:token", AccountSettingsController, :confirm_email)
      • After changing email. When going to this page, it's immediately confirmed
      • REMOVED, we do not use this bc we do not yet have working contact
    • delete("/accounts/log_out", AccountSessionController, :delete)
    • get("/accounts/confirm", AccountConfirmationController, :new)
      • Here you can provide your email to re-receive the conformation mail
      • REMOVED, we do not use this bc we do not yet have working contact
    • post("/accounts/confirm", AccountConfirmationController, :create)
      • Here the form at Get accounts/confirm posts to
      • REMOVED, we do not use this bc we do not yet have working contact
    • get("/accounts/confirm/:token", AccountConfirmationController, :edit)
      • Page with a "confirm my account" button
      • REMOVED, we do not use this bc we do not yet have working contact
    • post("/accounts/confirm/:token", AccountConfirmationController, :update)
      • When clicking the button on the "confirm my account" page
      • REMOVED, we do not use this bc we do not yet have working contact
    • remove deprecated things (i.e. things who were generated, but not required any more)
  • Create one or multiple (local) service bots
    • See /analysis/20250630_create_one_or_multiple_service_bots.md
  • Make a post
  • Get following (and unfollowing) working
  • Get basic AP working
  • Get reset password token work over fedi DM
  • Have some homepage or something on "GET /"
  • Have some about page or something somewhere
  • Preferably this all works without need for Javascript

Should have

Extra things who should be added, after an initial working concept is created

  • Edit service bot notes and profile
  • Profile picture for service bots
  • Make it look pretty (:
  • Scrub (or escape) html from html fields (eg profile)
  • Allow deleting of service bots, posts, accounts

Further scope

This software is aimed at automated bots, this is its scope and should be reflected in the features who are and aren't added. Some random ideas;

  • Auto expire of posts and media
  • different automations
    • post directly from web interface
    • post through http API with Bearer token (e.g. through AP-C2S API, Masto-API...)
    • crontab, random text from list
    • crontab, random picture
    • crontab, RSS (and maybe other) feed
    • "planet" service, follow specific accounts and boost their posts and announce if a specific hashtag was added to the post
    • "mention me and I reply", unsure how to decide what to reply. Maybe an http call and answer the reply? Or allow running a remote command over ssh? How secure is all that?
    • "make me follow you and I reply in certain conditions", unsure how to decide conditions and how to reply. Similar to "mention me and I reply".
  • Moderation for moderating bots and accounts
  • Close registrations based on metrics, e.g.
    • Always closed
    • Only allow X accounts
    • Only allow X bots
    • Only allow X amount of (DB/media) storage used
    • Only open registrations at certain moments
    • Approve queue when creating an account
  • Limit amount of allowed posting (e.g. throw error before going over, or delete older posts)
    • post frequency limit
    • Total amount of media
    • Total amount of posts
  • Discovery page
    • Public posts from services. Could have different filers; e.g. local, bubble, federated, marked as accepted...

Possible FEP's

The following are FEPs who may be interesting. Note that compatibility with current fedi is always a must.

Governance

As this is a project for me to gain basic experience and learn, it's basically a one person project. Don't expect it to be useful, and don't expect issues or PR's to be taken up.

Reading

See READING.md

License

 A fedi server aimed at service bots, as an exercise to learn Elixir's Phoenix framework
 Copyright (C) 2025 ilja@ilja.space
 This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
 You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.