需要关于 Discord 机器人架构的建议。

huangapple go评论82阅读模式
英文:

Need advice on architecture of a Discord bot

问题

什么是 Discord 角色?

角色是由服务器管理员创建的一组成员。角色具有权限、层级和名称。在这种情况下,重要的是玩家可以通过引用角色(如 @角色名称)来一次性地提及多个玩家("ping")。

背景信息:
我正在开发一个机器人,用于向用户分配临时角色。用户获取角色,以便其他人可以提及他们。角色根据用户的需求分配。机器人是用 Go 语言编写的。整个应用程序主要由处理 Mongo 事件和用户向机器人输入的命令的处理程序组成。

每当用户通过向机器人输入命令获取角色时,该用户的 Discord ID 将存储在 Mongo 数据库中,并设置过期时间。一旦达到文档中存储的时间,Mongo 将删除该文档(使用 TTL 索引进行删除)。然后,通过处理 Mongo 事件,机器人会从用户那里收回角色。(此外,用户也可以主动删除自己的角色。在这种情况下,角色将被收回,并从数据库中删除相应的记录。)

问题:
当用户决定删除自己的角色时,尽管用户的记录已经在用户命令处理程序中被删除,但 Mongo 删除事件处理程序仍会触发。因此,我认为可以在 Mongo 的事件处理程序中独占地控制机器人。我可以在与用户命令对应的处理程序中给予和收回角色,而是在 Mongo 事件中这样做。例如,要从用户那里收回角色,我需要在命令处理程序中从数据库中删除他的记录。然后,在相应的 Mongo 事件处理程序中,角色将自动被收回。

根据我的经验,我无法预见这将如何影响未来的机器人开发,所以我想请教您的建议。这样做是否是一个好主意?如果不是,处理在上述情况下触发 Mongo 处理程序的一个很好的方法是什么?

我不擅长写作,所以请随时提出需要澄清的问题。

英文:

What is discord Role?

A role is a group created by server admins. The role has permissions, a hierarchy, and a name. What's essential in this case is that players can refer to multiple players at once ("ping" them) by referring to their role like this @RoleName.

Context

I'm developing a bot that issues temporary roles to users. Users take Roles so that others can ping them. A Role is given for the duration user's desires. The bot is being written in Go. The whole app primarily consists of handlers of both Mongo events and commands that users type to the bot.

Each time user takes a role by typing a command to the bot, the Discord id of that user is stored inside the Mongo database with expiration time. Once a time stored within the document is reached, the document is deleted by Mongo (TTL index is used for this). Then via handling Mongo events, the bot handles deletion by taking away roles from users. (Also, the user may remove his role preemptively. In this case, the role is being taken away and the corresponding record from the database.)

Question

When a user decides to remove his role, the Mongo deletion event handler is fired despite the user's record already being deleted inside the user command handler. So, I thought it was possible to control the bot exclusively inside Mongo's event handlers. Instead of giving and removing roles inside handlers corresponding to commands users gave, I can do so inside Mongo events. For example, to take away a role from the user, I need to remove his record from the database inside the command handler. Then role will be taken away automatically inside the corresponding Mongo event handler.

My experience does not let me foresee how this would affect future bot development, so I'm asking you for advice on this. Would this be a good idea? If not, what would be an excellent way to deal with Mongo handlers being fired in such cases as one above?

I suck at writing, so don't be shy to ask for clarifications.

答案1

得分: 1

如果数据库是决定用户拥有哪些角色的权威机构,那么你的机器人应用程序就充当了与Discord保持同步的桥梁。

假设你只在数据库事件上处理角色更新。这意味着你的桥梁应用程序必须在每次过期时运行并正确连接到两个服务,而不会发生任何错误。否则,状态将不同步。为了正确性,最好设计时假设任何一个或全部三个服务随时可能离线。

为了保持用户体验的响应性和一致性,你应该尽快更新角色,并在必要的地方更新到尽可能多的位置,以确保最终一致性。这可能会导致冗余的更新,因此请检查更新是否已经应用,并在必要时跳过。

以下是更新情况的示例:

  • 在机器人应用程序启动时:更新所有用户
  • 在数据库事件上:更新用户
  • 在用户命令上:更新用户(可选,但如果数据库事件延迟,可能会提供更快的用户反馈)
  • 在用户加入服务器时:更新用户
  • 在定期/后台任务上:更新所有用户(可选,以防其他更新失败或角色被外部来源修改)
英文:

If the database is the authority on which users have which roles, your bot application serves as the bridge to keep Discord up to date with that authority.

Suppose you process role updates only on database events. In that case, this means your bridge application must be running and properly connected to both services without any error occurring at the time of every expiration. Otherwise, the state will fall out of sync. For correctness, it's best to design with the assumption that any or all of the three services could go offline at any time.

To keep your experience responsive and consistent, you should update the roles quickly and in as many places as is necessary to ensure eventual consistency. This may result in redundant updates, so check if the update is already applied and skip it if necessary.

Here's an example of update cases:

  • On bot application startup: Update all users
  • On database event: Update user
  • On user command: Update user (optional, but may provide faster user feedback if DB events are delayed)
  • On user joining server: Update user
  • On periodic/background task: Update all users (optional, in case other updates fail or roles are modified by external sources)

huangapple
  • 本文由 发表于 2022年3月5日 22:27:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/71362999.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定