Chat bot in php CLI

Hello Guys,

I have successfully create chat API in PHP Script to get chat messages here is my working code.

<?php
        set_time_limit(0);

        $chan = "#channel";
        $server = "irc.chat.twitch.tv";
        $port = 6667;
        $nick = "username";
        $pass = "oauth:****************************"; // actual oauth is used in script.

        $socket = fsockopen($server, $port,$errno,$errstr,15);
        //echo $errno."\n".$errstr."\n"; // echoes "0 and no string. no errors connecting
        fwrite($socket,"PASS ".$pass."\r\n"); // have tried PASS after USER/NICK, no changes
        //fwrite($socket,"USER ".$nick."\r\n"); // have tried both fwrite and fputs. no difference in results.

        fwrite($socket,"NICK ".$nick."\r\n"); 
        // have tried NICK instead of USER, as well as both NICK and USER, and visa versa. still errors ":tmi.twitch.tv NOTICE * :Login unsuccessful"
        // will only not error if only USER is sent.

        //echo var_dump($socket); // resource(4) of type (stream) - what one would expect from an open socket.
        fwrite($socket,"JOIN ".$chan."\r\n"); // have also tried sending all commands without "\r", only "\n" character. makes no difference
        while(1) {
            //echo "starting pull loop\n"; // prints on command prompt once
        while($data = fgets($socket,256)) { // Script never gets past this point, unless login error, then it does 1 time.
            
            //echo $data; // does not print unless login error

            
            //exit;
                $file = fopen("testfile.txt",'a+');
                fwrite($file,$data."\r\n");
                fclose($file);
                $ex = explode (' ', $data);
                if($ex[0] == "PING"){
            
                    fputs($socket, "PONG ".$ex[1]."\r\n");
                }
            }
        }
?>

Now the thing here is, I am appending the file testfile.txt and its appending messages something like this

:tmi.twitch.tv 001 username :Welcome, GLHF!

:tmi.twitch.tv 002 username :Your host is tmi.twitch.tv

:tmi.twitch.tv 003 username :This server is rather new

:tmi.twitch.tv 004 username :-

:tmi.twitch.tv 375 username :-

:tmi.twitch.tv 372 username :You are in a maze of twisty passages, all alike.

:tmi.twitch.tv 376 username :>

:ceepee100!ceepee100@ceepee100.tmi.twitch.tv PRIVMSG #swagg :"you gotta take me to the loadout, I'm an expensive bich rn"

So my first question is how can I make json here and append all the messages in my “messages” json something like this

{
	"messages": ["message1", "message2"]
}

And my second question is I do not want to add messages like

:tmi.twitch.tv 001 username :Welcome, GLHF!

I am trying to comment below code to remove above message …

fwrite($socket,"PASS ".$pass."\r\n");

fwrite($socket,"NICK ".$nick."\r\n");

fwrite($socket,"JOIN ".$chan."\r\n");

But then obviously not working … Can someone guide me to solve or udate my API please …

So you’d always be added messages to the messages array?

Thats not a good idea. as your bot will take exponentitally longer to write the messages.txt file as you will have to write the file competely every time instead of just appending to it.

For a log of messages it’s generally better to append to a flat file as raw messages from the server, like you are currently doing.

And process that flat file later.

As, to do it the way you propose

  1. Load the file
  2. Json parse the file
  3. Push an item to the messages array
  4. json encode the array again
  5. write the whole json blob back to a file

Your bot won’t be able to keep up.

@BarryCarlyon Thanks for your reply.

No I am not supposed to add the messages from scratch.

Instead I want to open the .txt file, want to decode json content from the file in which it will contain messages object or dictionary and i want to decode as array in php and then want to append it.

does this makes sense ?

@BarryCarlyon But the problem I am having is my .txt file always added data which is not related to chat something like below.

:tmi.twitch.tv 001 mittultwitch :Welcome, GLHF!

:tmi.twitch.tv 002 mittultwitch :Your host is tmi.twitch.tv

:tmi.twitch.tv 003 mittultwitch :This server is rather new

Hence my full .txt file is not in json format. I do not want to add above content in a file but its always added may be due to below code.

fwrite($socket,"PASS ".$pass."\r\n");
fwrite($socket,"NICK ".$nick."\r\n"); 
fwrite($socket,"JOIN ".$chan."\r\n"); 

