# Bot doesn't see the server responses to its slash commands?

**URL:** <https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054>\
**Category:** Chat and IRC\
**Created:** [April 22, 2022, 9:30am UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054 "2022-04-22T09:30:34Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![robertsmania](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/robertsmania/32/17858_2.png) [@robertsmania](https://discuss.dev.twitch.com/u/robertsmania)\
**Post date:** [April 22, 2022, 9:30am UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054/1 "2022-04-22T09:30:34Z")

</div>

I’m working on a bot in C# and would like to get the list of vips and moderators. It seemed like a simple idea to just send /vips /mods or .vips .mods and parse the response. But the bot does not actually see the server replies for any slash or dot commands it sends.

Is there something I need to do to enable that? Or is it a limitation with how I’m sending/receiving the messages?

Searching this forum I do see people asking about their bot not seeing its own messages, and it sounds like you need to establish a second connection to do that. Is that also necessary to see the server responses for commands?

What I’m using is built on the minimalist sample in this tutorial:

> **[Writing a Twitch Bot From Scratch in C#](https://medium.com/swlh/writing-a-twitch-bot-from-scratch-in-c-f59d9fed10f3)**
>
> I’ve written a few Twitch bots and I’ve almost always used whatever library comes up first in a Google search. Using a library is great…

It uses a single TcpClient and a single SslStream to establish a StreamReader and StreamWriter.

It works great to connect, send and receive messages, respond to PINGS and everything. The only issue I have is that it does not see replies to slash commands it sends.

Here’s the connection routine:

```
        const string ip = "irc.chat.twitch.tv";
        const int port = 6697;

        var tcpClient = new TcpClient();
        await tcpClient.ConnectAsync(ip, port);
        SslStream sslStream = new SslStream(
            tcpClient.GetStream(),
            false,
            new RemoteCertificateValidationCallback(ValidateServerCertificate),
            null
        );
        await sslStream.AuthenticateAsClientAsync(ip);
        streamReader = new StreamReader(sslStream);
        streamWriter = new StreamWriter(sslStream) { NewLine = "\r\n", AutoFlush = true };

        await streamWriter.WriteLineAsync($"PASS oauth:{chatToken}");
        await streamWriter.WriteLineAsync($"NICK {chatUsername}");
        await streamWriter.WriteLineAsync($"JOIN #{channel}");

```

That does connect and join.

Then I’m reading and monitoring the messages coming back from the server like so:

```
                line = await streamReader.ReadLineAsync();
                Console.WriteLine($"Read: {line}");

```

The oauth token I’m using to login looks like it has all the scopes that would be involved:  
[https://id.twitch.tv/oauth2/validate](https://id.twitch.tv/oauth2/validate)  
{“client\_id”:“XXX”,“login”:“pitgirl”,“scopes”:[“channel:moderate”,“channel\_editor”,“chat:edit”,“chat:read”,“whispers:edit”,“whispers:read”],“user\_id”:“552557131”,“expires\_in”:0}

Any insight or suggestions, or more details I can provide from the code?

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [April 22, 2022, 11:25am UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054/2 "2022-04-22T11:25:56Z")

</div>

Do you have an example of _how_ you are sending/requesting a slash command to be run?

You can try instead of `/command` using `.command` in case something is being misunderstood somewhere.

You should also request some capabilties

> **[Chat & Chatbots](https://dev.twitch.tv/docs/irc/)**
>
> Twitch Chat & Chatbots

To help track information on response/error messaging

---

<div class="post-metadata">

**Author:** ![robertsmania](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/robertsmania/32/17858_2.png) [@robertsmania](https://discuss.dev.twitch.com/u/robertsmania)\
**Post date:** [April 22, 2022, 3:40pm UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054/3 "2022-04-22T15:40:35Z")

</div>

I’m sending the commands as PRIVMSGs as described in the documentation:

[Chat & Chatbots | Twitch Developers](https://dev.twitch.tv/docs/irc/guide#scopes-for-irc-commands) : Twitch slash commands are sent via `PRIVMSG` . The following table lists these commands and required scopes…

So in the code, the commands are sent just like any other message the bot sends.

```
        if (twitchChatMessage.Message.StartsWith("?slash",StringComparison.OrdinalIgnoreCase))
        {
            await _twitchBot.SendMessage("Sending slash / dot . commands: /vips .vips /mods .mods");
            await _twitchBot.SendMessage("/vips");
            await _twitchBot.SendMessage(".vips");
            await _twitchBot.SendMessage("/mods");
            await _twitchBot.SendMessage(".mods");
            await _twitchBot.SendMessage("Commands sent.");
        }

```

The above messages are formatted in SendMessage:

```
    public async Task SendMessage(string message, string channel=chatChannel)
    {
        await TryWriteLineAsync($"PRIVMSG #{channel} :{message}");
    }

```

And sent with the streamWriter:

```
            Console.WriteLine($"<{line}");
            try
            { 
                await streamWriter.WriteLineAsync(line);
                //throw(new Exception("Some f'cking thing in TryWriteLineAsync"));
            }
            catch (Exception ex)
            {

                Console.WriteLine("TwitchBot Exception! in TryWriteLineAsync", "red");
            ...

```

I’ve added those messages/commands to be sent when it joins, and also set a ?slash command to send them later just in case there was some race condition or whatever sending them too fast on connect. In both cases, the messages before/after the commands do show up in the chat for others to see - but the commands are not echoed, nor is their response seen by the bot on its streamReader.

So here’s what the console output looks like showing all the messages that are send/read on the streams:

 ![Bot_Cmds_Console_01](https://d2opxh93rbxzdn.cloudfront.net/original/3X/9/1/912728f7f46accc3ee599ea453a82ed81e4a0ca6.png)

And here’s what it looks like on the chat output:  
 ![Bot_Cmds_Chat_01](https://d2opxh93rbxzdn.cloudfront.net/original/3X/8/c/8c4b51e0c204d931780bdc718d78aef89539fddc.png)

I’ll try adding the capabilities requests now and see if that changes anything.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [April 22, 2022, 3:47pm UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054/4 "2022-04-22T15:47:11Z")

</div>

Probably not the easiest commands to test with since they could trip for a variety of issues.

Your first send is sending _before_ GLHF so you ran too soon probably should wait for the JOIN to complete.

If you send a second `?slash` after the second command sent. does yoru script log and do the thing.

wondering if your reader isn’t reading right

---

<div class="post-metadata">

**Author:** ![robertsmania](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/robertsmania/32/17858_2.png) [@robertsmania](https://discuss.dev.twitch.com/u/robertsmania)\
**Post date:** [April 22, 2022, 4:17pm UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054/5 "2022-04-22T16:17:29Z")

</div>

Good questions, and thank you for your help. Are there other commands you suggest that would be easier to demonstrate the send/receive is working properly? I did try adding /help and .help but that also doesnt show anything.

I did add timestamps (just to the Console.WriteLine output - they are not included in whats being sent) to try and show more clearly when things happen.

Yes, the first send is right after the connect. But you will notice the “PitGirl is love.4/22/2022 9:05:08 AM” message is sent before the commands, and that does show up properly in the chat.

In this run, I wait until 9:06 so the ?slash command tries them again well after the connect/join. You can see in both cases the “Sending slash…” and “Commands sent” messages that wrap the commands are showing up in chat as expected.

Yes, I wonder if the reader is reading correctly as well - but it does get everything else: the messages on connect from :tmi.twitch.tv, the PRIVMSG from robertsmania to call the ?slash command, the subsequent PING, etc…

 ![Bot_Cmds_Console_02](https://d2opxh93rbxzdn.cloudfront.net/original/3X/d/2/d22a869bae2f8dbe35177f1ed55c5ad4b2a1ce14.png)

 ![Bot_Cmds_Chat_02](https://d2opxh93rbxzdn.cloudfront.net/original/3X/d/0/d08be76a527ebd595f1ed62b2ec725fcedbf7c48.png)

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [April 22, 2022, 4:27pm UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054/6 "2022-04-22T16:27:00Z")

</div>

> [@robertsmania](#):
>
> I did try adding /help and .help but that also doesnt show anything.

help isn’t a command.

But that should result in an “invalid command” error.

I don’t see anything obviously wrong here.

I do notice you didn’t get a ROOMSTATE on room join. But thats a CAP commands thing iirc

I ran my own test to confirm. It is working as expected here

```auto
init
opening
PONG :tmi.twitch.tv
:tmi.twitch.tv CAP * ACK :twitch.tv/commands
:tmi.twitch.tv CAP * ACK :twitch.tv/tags
:tmi.twitch.tv 001 barrycarlyon :Welcome, GLHF!
:tmi.twitch.tv 002 barrycarlyon :Your host is tmi.twitch.tv
:tmi.twitch.tv 003 barrycarlyon :This server is rather new
:tmi.twitch.tv 004 barrycarlyon :-
:tmi.twitch.tv 375 barrycarlyon :-
:tmi.twitch.tv 372 barrycarlyon :You are in a maze of twisty passages, all alike.
:tmi.twitch.tv 376 barrycarlyon :>
@badge-info=;badges=ambassador/1;color=#033700;display-name=BarryCarlyon;emote-sets=0,2,26,42,46,59,75,112,237,322,365,376,572,615,934,1057,3543,4163,4739,9318,10699,13338,13968,14755,19194,33563,197870,343806,400795,647181,739425,758802,300206296,300374282,300548756,300563799,300981539,301590448,301592777,301850800,301919687,302696035,302696036,302696037,302696038,302696039,302696040,302760317,303434564,318285583,318939165,339395276,343525774,368962233,371408320,381822777,384508024,395764043,401295080,411996111,418301196,420758870,436284473,436820331,437343514,443761993,453335100,463212988,466997024,472873131,477339272,477942371,483832563,488737509,490221517,492125462,498223190,537206155,564265402,592920959,610186276,1962979319,2001998065;user-id=15185913;user-type= :tmi.twitch.tv GLOBALUSERSTATE
:barrycarlyon!barrycarlyon@barrycarlyon.tmi.twitch.tv JOIN #barrycarlyon
join {
  tags: {},
  command: 'JOIN',
  message: undefined,
  raw: ':barrycarlyon!barrycarlyon@barrycarlyon.tmi.twitch.tv JOIN #barrycarlyon',
  user: 'barrycarlyon',
  room: '#barrycarlyon',
  action: false
}
Connected to Channel
:barrycarlyon.tmi.twitch.tv 353 barrycarlyon = #barrycarlyon :barrycarlyon
:barrycarlyon.tmi.twitch.tv 366 barrycarlyon #barrycarlyon :End of /NAMES list
@badge-info=;badges=broadcaster/1,ambassador/1;color=#033700;display-name=BarryCarlyon;emote-sets=0,2,26,42,46,59,75,112,237,322,365,376,572,615,934,1057,3543,4163,4739,9318,10699,13338,13968,14755,19194,33563,197870,343806,400795,647181,739425,758802,300206296,300374282,300548756,300563799,300981539,301590448,301592777,301850800,301919687,302696035,302696036,302696037,302696038,302696039,302696040,302760317,303434564,318285583,318939165,339395276,343525774,368962233,371408320,381822777,384508024,395764043,401295080,411996111,418301196,420758870,436284473,436820331,437343514,443761993,453335100,463212988,466997024,472873131,477339272,477942371,483832563,488737509,490221517,492125462,498223190,537206155,564265402,592920959,610186276,1962979319,2001998065;mod=0;subscriber=0;user-type= :tmi.twitch.tv USERSTATE #barrycarlyon
@emote-only=0;followers-only=-1;r9k=0;rituals=0;room-id=15185913;slow=0;subs-only=0 :tmi.twitch.tv ROOMSTATE #barrycarlyon
@badge-info=;badges=broadcaster/1,ambassador/1;client-nonce=a394e01dc161ed1dccd5eb89e71999d0;color=#033700;display-name=BarryCarlyon;emotes=;first-msg=0;flags=;id=0e7647c1-8089-429a-b37f-49d973a71686;mod=0;room-id=15185913;subscriber=0;tmi-sent-ts=1650644745599;turbo=0;user-id=15185913;user-type= :barrycarlyon!barrycarlyon@barrycarlyon.tmi.twitch.tv PRIVMSG #barrycarlyon :!ehco test
@badge-info=;badges=broadcaster/1,ambassador/1;client-nonce=6404bc5b2ac5cec2f764ef765fae4b84;color=#033700;display-name=BarryCarlyon;emotes=;first-msg=0;flags=;id=88403d6d-e8f0-4d52-ae3a-561bfea92f1c;mod=0;room-id=15185913;subscriber=0;tmi-sent-ts=1650644751786;turbo=0;user-id=15185913;user-type= :barrycarlyon!barrycarlyon@barrycarlyon.tmi.twitch.tv PRIVMSG #barrycarlyon :!echo test
Request test
@badge-info=;badges=broadcaster/1,ambassador/1;color=#033700;display-name=BarryCarlyon;emote-sets=0,2,26,42,46,59,75,112,237,322,365,376,572,615,934,1057,3543,4163,4739,9318,10699,13338,13968,14755,19194,33563,197870,343806,400795,647181,739425,758802,300206296,300374282,300548756,300563799,300981539,301590448,301592777,301850800,301919687,302696035,302696036,302696037,302696038,302696039,302696040,302760317,303434564,318285583,318939165,339395276,343525774,368962233,371408320,381822777,384508024,395764043,401295080,411996111,418301196,420758870,436284473,436820331,437343514,443761993,453335100,463212988,466997024,472873131,477339272,477942371,483832563,488737509,490221517,492125462,498223190,537206155,564265402,592920959,610186276,1962979319,2001998065;mod=0;subscriber=0;user-type= :tmi.twitch.tv USERSTATE #barrycarlyon
@badge-info=;badges=broadcaster/1,ambassador/1;client-nonce=e1ec59737ba5ab7ae56ce61258b41246;color=#033700;display-name=BarryCarlyon;emotes=;first-msg=0;flags=;id=587f4c33-fab0-4777-9558-f3ac588c5700;mod=0;room-id=15185913;subscriber=0;tmi-sent-ts=1650644756293;turbo=0;user-id=15185913;user-type= :barrycarlyon!barrycarlyon@barrycarlyon.tmi.twitch.tv PRIVMSG #barrycarlyon :!echo .vips
Request .vips
@msg-id=vips_success :tmi.twitch.tv NOTICE #barrycarlyon :The VIPs of this channel are: 42ndActual, BarryCarlyonBotTest.
@badge-info=;badges=broadcaster/1,ambassador/1;client-nonce=fdc123ea3f4fe046aeed34e017595c24;color=#033700;display-name=BarryCarlyon;emotes=;first-msg=0;flags=;id=b582a87d-42c1-40c4-b4f1-0d5b661a1f90;mod=0;room-id=15185913;subscriber=0;tmi-sent-ts=1650644764838;turbo=0;user-id=15185913;user-type= :barrycarlyon!barrycarlyon@barrycarlyon.tmi.twitch.tv PRIVMSG #barrycarlyon :!echo .mods
Request .mods
@msg-id=room_mods :tmi.twitch.tv NOTICE #barrycarlyon :The moderators of this channel are: 42ndbot, barrycarlyonbot, cohhilitionbot, cohhkittenbot, emilyelectronic1, eschaap, gecky, ghostcommanderbot, nuuriell

```

Bit more noise due to my emotesets and tags enabled.

Retesting without caps I get no response. So you need the COMMANDS CAPability

So after PASS but before JOIN

send

> CAP REQ :twitch.tv/commands

And then `.mods` and `.vips` should work as expected

---

<div class="post-metadata">

**Author:** ![robertsmania](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/robertsmania/32/17858_2.png) [@robertsmania](https://discuss.dev.twitch.com/u/robertsmania)\
**Post date:** [April 22, 2022, 4:37pm UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054/7 "2022-04-22T16:37:51Z")

</div>

YES! The key was the commands capability request:

```
        await _twitchBot.SendCommand("CAP REQ :twitch.tv/commands");

```

After that, the commands work as expected.

 ![Bot_Cmds_Console_03](https://d2opxh93rbxzdn.cloudfront.net/original/3X/e/a/ea423d1ef2147c066dd9790d86897887bea50afc.png)

Even the /help and .help do show the response as NOTICE messages.

Also, I find it makes no difference experimentally if the CAP REQ happens before or after the JOIN. That kind of makes sense since those requests are not channel specific?

Thank you for your help!!!

---

<div class="post-metadata">

**Author:** ![robertsmania](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/robertsmania/32/17858_2.png) [@robertsmania](https://discuss.dev.twitch.com/u/robertsmania)\
**Post date:** [April 22, 2022, 10:07pm UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054/8 "2022-04-22T22:07:28Z")

</div>

Just to wrap this up if anyone stumbles on this thread in the future trying to get /vips and /mods from chat, here’s what I ended up with to process the output.

Here `line` is the string that came back from streamReader.ReadLineAsync. There are two `List<string>` objects: `vips` and `mods` that get populated with the data from the NOTICEs.

```
                string[] split = line.Split(' ');
                //PING :tmi.twitch.tv
                //Respond with PONG :tmi.twitch.tv
                if (line.StartsWith("PING"))
                {
                    await TryWriteLineAsync($"PONG {split[1]}");
                }
                else if (split.Length > 2 && split[1] == "NOTICE")
                {
                    //:tmi.twitch.tv NOTICE #robertsmania :The moderators of this channel are: mod1, mod2, mod3, ... modX 
                    //:tmi.twitch.tv NOTICE #robertsmania :The VIPs of this channel are: vip1, vip2, vip3, .. vipX.
                    // ^^^^^^^^
                    //Grab the channel name here
                    int secondColonPosition = line.IndexOf(':', 1);//the 1 here is what skips the first character
                    string message = line.Substring(secondColonPosition + 1);//Everything past the second colon
                    string channel = split[2].TrimStart('#');

                    if (message.StartsWith("The VIPs of this channel are:"))
                    {
                        int thirdColonPosition = line.IndexOf(':', secondColonPosition + 1); 
                        string vipStr = line.Substring(thirdColonPosition + 2); //2 skips the space after the colon, should be list of VIPs
                        vipStr = vipStr.TrimEnd('.'); //VIPs do apper to have a period?
                        vips = vipStr.Split(new string[] {", "}, StringSplitOptions.None).ToList();
                    }
                    else if (message.StartsWith("The moderators of this channel are:"))
                    {
                        int thirdColonPosition = line.IndexOf(':', secondColonPosition + 1); 
                        string modsStr = line.Substring(thirdColonPosition + 2); //2 skips the space afte rthe colon, should be list of mods
                        modsStr = modsStr.TrimEnd('.'); //mods doesnt look like it has a period?
                        mods = modsStr.Split(new string[] {", "}, StringSplitOptions.None).ToList();
                    }
                } ...

```

And then goes on to process other types of messages.

---

<div class="post-metadata">

**Author:** ![zneix](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/zneix/32/10836_2.png) [@zneix](https://discuss.dev.twitch.com/u/zneix)\
**Post date:** [April 22, 2022, 11:41pm UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054/9 "2022-04-22T23:41:47Z")

</div>

I see that this topic is already marked as solved, but I see some things that are probably worth pointint/clearing out.

> Also, I find it makes no difference experimentally if the CAP REQ happens before or after the JOIN. That kind of makes sense since those requests are not channel specific?

Just to add on top of that, it actually makes some difference but you won’t make much use of it - simply, sending `CAP`s before you send `PASS` message is the only way to receive [`GLOBALUSERSTATE`](https://dev.twitch.tv/docs/irc/tags#globaluserstate-twitch-tags) message (which btw can be only sent once and only right after authenticating). But maybe this could turn out useful for you in the future, who knows.  
P.S.: All channels on twitch have `-n` mode, which means you can send `PRIVMSG`s without joining any channel - same goes for messages like `PRIVMSG #channel :/mods` and you should also get your `NOTICE` back, even if you’re not JOINed the channel. Which also means that if you only care about getting lists of mods/vips you might not even need to JOIN any channels at all 🙂

> Just to wrap this up if anyone stumbles on this thread in the future trying to get /vips and /mods from chat, here’s what I ended up with to process the output.

@robertsmania In the snippet you’ve posted, you rely on the message’s text itself which could always change, so a way better solution would be making use of [msg-id tags](https://dev.twitch.tv/docs/irc/msg-id). For these, it’s necessary to also request `twitch.tv/tags` CAP, which btw is shown in Barry’s example (but instead of doing that in 2 separate outgoing `CAP REQ ...` messages, both CAPs can be all requested with just one: `CAP REQ :twitch.tv/tags twitch.tv/commands`).  
With both capabilities, you should get more verbose but also way more reliable messages, like so:

```auto
# outgoing messages: >
# incoming messages: <

> PRIVMSG #zneixbot :.vips
< @msg-id=no_vips :tmi.twitch.tv NOTICE #zneixbot :This channel does not have any VIPs.
> PRIVMSG #zneix :.vips
< @msg-id=vips_success :tmi.twitch.tv NOTICE #zneix :The VIPs of this channel are: ALazyMeme, Amayii, CollapsingWave, Eltefan, IceCreamDataBase, Leppunen, NotKarar, PepegePaul, Smaczny, Somso2e, Supinic, TETYYS, TeoTheParty, TranRed, Tsoding, WiFeSeN, YOSEFSA7, YOSEFSAA7, YUNG_RANDD, YungLPR, apa420, boring_nick, cbdg, fabZeef, flex3rs, foUrtf, jammehcow, matthewde, muskatico, nourylul, pajlada, randers, ravi0li_, rl_grey, romyDank, sbus, talenq, teischEnte, tolekk, xVeroNy, ツーツーツーツーツーツーツ
ーツーツーツ.
> PRIVMSG #cinipus :.mods
< @msg-id=no_mods :tmi.twitch.tv NOTICE #cinipus :There are no moderators of this channel.
> PRIVMSG #zneix :.mods
< @msg-id=room_mods :tmi.twitch.tv NOTICE #zneix :The moderators of this channel are: heryin, mm2pl, mm_sutilitybot, senderak, testaccount_420, zneixbot

```

and that makes it just a matter of parsing incoming NOTICE messages and accessing its `msg-id` tags. Keep in mind that a NOTICE message should pretty much always include said tag telling you which kind of message it is, so you can just check for `no_vips`, `vips_success`, `no_mods` or `room_mods` (as shown above).  
Last but not least is a little warning that `vips_success` shows display names instead of login names, so you might get a username that could contain non-ascii localized display names (just like in the example of `PRIVMSG #zneix :.vips`.

sorry if I was too verbose, I’ve tried to share as much of my knowledge as possible ;p

---

<div class="post-metadata">

**Author:** ![robertsmania](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/robertsmania/32/17858_2.png) [@robertsmania](https://discuss.dev.twitch.com/u/robertsmania)\
**Post date:** [April 23, 2022, 12:36am UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054/10 "2022-04-23T00:36:34Z")

</div>

Thank you so much for the reply and additional information. I’m pretty new to this, so everything helps.

The original issue of not getting the response to the commands was indeed solved, and I do have a functional method for getting the data I wanted. But as you point out, its not totally bullet proof. I want to try and be cautious and not get too clever right away, particularly since I’m not familiar with the syntax of all the possible NOTICE message response formats. But experimenting with adding the CAP for tags and adjusting which splits have which parts of the data, this is what I’m using now:

```
                else if (split.Length > 2 && split[2] == "NOTICE")
                {
                    _vaProxy.WriteToLog($"TwitchBot NOTICE: {line}", "yellow");
                    //Not sure about the format of all the NOTICE messages, but we want to handle mods and vips_success
                    if (split[0].StartsWith("@msg-id=room_mods") || split[0].StartsWith("@msg-id=vips_success"))
                    {
                        //@msg-id=room_mods :tmi.twitch.tv NOTICE #robertsmania :The moderators of this channel are: mod1, mod2, mod3, ... modX
                        //@msg-id=vips_success :tmi.twitch.tv NOTICE #robertsmania :The VIPs of this channel are: vip1, vip2, vip3, ... vipX.
                        // ^^^^^^^^
                        //Grab the channel name here
                        int secondColonPosition = line.IndexOf(':');
                        int thirdColonPosition = line.IndexOf(':', secondColonPosition + 1);
                        int fourthColonPosition = line.IndexOf(':', thirdColonPosition + 1);
                        string message = line.Substring(thirdColonPosition + 1);//Everything past the third colon
                        string channel = split[3].TrimStart('#');
                        string userList = line.Substring(fourthColonPosition + 2); //2 skips the space after the colon, should be list of users
                        userList = userList.TrimEnd('.'); //VIP lists do appear to have a period at the end?
                        if (split[0].StartsWith("@msg-id=vips_success"))
                        {
                            vips = userList.Split(new string[] { ", " }, StringSplitOptions.None).ToList();
                        }
                        else if (split[0].StartsWith("@msg-id=room_mods"))
                        {
                            mods = userList.Split(new string[] { ", " }, StringSplitOptions.None).ToList();
                        }
                    }
                }

```

I guess I am a little worried that its depending on things in the message being a certain number of colons in, or that the NOTICE/JOIN/PING/PRVMSG identifiers are always in the same segment when split by spaces. Seems kind of risky.

Is there some kind of documentation with best practice or established framework for reliably parsing and handing the messages?

---

<div class="post-metadata">

**Author:** ![Marenthyu](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/marenthyu/32/530_2.png) [@Marenthyu](https://discuss.dev.twitch.com/u/Marenthyu)\
**Post date:** [April 25, 2022, 6:02am UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054/11 "2022-04-25T06:02:37Z")

</div>

> [@robertsmania](#):
>
> Is there some kind of documentation with best practice or established framework for reliably parsing and handing the messages?

Only what is in the Docs is really “official”, but @BarryCarlyon 's Examples on GitHub are generally really high-quality and I can vouch for them.

> <https://github.com/BarryCarlyon/twitch_misc/tree/main/chat>
>
> //github.com/BarryCarlyon/twitch\_misc/tree/main/chat

Generally, it may also be worth to note the existance of some API Endpoints that Mirror Information available via chat - like [GET moderators](https://dev.twitch.tv/docs/api/reference#get-moderators) - do note the requirement for a broadcaster/moderator token on the Endpoints, though. Also EventSub and its soon™ to be available WebSocket Transfer.

That said, chat is still a very good general source for most things - just be aware of the other potential sources in case this changes in the future.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d3ovvz0v2ajtpu.cloudfront.net/user_avatar/discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [April 25, 2022, 10:57am UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054/12 "2022-04-25T10:57:28Z")

</div>

> [@robertsmania](#):
>
> Is there some kind of documentation with best practice or established framework for reliably parsing and handing the messages?

As Twitch is “standard” IRC when it comes to the format of a line.

Any IRCv3 compatible tokeniser/parser will do the job.

Twitch doc’s don’t describe parsing/tokenisation as Twitch manages to follow the specificiation for the formatting of an IRC line. So any existing IRCv3 paser/tokeniser will do the job. Or roll your own as per the IRC RFC’s/specifications

[RFC 1459 - Internet Relay Chat Protocol](https://tools.ietf.org/html/rfc1459) (see also RFC2812 and RFC7194)  
[IRCv3 Specifications - IRCv3](https://ircv3.net/irc/)

Just note that Twitch only supports two CAP’s tags/commands (we don’t talk about membership since it’s basically useless)

---

<div class="post-metadata">

**Author:** ![system](https://d2opxh93rbxzdn.cloudfront.net/original/2X/0/05909729875cce3b53e59d5561c4d23bb14948fc.png) [@system](https://discuss.dev.twitch.com/u/system)\
**Post date:** [May 25, 2022, 10:57am UTC](https://discuss.dev.twitch.com/t/bot-doesnt-see-the-server-responses-to-its-slash-commands/38054/13 "2022-05-25T10:57:37Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
