使用 AWS Lambda 的 Discord 机器人

Posted

技术标签:

【中文标题】使用 AWS Lambda 的 Discord 机器人【英文标题】:Discord Bot using AWS Lambda 【发布时间】:2019-01-13 22:56:35 【问题描述】:

我正在尝试构建一个不和谐的机器人,并且想知道我是否可以使用 AWS lambda。到目前为止,我还没有看到有人已经这样做了,所以如果可能的话,我会感到困惑。特别是当 lambda 不是一直处于活动状态时。

【问题讨论】:

应该不会吧?什么会触发你的 lambda 函数?通常,您的机器人会登录,然后从 discord 接收数据,这些数据代表它已加入的服务器状态的更改(加上私人消息等)。 EC2 对于该模型更有意义。 是的,这就是我认为需要触发 lambda 的原因。另一种选择是拥有一个 ec2 实例,但这听起来有点过头了。 reddit.com/r/aws/comments/6qeje7/using_lambda_for_discord_bot 说不。没有“传出”的 webhook,所以 discord 不能发出可能触发 lambda 的东西。 你将如何扩展它? ELB 可以工作吗? 【参考方案1】:

一个古老的问题,但现在有可能,因为几周前 discord 开始提供传出 webhook

(无耻的自我插入)我写了一点指南here

【讨论】:

【参考方案2】:

这现在是可能的,但遵循集成方法而不是传统的机器人方法。如下所述。

slash commands official documentation 向我们提供了以下信息:

Slash 命令和交互带来了全新的东西:无需公会中的机器人用户即可与应用程序交互的能力。

您现在可以通过首选 URL 端点(例如 AWS Lamba 函数、Firebase Cloud 函数、Azure Cloud 函数等)接收交互事件。

这个官方receiving an interaction部分告诉我们:

在 Developer Portal 的应用程序中,主页上有一个名为“Interactions Endpoint URL”的字段。如果您想通过传出 webhook 接收交互,您可以在此字段中设置您的 URL。

重要的是要记住,但是,发送到端点 URL 以进行交互的数据与运行机器人客户端不同,实际上他们对 here 发表评论:

在许多情况下,您可能仍需要机器人用户。如果您需要接收网关事件,或者需要与我们 API 的其他部分进行交互...

【讨论】:

【参考方案3】:

在我看来,虽然我们可以通过 AWS Lambda 使用 Webhook 发布消息,但我们不能使用 AWS Lambda 接收和处理消息。 这是因为 discord 不提供消息发布事件。

【讨论】:

【参考方案4】:

这是 nodejs 中的一个最小实现,它将为您提供可接受的交互端点 URL

serverless.yml

service: discord
variablesResolutionMode: 20210326

frameworkVersion: '2'

provider:
  name: aws
  runtime: nodejs14.x
  stage: whatever
  region: us-east-1
  lambdaHashingVersion: 20201221
  iam:
    role:
      name: discord
      # https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-access.html
      statements:
        -
          Effect: Allow
          Action:
            - 'ssm:DescribeParameters'
          Resource: '*'
        -
          Effect: Allow
          Action:
            - 'ssm:GetParameter'
          Resource:
            - 'arn:aws:ssm:us-east-1::parameter/discord_token'
            - 'arn:aws:ssm:us-east-1::parameter/discord_application_id'
            - 'arn:aws:ssm:us-east-1::parameter/discord_public_key'

functions:
  interactions:
    handler: handler.interactions
    environment:
      DISCORD_TOKEN: $ssm:/discord_token
      DISCORD_APPLICATION_ID: $ssm:/discord_application_id
      DISCORD_PUBLIC_KEY: $ssm:/discord_public_key
    events:
      -
        http: 
          path: interactions
          method: post
          cors: true

handler.js

'use strict';

const nacl = require('tweetnacl');

module.exports.interactions = async (event) => 
  const verified = nacl.sign.detached.verify(
    Buffer.from(event.headers['x-signature-timestamp'] + event.body),
    Buffer.from(event.headers['x-signature-ed25519'], 'hex'),
    Buffer.from(process.env.DISCORD_PUBLIC_KEY, 'hex')
  );
  const body = JSON.parse(event.body);
  const response = 
    body: JSON.stringify(
      verified
        ?  type: body.type 
        :  error: 'invalid request signature' ,
      null,
      2
    ),
    statusCode: verified
      ? 200
      : 401
  ;
  console.log(JSON.stringify( event, response , null, 2));
  return response;
;

【讨论】:

以上是关于使用 AWS Lambda 的 Discord 机器人的主要内容,如果未能解决你的问题,请参考以下文章

什么是AWS Lambda?

从java lambda调用aws Step函数

我应该如何通过 cloudformation 部署我的 aws 状态机?

aws

使用无服务器和 chrome-aws-lambda 节点包在 AWS Lambda 上找不到 Chrome 二进制文件

使用 AWS Lambda (NodeJS) 创建 AWS AppSync