Bravo List
Register
Go Back   > Bravo List > P2P > Forum > Tutorials
Reply
  #1  
Old 05-05-15, 13:31
BamBam0077's Avatar
BamBam0077 BamBam0077 is offline
Support
 
Join Date: Jul 2013
P2P
Posts: 260
Default Creating an IRC bot in PHP
Combined Minds presents you the biggest and best PHP -> IRC bot tutorial on the web! This tutorial teaches you how to create a very good working IRC bot from scratch!

Welcome to this second PHP Socket tutorial in Combined-Minds.net. In this tutorial i will explain the ins and outs of how to connect to an IRC server.

You may think, "what does an IRC bot has to do with webdevelopment?". Well, nothing actually. I will just use a interesting subject for talking about the sockets. On this way the tutorial will be much more fun to write, and read.

When making a PHP powered bot to connect to some external source, you need to know 2 major things. How to connect and talk to the server, and what you need to talk.

The first one is the PHP part, while the second part is the API or Protocol of the sort of server you are connecting to.

We will connect to an IRC server in this tutorial, i will explain the basics of the IRC protocol. But i will mainly talk about how to connect and read/write to the server in PHP. For that is the one thing you will be using on every protocol.

How to connect

First select the server you want to connect to. The server i will use is irc.rizon.net, port 6667. We will use fsockopen(); for opening the socket You could also use the socket_create() function, but this does not work well often for the windows powered servers.

This function works by first specifying the server address (can be a URL, can be an IP address). The second is the port. You may use a third and fourth one for error handling, and a fifth one for a time-out number. For more information, please see PHP.net.

The following example is how to use it. I did not use the third, fourth and fifth parameters. Because i want to keep it simple for this tutorial.
Code:
<?php
 
// Opening the socket to the Rizon network
$socket = fsockopen("irc.rizon.net", 6667);
 
?>
As you can see, save the socket data in a variable/object.

After connecting to the server, you must give it some details:

USER A-trivial-nickname a-domain-like-combined-minds.net some-trivial-stuff :your-real-name
NICK CM-bot

The first line looks rather weird. But just fill in something the same as i got there. If you do not know what to edit exactly, just copy the line from me.

The second line is simple, just the NICK command, followed by the nickname desired.

To send text to the server, you need to use the fputs(); function. This functions works by first giving it the socket variable, where the data needs to go. The second is the text needs to be send. When you send text to the server, always close it with a new line! (\n) Or else the server will think the text you will send is all one line, and wont process it correctly.

This is what i send, using the fputs(); function.
Code:
<?php
 
// Opening the socket to the Rizon network
$socket = fsockopen("irc.rizon.net", 6667);
 
// Send auth info
fputs($socket,"USER CMbot combined-minds.net CM :CM bot\n");
fputs($socket,"NICK CM-bot\n");
 
?>
This will open the connection, and after that it will tell the server what/who it is.

Two important things, tell the server which channel it should join. This is done by the JOIN command. Followed by the channel you want to join. For this tutorial i registered the channel #cm-bot-test on the rizon network.

The second very important thing, is to change the nickname of the bot for testing!. If you will test it at the Rizon network that is. (i suggest you do it at the rizon network, for i will be there sometimes to help you guys)

Code:
<?php
 
// Opening the socket to the Rizon network
$socket = fsockopen("irc.rizon.net", 6667);
 
// Send auth info
fputs($socket,"USER CMbot combined-minds.net CM :CM bot\n");
fputs($socket,"NICK CM-bot\n");
 
// Join channel
fputs($socket,"JOIN #cm-bot-test\n");
 
?>
Next thing to do is read what the server has to say back. But there is one little problem you might think. Most people who think of "How can you keep an idle connection in PHP? It will stop after the script has run right?". Well of course the script stops when its ended. Thats why we'll make sure the script wont end .

We will need 2 things. An endless while, and something to stop PHP from canceling the script after the normal 30sec time limit. The last one is easy to solve, PHP has the function set_time_limit(). You use this function the following way:

Code:
<?php
 
// Prevent PHP from stopping the script after 30 sec
set_time_limit(0);
 
// Opening the socket to the Rizon network
$socket = fsockopen("irc.rizon.net", 6667);
 
// Send auth info
fputs($socket,"USER CMbot combined-minds.net CM :CM bot\n");
fputs($socket,"NICK CM-bot\n");
 
// Join channel
fputs($socket,"JOIN #cm-bot-test\n");
 
?>
Simple give PHP the number of second you want the script to run maximally. When it's set to zero it will cancel the whole max run time thing. And you are able to run the script as long as you want.

Next is actually preventing from PHP to stop exiting the script while the bot is running. We will use while() for this job. We will make a while loop, that wont stop until we say it can. This is called an endless while, a while loop without an end. For this to work we need to keep the so called "expression" to be TRUE. (the expression is the check between the ( and the )) When the expression is TRUE, it will continue with the job thats done between the { and the } (accolades). We can just use "1" as the expression. For one is always TRUE!

