Discord.NetでSocketMessage.Contentが空白になる問題の対処

# 概要
C#でBot作ってみようと思ったらテキストが取得できない問題が出たが特に解決法が見当たらなかったのでCopilot(BingAI)に聞いたところ解決できたので記載
まだ使い始めてばかりなので間違っているところがあるかもしれません。

## 環境
- .NET Framework 4.8  コンソールアプリケーション
- Discord.Net 3.12.0

## 参考
- [DiscordのBotをC#で作ってみる](https://qiita.com/HAGITAKO/items/fff2e029064ea38ff13a)
- [DiscordBotをC#で作ってAzureで公開してみた](https://qiita.com/xxIN0xx/items/9cb561f1765d427957a9)
- [C#でDiscord Bot開発（Discord.Net）](https://www.dice-programming-etc.com/c%e3%81%a7discord-bot%e9%96%8b%e7%99%ba%ef%bc%88discord-net%ef%bc%89/)

- [DiscordBOTでメッセージが取得できない](https://teratail.com/questions/joyxs1ue7hvsu4)
- [ゲートウェイインテント入門](https://discordpy.readthedocs.io/ja/latest/intents.html)
- [Discord.py の Intents について](https://qiita.com/Pumila/items/8b8e14f60fd7f266872b)

# 詳細
↓概要画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052941/50c0b1c0-2ab6-2121-612d-793e66245da6.png)
(最後のはStartsWithで検知してるだけ)

## 流れ
1. 自作ソフト(世界地震情報表示ソフト)の情報をbotで投稿できないかと試していたところ、SocketMessage.Contentが取得できない(空白になる)問題が発生
2. Discord側のPrivileged Gateway Intentsをオンにしても変わりなし
3. BingAI(より厳密に)に聞いたらコード内でIntentsを有効にする必要があるとわかり、コードを追加したら取得できた

<details><summary>BingAIの回答(.txtエクスポートしたものを抜粋)</summary>
全体:https://sl.bing.net/cDkAFp3MFwq

##ユーザー
c#でdiscord.netを使いdiscordのbotを開発していますが、投稿するときbotにメンションしないとSocketMessage.Contentが空白になります。原因はわかりますか？
##Bing
SocketMessage.Contentが空白になる原因はいくつか考えられますが、一般的には以下の可能性があります：
- メッセージが実際に空である場合：ユーザーがメッセージを送信せずに、画像や他のメディアのみを送信した場合、SocketMessage.Contentは空になります。
- ボットの権限：ボットがメッセージを読む権限を持っていないチャンネルからメッセージが送信された場合、SocketMessage.Contentは空になる可能性があります。
- プライバシー設定：Discordのプライバシー設定により、特定のユーザーからのメッセージをボットが読むことが制限されている場合、SocketMessage.Contentは空になる可能性があります。
- Intentsの設定：Discord BotのIntentsが正しく設定されていない場合、メッセージの内容が正しく取得できないことがあります。
これらの要因を確認し、問題が解決しない場合は、Discord.Netのドキュメンテーションやコミュニティフォーラムを参照することをお勧めします。また、具体的なエラーメッセージやコードスニペットを提供していただければ、より具体的なアドバイスが可能かもしれません。どうぞよろしくお願いいたします。
##ユーザー
botにメンションすると正常に取得できます。違いは何でしょうか？
##Bing
Discordの仕様により、ボットがメッセージの内容を取得できるのは以下の3つの状況です：
- ボットが送信したメッセージ
- ボットがDMで受け取ったメッセージ
- ボットがメンションされているメッセージ
したがって、ボットにメンションをつけると、そのメッセージの内容がSocketMessage.Contentで取得できます。一方、ボットにメンションがないメッセージは、上記の仕様により、SocketMessage.Contentが空になる可能性があります。
また、DiscordのIntents設定が正しく設定されていない場合も、メッセージの内容が正しく取得できないことがあります。具体的には、GatewayIntentsをGatewayIntents.Allに設定することで、すべてのメッセージイベントを受け取ることができます。
これらの情報がお役に立てば幸いです。他にご質問がありましたら、お気軽にどうぞ。よろしくお願いいたします。
##ユーザー
Intentsの設定方法を教えてください。
##Bing
DiscordのIntentsを設定する方法は以下の通りです：
- まず、Discordのウェブサイトにログインします。
- アプリケーションページに移動します。
- Intentsを有効にしたいBotを選択します。
- 画面の左側にあるBotタブに移動します。
- 「特権ゲートウェイインテント」セクションまでスクロールし、必要なものを有効にします。
また、コード内でIntentsを有効にするためには以下のようにします：

var config = new DiscordSocketConfig
{
    Intents = GatewayIntents.All
};
var client = new DiscordSocketClient(config);

この設定により、すべてのメッセージイベントを受け取ることができます。
なお、特権インテントであるため、Intents.membersは有効になりません。これらの情報がお役に立てば幸いです。他にご質問がありましたら、お気軽にどうぞ。よろしくお願いいたします。
</details>

## やり方
1. Discord側で`Privileged Gateway Intents`の3つ目の`MESSAGE CONTENT INTENT`をオンに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052941/348ac9c6-077e-28f9-a443-7cc0281d5ad8.png)
(必要な場合は他のもオンに)
2. コードを追加
```c#:C#
internal class Program
{
    private readonly DiscordSocketClient client;

    static void Main(string[] args)
    {
        new Program().MainAsync().GetAwaiter().GetResult();
    }

    public Program()
    {
        //MESSAGE CONTENT INTENTのみオンにした場合(最低限)
        //他のをオンにした場合や他にも必要な場合それに対応するGatewayIntentsを追加
        //すべてオンにした場合はGatewayIntents = GatewayIntents.Allでもいい
        DiscordSocketConfig config = new DiscordSocketConfig
        {
            GatewayIntents = GatewayIntents.Guilds | GatewayIntents.GuildMessages | GatewayIntents.MessageContent
        };
        client = new DiscordSocketClient(config);//設定付きで初期化
        //以下自由
        client.Log += Log;
        client.Ready += Ready;
        client.MessageReceived += Message;
    }
}
```
※必要ないものも入れるとclient.Logで以下のメッセージが出る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052941/ab7cd820-98bf-db09-2510-5b4b7eae7308.png)

完成!

# まとめ
Privileged Gateway Intentsをオンにするだけでは取得できないがコードも追加することで取得できる。
BingAIありがとう。