So I am confused how can I not add above content as well. As I only want to get chat response in my json file.

That is exactly what I wrote.

It’s not practical to do this.

you have 1000 messages in the file. load and add one message and write the file

The time taken do do this operation is longer now

eventually you’ll end up corrupting the file or dropping messages from the file due to no locking of the file.

You won’t be able to load the file and add messages to it when trying to do this twice. Since the previous write function is still writing you file.

Even more so if this file gets to 10,000 messages and so on. you’ll end up with file corruption or missing messages.

The File somehow gets to 1GB in size.
Ok now you need to laod that 1GB file into memory, oh wait, a second message has arrived to be added to the file, now I’m loading the file Twice.

And then your bot crashes as it’s opening the file 50 times and the same time and writing it at least one, and now your whole file is corrupt.

Sure you could add some logic to load once, write x number of lines, hold the array in memory and write a copy of the array to the file.

But then you are holding 1GB of chat in memory for no reason.

This is not a very good way to do this.

Then parse the IRC message and extract only the messages you are interested in, for IRC this is most likely any message that uses the IRC COMMAND of PRIVMSG

@BarryCarlyon Yes you are correct … I knew I was after the wrong way or direction.

Thanks for correcting me.

So do you feel, I can just make another PHP file and open using something like file_get_contents and load the content ?

What is an another approach to store data ? I have a requirement to get all chat you know … Any other suggestion mate ?

Exactly

I’d just

  • on rawMessage
  • file_put_contents(target, rawMessage, FILE_APPEND);

And use a separate PHP script to read and parse out the stuff/messages I’m looking for.

Now this is what I’d do if I’m building a chat logger and wanted all messages, since there are some useful messages that are not PRIVMSG (user USERNOTICE)

And better to collect it all and process later, than to go “well I wish I’d collected that at the time”

There are some other options but it depends what you intend to do with what you collect and why you are collecting

@BarryCarlyon Perfect. Thank you so much.

I will update my code and come back here if anything else to deal with.

Thanks a lot.

@BarryCarlyon

Additionally, currently I am getting the message like this…

:ceepee100!ceepee100@ceepee100.tmi.twitch.tv PRIVMSG #swagg :"you gotta take me to the loadout, I'm an expensive bich rn"

as you can see … its not getting the real username. Instead its showing something like :ceepee100!ceepee100@ceepee100.tmi.twitch.tv PRIVMSG #swagg

I want a username just like its showing in chat window in Twitch website …

This is a “standard” IRC message, tokenise/parse the raw chat line.

Thanks for reply.

So you mean we can not modify the response ?

No because this is what twitch chat sends

Basically its

alias!user@hostname

See also https://dev.twitch.tv/docs/irc/guide#generic-irc-commands

> :<user>!<user>@<user>.tmi.twitch.tv PRIVMSG #<channel> :This is a sample message

And we usually extract the user from that string

IRC is a fairly old format so regex’s exist for tokenising.

Some examples at https://github.com/BarryCarlyon/twitch_misc/blob/master/chat/chat.js#L46 node JS examples of the Regex I use

or for PHP you can use an existing library such as SmartIRC

Might need some modifications to support IRCv3 though. But otherwise for unenhanced/capabilitied Twitch Chat should work just fine.

Thats looks good … I followed the links you mentioned … I believe I can do the same by using REGEX in my PHP code to achieve the same … what you think ? Something like this…

const ircRegex = /^(?:@([^ ]+) )?(?:[:](\S+) )?(\S+)(?: (?!:)(.+?))?(?: [:](.+))?$/;

I can do something in $data to split my message and my username. I believe.

seems good

tested it in https://regex101.com/

Wow … let me try … would be awesome if it works. Let me try.

Thank you so much mate.

I have done all the required stuff and its working as per my requirements.

I have created .json file and storing all my messages there.

I just wonder though, like YOUTUBE API does provide response in CURL php for chat messages https://developers.google.com/youtube/v3/live/docs/liveChatMessages

Here, in response we get the messages in array and I can play around for pagination etc.

So I just wonder does Twitch also supports any other way like this in PHP in particular ? Or IRC is the only way ?

If you can let me know it would be great deal you know.

Thanks

IRC/RealTime is the only way

OK I see … Thanks