【discord.js】なぜ転送メッセージは荒らし対策BOTを貫通してしまうのか。

お久しぶりです。りょうです。
今回はdiscordの転送メッセージが荒らし対策BOTを貫通してしまう原因について書きます。

# 転送メッセージ
別の場所から自分が送信できる場所にメッセージ(画像や動画含む)を転送して共有できるようにする機能です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/603d0807-073e-41ef-940b-e7afa731f611.png)

# 貫通の原因
転送メッセージの中身です↓
```js
<ref *1> Message {
  channelId: '1280866748920365121',
  guildId: '1280866748920365118',
  id: '1357897427893485628',
  createdTimestamp: 1743818375324,
  type: 0,
  system: false,
  content: '',
  author: User {
    id: '1095869643106828289',
    bot: false,
    system: false,
    flags: UserFlagsBitField { bitfield: 4194560 },
    username: 'ryo_001339',
    globalName: 'りょう',
    discriminator: '0',
    avatar: '03b6b8934fa4b517f8a2384dcb2123de',
    banner: undefined,
    accentColor: undefined,
    avatarDecoration: null,
    avatarDecorationData: null
  },
  pinned: false,
  tts: false,
  nonce: '1357897423111847936',
  embeds: [],
  components: [],
  attachments: Collection(0) [Map] {},
  stickers: Collection(0) [Map] {},
  position: 0,
  roleSubscriptionData: null,
  resolved: null,
  editedTimestamp: null,
  reactions: ReactionManager { message: [Circular *1] },
  mentions: MessageMentions {
    everyone: false,
    users: Collection(0) [Map] {},
    roles: Collection(0) [Map] {},
    _members: null,
    _channels: null,
    _parsedUsers: null,
    crosspostedChannels: Collection(0) [Map] {},
    repliedUser: null
  },
  webhookId: null,
  groupActivityApplication: null,
  applicationId: null,
  activity: null,
  flags: MessageFlagsBitField { bitfield: 16384 }, // MessageFlagsBitField.HasSnapshot
  reference: {
    channelId: '1280866748920365121',
    guildId: '1280866748920365118',
    messageId: '1357897357479510207',
    type: 1
  },
  interactionMetadata: null,
  interaction: null,
  poll: null,
  messageSnapshots: Collection(1) [Map] { // 転送メッセージの中身
    '1357897357479510207' => Message {
      channelId: '1280866748920365121',
      guildId: '1280866748920365118',
      id: '1357897357479510207',
      createdTimestamp: 1743818358536,
      type: 0,
      system: false,
      content: 'あ',
      author: [User],
      pinned: false,
      tts: false,
      nonce: '1357897352794341376',
      embeds: [],
      components: [],
      attachments: Collection(0) [Map] {},
      stickers: Collection(0) [Map] {},
      position: null,
      roleSubscriptionData: null,
      resolved: null,
      editedTimestamp: null,
      reactions: [ReactionManager],
      mentions: [MessageMentions],
      webhookId: null,
      groupActivityApplication: null,
      applicationId: null,
      activity: null,
      flags: [MessageFlagsBitField],
      reference: null,
      interactionMetadata: null,
      interaction: null,
      poll: null,
      messageSnapshots: Collection(0) [Map] {},
      call: null
    }
  },
  call: null
}
```
荒らし対策のBOTの多くは`message.content`に招待リンクなどが含まれていないかを確認するようになっています。
ですが、転送メッセージは`messageSnapshots`の部分にあるため、contentは''、つまり何も入っていないんです。だから見過ごされて貫通してしまいます。
(オプションで追加されたメッセージは普通にmessage.contentに入ります)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/f13d63f8-7fe0-4bf5-a724-c60f6db6673e.png)


# 対策
```js
if (message.messageSnapshots?.size) {
  console.log(message.messageSnapshots.first().content); // ここは適切な処理に変えて
}

```
これは一例ですが、messageSnapshotsが存在するかつ1件以上あるかを確認し、満たした場合に処理を行うようにすれば転送メッセージへの対応ができます。
message.messageSnapshots は Collection オブジェクトなので、`.first()`や `values().next().value` を使って要素を取得できます

他にも一定時間内に同一ユーザーからのmessageCreateが◯件発生したら対処にすれば対策できます

# まとめ
短いですが終わりです
これはもっとこうしたほうがいいんじゃないかなどの提案や意見、質問等あれば書いてもらえると助かります

Discordに湧く荒らしの情報や対策方法の共有をしている自鯖です(1100人いきました！)
よければ参加お願いします↓

https://discord.com/invite/ESRGwGQhxc

twitter🐦️

https://x.com/ryo_001339