Code:
<?php
 
// Prevent PHP from stopping the script after 30 sec
set_time_limit(0);
 
// Opening the socket to the Rizon network
$socket = fsockopen("irc.rizon.net", 6667);
 
// Send auth info
fputs($socket,"USER CMbot combined-minds.net CM :CM bot\n");
fputs($socket,"NICK CM-bot\n");
 
// Join channel
fputs($socket,"JOIN #cm-bot-test\n");
 
// Force an endless while
while(1) {
 
    // Continue the rest of the script here
    while($data = fgets($socket, 128)) {
 
        echo $data;
 
    }
 
}
 
?>
Now the script won't stop.

Next is to read what the server is sending us. For this we will use the fgets() function. The function will return the text the server is sending us. So we will store the text what the function returns into a variable. The two things the function needs are the socket variable and the number of bytes it may read each time when its called.
Code:
<?php
 
// Prevent PHP from stopping the script after 30 sec
set_time_limit(0);
 
// Opening the socket to the Rizon network
$socket = fsockopen("irc.rizon.net", 6667);
 
// Send auth info
fputs($socket,"USER CMbot combined-minds.net CM :CM bot\n");
fputs($socket,"NICK CM-bot\n");
 
// Join channel
fputs($socket,"JOIN #cm-bot-test\n");
 
// Force an endless while
while(1) {
 
    // Continue the rest of the script here
    while($data = fgets($socket, 128)) {
 
        echo $data;
 
    }
 
}
 
?>
Why i use 128 bytes to send is trivial information. I Think this is pretty clear, so save your file. And run it in your browser! If it all went right, you should be able to find your bot in the user list of channel #cm-bot-test!

When you are running the script in your browser. You may want to use the nl2br(), and flush() functions. nl2br() to make sure your $data output is all one a new line, that is quite handy for reading. ;-) You want to use the flush() function for flushing the data to the browser. Normally PHP send it's output to the browser after the outcome is calculated, so on the very and. But when flush() is called, all that's calculated so far will be already send to the browser.

Code:
<?php
 
// Prevent PHP from stopping the script after 30 sec
set_time_limit(0);
 
// Opening the socket to the Rizon network
$socket = fsockopen("irc.rizon.net", 6667);
 
// Send auth info
fputs($socket,"USER CMbot combined-minds.net CM :CM bot\n");
fputs($socket,"NICK CM-bot\n");
 
// Join channel
fputs($socket,"JOIN #cm-bot-test\n");
 
// Force an endless while
while(1) {
 
    // Continue the rest of the script here
    while($data = fgets($socket, 128)) {
 
        echo nl2br($data);
        flush();
 
    }
 
}
 
?>
How to use IRC

Now a few other things are important. First, to stay connected. And second, how to make functions for the bot.

When I am talking about the first subject, I am talking about PING and PONG. This is an technique from the IRC protocol to check of you are still there. This is needed, because sometimes you cannot send the QUIT command when you are stopping your bot. This can happen by just stopping your bot in the browser, or your ISP can crash down. ;-)

Before we use the PING / PONG technique, we need to read what the server is saying right? Well, for this i often use the explode() function. This function can separate a string, or integer (whatever you want) and will store all separated things into an array. We will separate the string we receive with a simple " " (space). And store the data into an array called "$ex".
Code:
<?php
 
// Prevent PHP from stopping the script after 30 sec
set_time_limit(0);
 
// Opening the socket to the Rizon network
$socket = fsockopen("irc.rizon.net", 6667);
 
// Send auth info
fputs($socket,"USER CMbot combined-minds.net CM :CM bot\n");
fputs($socket,"NICK CM-bot\n");
 
// Join channel
fputs($socket,"JOIN #cm-bot-test\n");
 
// Force an endless while
while(1) {
 
    // Continue the rest of the script here
    while($data = fgets($socket, 128)) {
 
        echo nl2br($data);
        flush();
 
        // Separate all data
        $ex = explode(' ', $data);
 
    }
 
}
?>
Now, we got a an array with all words in it. This is easy for checking the commands. The fourth word (in channel) is most of the time the first word said in the channel itself. It is the fourth word because you still have 3 big and important words before the text. So knowing you can just check $ex[3] is rather nice, isn't it? (notice $ex[3] is the fourth, because the array starts at zero, not one)

Lets check for the PING command shall we? The server will send you something like this:
PING :Unique-Code

The server expects you will send:
PONG :Unique-Code
Back to the server. But be warned, every server has another unique code. So we will extract the unique code from the server, and then send it back in a variable!

Code:
<?php
 
// Prevent PHP from stopping the script after 30 sec
set_time_limit(0);
 
// Opening the socket to the Rizon network
$socket = fsockopen("irc.rizon.net", 6667);
 
// Send auth info
fputs($socket,"USER CMbot combined-minds.net CM :CM bot\n");
fputs($socket,"NICK CM-bot\n");
 
// Join channel
fputs($socket,"JOIN #cm-bot-test\n");
 
// Force an endless while
while(1) {
 
    // Continue the rest of the script here
    while($data = fgets($socket, 128)) {
 
        echo nl2br($data);
        flush();
 
        // Separate all data
        $ex = explode(' ', $data);
 
        // Send PONG back to the server
        if($ex[0] == "PING"){
            fputs($socket, "PONG ".$ex[1]."\n");
        }
 
    }
 
}
 
?>
This should not be difficult right? Well then, lets continue to making your own commands! Lets make a command to let the bot simply say something in the same room the command is given in.

There are some problems with this though. But i will help you along the way, for i have done this a trillion times a few years ago. The problem is simple, when a command is given by the server it adds a newline, and carriage return with it. (not always the carriage return) So when you are checking a command, and it is the last word from this line, it has the newline after it.

This gives the following problem. When you want to check the word for a command, and you will simply use the if() function it won't work. This is because !command is not the same as !command\n for example. So we first have to strip the word we want to check from the newline and carriage return.

This is very simple though:
Code:
<?php
 
$command = str_replace(array(chr(10), chr(13)), '', $ex[3]);
 
?>
What this does, is replacing an array of both newline, and carriage return with nothing. An saves that word in the $command variable. The chr() function returns an ASCII value by giving it's number. Check this website for all ASCII numbers.

Now you can easily check the $command for if it contains the command you want! Well then, lets continue with the command. First we need to check if the command variable contains the correct command. And then, we need an action for that command. To keep it simple, we will let the bot say something in the channel the command is given OK?

First we need to know more about the IRC protocol. When someone says something, the protocol will send something like this:
:Nickname!Host@name PRIVMSG #cm-bot-test :The stuff thats said

This little line is very resourceful. It contains the nickname of the person who said it. It contains the hostname (good for a admin module). It contains the channel, and it contains the string the person said in the channel.

So lets take a close look at that line, if we want to know the channel it's said in. We need the third word. So $ex[2] contains the channel!

Now lets use our freshly learned knowledge, and use it on the bot!
Code:
<?php
 
// Prevent PHP from stopping the script after 30 sec
set_time_limit(0);
 
// Opening the socket to the Rizon network
$socket = fsockopen("irc.rizon.net", 6667);
 
// Send auth info
fputs($socket,"USER CMbot combined-minds.net CM :CM bot\n");
fputs($socket,"NICK CM-bot\n");
 
// Join channel
fputs($socket,"JOIN #cm-bot-test\n");
 
// Force an endless while
while(1) {
 
    // Continue the rest of the script here
    while($data = fgets($socket, 128)) {
 
        echo nl2br($data);
        flush();
 
        // Separate all data
        $ex = explode(' ', $data);
 
        // Send PONG back to the server
        if($ex[0] == "PING"){
            fputs($socket, "PONG ".$ex[1]."\n");
        }
 
        // Say something in the channel
        $command = str_replace(array(chr(10), chr(13)), '', $ex[3]);
        if ($command == ":!sayit") {
            fputs($socket, "PRIVMSG ".$ex[2]." :Combined-Minds.net irc bot tutorial!\n");
        }
 
    }
 
}
?>
Credits were given at the start of the thread.
You may have to fiddle with the scripts a little.

Enjoy!

!SR - Learn This BamBam
__________________
http://blazinscene.us
Reply With Quote
The Following User Says Thank You to BamBam0077 For This Useful Post:
Demon-Cod3rs (05-05-15)
  #2  
Old 05-05-15, 13:44
Demon-Cod3rs's Avatar
Demon-Cod3rs Demon-Cod3rs is offline
Banned
 
Join Date: Apr 2015
P2P
Posts: 47
Default
http://www.dreamincode.net/forums/to...rc-bot-in-php/


Also good IRC chatroom would be good to add to this where you can set up in ssh so users can chat too
Reply With Quote
  #3  
Old 05-05-15, 13:47
BamBam0077's Avatar
BamBam0077 BamBam0077 is offline
Support
 
Join Date: Jul 2013
P2P
Posts: 260
Default
If you have irc tutorials please do share I am interested
__________________
http://blazinscene.us
Reply With Quote
  #4  
Old 05-05-15, 13:50
Demon-Cod3rs's Avatar
Demon-Cod3rs Demon-Cod3rs is offline
Banned
 
Join Date: Apr 2015
P2P
Posts: 47
Default
yes i do ill post it up soon as mine very bizy at mo mate but when i get too it ill post on my forum about it mate nps


try this one

http://www.codeography.com/2012/09/2...rc-server.html
Reply With Quote
Reply

Tags
bot , creating , irc , php

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump



All times are GMT +2. The time now is 03:15. vBulletin skin by ForumMonkeys. Powered by vBulletin® Version 3.8.11 Beta 3
Copyright ©2000 - 2018, vBulletin Solutions Inc.