Documentation
Faucet Scripts
In Faucet Collector 2.0 Faucet Scripts were introduced. It might seem pretty hard at the start, but once you get the ideas it should be fine.
You do need to have a little programming knowledge to be able to add your own scripts.
If you want to share your script and get it listed on our site you can upload it here.
Faucet Scripts are using C# (dotnet) as programming language. You can take a look here to check the C# syntax and learn some basics or watch some videos.
Getting started
Make sure you read the Walktrough below before starting to create your own scripts.
Faucet Script - All the availble properties and methods you can use in Faucet Script are listed here.
Full Example - A fully working example of moonliteco.in.
Empty Example - You can use this template if you want to start from scratch.
Walkthrough
Faucet Scripts are roughly divided into the following parts:
Login, Captcha Solving, Claiming, Checking results and Settings.
These different sections all contain predefined methods where you can place your code.
Return value
Most methods that are available have an int
(number) as return type.
The value returned in these methods is used to determine if the method was successful or not.
If you return 0 then you will tell Faucet Collector everything is good and the bot can continue. If you return a value bigger than 0 then you are telling Faucet Collector something isn't right and the bot needs to wait a couple of seconds before retrying.
So if you want to search for a button on the faucet website but cannot find it, then you can return 30 to wait 30 seconds before the next attempt.
First example
Lets show a small example:
public override int DoLogin()
{
var button = ElementById("login-btn");
if (button == null)
{
Reload = true;
return 15;
}
Click(button);
return 0;
}
The first line public override int DoLogin()
is the definition of this method. In Faucet Script there are a couple of predefined methods where you can add to your scripts. All the methods that are available are defined below.
The next line var button = ElementById("login-btn");
will try to find an element with the id "login-btn" on the faucet website. Check the Finding elements section on how to locate elements on the faucet website.
The line if (button == null)
will check if the button was actually found on the faucet website.
If the button isn't found then we will set the variable Reload = true;
that tells Faucet Collector to reload the page before doing the next attempt.
And the return 15;
tells the bot to wait 15 seconds before trying the next attempt.
If the button is found it will click on the button Click(button);
and return 0;
so Faucet Collector knows the method was successful and the bot can proceed.
Extended example
Now lets extend the example a little further:
public override int DoLogin()
{
var button = ElementById("login-btn");
if (!IsVisible(button))
{
return Fail("Login button not found");
}
Click(button);
return base.DoLogin();
}
In this example we have changed if (button == null)
into if (!IsVisible(button))
. It is basically doing the same as before but now it will also check if the button is actually showing on the faucet website.
We have also replaced Reload = true; return 15;
with return Fail("Login button not found");
. This will also be doing exactly the same as before except its now a one-liner that will also show a log entry in the Log that is visible on the bottom of Faucet Collector. This is helpful to show that something went wrong with the script.
And the last line we replaced return 0;
with return base.DoLogin();
. In general this is also the same, but now you let Faucet Collector also execute its DoLogin method. This example will also return 0 as value, but for some methods it can be useful to let Faucet Collector handle it. We will get to that later.
Finding elements
A faucet website is build up with html. In Faucet Script you can easily find html elements with the following methods
Element by Id
Finding an element by id is the easiest option to locate an element. Most of the time there is only one html element on the website with that id, so not much can go wrong. You can use it this way:
var emailInput = ElementById("Email");
SetText(emailInput, "[email protected]")
To find out if you can use this method you can right click on the element in Chrome and select "Inspect element". This will open a new window (Chrome Developer Tools) and selects the html element:
As you can see the html of the Email element is <input class="form-control input-validation-error" id="Email" name="Email" placeholder="Email Address">
Because this element has id="Email"
you can find it with ElementById
Note: if there are also other elements with that same id, or if the id is changed on each reload, you need to use another method to locate the element.
Element by Name
Its basically the same as ElementById but it will try to find the html element that has name="Email"
. For example:
var emailInput = ElementByName("Email");
Element by Class
Many html elements have one or multiple class attributes. Often you can also use these to locate elements.
For example if there is an element that shows the username:
You can find this element by class:
var user = ElementByClass("logged_in_username");
if (user != null && user.Text == "faucetcollector")
{
return true;
}
return false;
Element by LinkText
Another option to find an element is by searching for its link text.
It will search for all <a>
html elements on the website. The following example locates the <a>
element with "Switch to Recaptcha" as text tries to click on it.
Click(ElementByLinkText("Switch to Recaptcha"));
Element by XPath
Sometimes the faucet website doesn't assign an id, name or class to the element you want to use, or there are multiple elements that meets that criteria.
If that is the case then you can try to find the element using XPath.
You can take a look here how xpath works and how to get an xpath for your element.
To find this button you can use the following syntax:
var submitButton = ElementByXPath("//div[@id='CaptchaPopup']//input[@class='submit-button']");
if (!IsVisible(submitButton))
{
return Fail("Button not found.");
}
Click(submitButton);
First part //div[@id='CaptchaPopup']
tries to find the <div>
element with the id "CaptchaPopup". The second part of the XPath //input[@class='submit-button']
only tries to locate elements inside the <div>
element that was found in the first part. It will look for a <input>
element that has the class attribute "submit-button".
You can use ElementsByXPath
to return multiple elements that complies with the xpath. For example:
var errors = ElementsByXPath("//div[@class='error_msg' and @style='']");
if (errors.Any())
{
var errorMsg = errors.FirstOrDefault();
return Fail("Error message is visible: " + errorMsg.Text);
}
This example tries to find all <div>
elements that has the class "error_msg" and an empty style attribute.
If there are any elements found it will log an error with the Text of the first element.
Script methods
In the previous section we explained how to get elements on a page. This section will explain what you can do with these elements and some other handy functions.
IsVisible
With IsVisible
you can check if the element is found and if it is visible on the page.
var fail = ElementByXPath("//div[contains(@class,'alert-danger')]");
if (IsVisible(fail))
{
return Fail("Login failed: " + fail.Text);
}
Click
With Click
you can click on an element you found. For example a button:
var loginButton = ElementById("SignInButton");
if (!IsVisible(loginButton))
{
return Fail("Login button not found.");
}
Click(loginButton);
SetText
With SetText
you are able to add text to an input field.
var address = ElementByXPath("//input[@ng-model='address']");
if (!IsVisible(address))
{
return Fail("Unable to locate the Waves address input.");
}
SetText(address, GetSetting("Waves"));
With .Text
you can return the plain text from an html element.
var button = ElementByXPath("//button[contains(@class,'btn btn-primary') and @type='submit']");
Log("Text of the button is: " + button.Text);
ExecuteScript
With ExecuteScript
you can execute a piece of javascript. For example it can be used to accept the Cookie banner:
ExecuteScript("if($('.cc_btn_accept_all').length > 0) { $('.cc_btn_accept_all')[0].click(); }");
Or if you want to use jquery to find an element and return its value you can do this:
var minutesStr = Convert.ToString(ExecuteScript("return $('#clockdiv .minutes')[0].innerText"));
if (string.IsNullOrEmpty(minutesStr))
{
return Fail("Minutes not found");
}
int minutes = Convert.ToInt32(minutesStr);
Log("There are " + minutes + " minutes left");
Wait
You can use Wait
to pause the script for a few seconds. Wait with no parameters will wait between 1 and 2 seconds. You can also specify a different wait time:
//Wait between 1 and 2 seconds
Wait();
//Wait between 15 and 20 seconds
Wait(15, 20);
//Wait 5 seconds
Wait(5);
CheckForPopups
CheckForPopups
can be useful if the faucet opens popups (new browser windows) all the time. Faucet Collector will also check for popups on a regular basis, but sometimes you also need to check them in your script.
Faucet Collector will try to detect the right browser window by using the title that you defined in the Start method. If CheckForPopups
method returns a value greater than 0 it couldn't detect the right window and you should return the same value in your script.
//Check if there are any popups opened and close them if there are any.
var sleep = CheckForPopups();
if (sleep > 0)
{
//Something went wrong.
return sleep;
}
SelectOptionByValue
SelectOptionByValue
can be used when there is a <select>
dropdown on the page.
For example if you want to select "solvemedia" in this dropdown <select id="dropdown"><option value="solvemedia"><option value="recaptcha"></select>
then you can use the following method:
var dropdown = ElementById("dropdown");
SelectOptionByValue(dropdown, "solvemedia");
Navigating
If you want to open another website you can use GoToUrl("https://www.google.nl")
to navigate to a different page.
Most of the time you don't need to do this because you will define a base url in the script settings and many times you will be clicking buttons to navigate to a different page.
Start
The Start method is where you need to setup some of the required settings. It will be the first method that will be called when you press the Go button in Faucet Collector.
public override void Start()
{
//Title that is visible in the browser window. It is used to close popups.
Title = "moon dogecoin";
//After we did try to claim on the faucet we search for these elements to determine if it was a success or a fail
SuccessXPath = "//div[contains(@class,'alert-success') and contains(text(), 'success')]";
FailXPath = "//div[contains(@class,'alert-danger')]";
//Let Faucet Collector start up everything
base.Start();
}
The Title
property is used to close popup windows. It will know by looking at the browser title which popup windows it needs to close and what window holds the faucet website.
If the title changes you can defined multiple titles by using the | character to separate them.
Title = "claim free bitcoin|coinmine.online";
The SuccessXPath
and FailXPath
properties are used at the end of the script in the Checking Results section.
For example if it finds one of the elements from the SuccessXPath, and it is visible, then it will flag the claim attempt as a success.
If there is no element visible from the SuccessXPath it will try to find elements using the FailXPath. If it find a visible element it will flag the claim attempt as a failure.
If no elements are found it will keep trying for 30 seconds. If then still no element is visible it will also markt the attempt as failed. You can also use the | character to specify multiple XPaths.
And finally don't forget to call the base.Start();
in the end, otherwise the script won't continue.
Settings
Defining settings
Every script needs to have the settings defined. All scripts need to tell Fauect Collector what the faucet its website is. You can do it like this:
public override FaucetSettings Settings
{
get
{
return new FaucetSettings("http://faucetcollector.com/");
}
}
You can also define multiple properties that the user can enter values in. For example if you want to ask for the user its BTC address you can do it like this:
public override FaucetSettings Settings
{
get
{
return new FaucetSettings("http://faucetcollector.com/bitcoin/")
{
new FaucetSetting { Name = "BTC", Display = "BTC wallet", Type = EditorType.Wallet, Required = true}
}
}
}
This will show an input on the Faucets tab inside Faucet Collector like this:
You can also define multiple input properties like this:
public override FaucetSettings Settings
{
get
{
return new FaucetSettings("http://faucetcollector.com/bitcoin/")
{
new FaucetSetting { Name = "Email", Display = "Email", Type = EditorType.TextBox, Required = true },
new FaucetSetting { Name = "Password", Display = "Password", Type = EditorType.Password, Required = true },
new FaucetSetting { Name = "UseSolveMedia", Display = "Use SolveMedia", Type = EditorType.CheckBox, Default = true }
}
}
}
Retreiving setting
The Name
field can be used to get and set values in your script. In one of the the examples the Name
is set to "BTC". To get the value in your script you can do GetSetting("BTC")
. For example:
var addressInput = ElementByName("address");
if (!IsVisible(addressInput))
{
//We couldn't find it. Register it as a fail so it can reload the page and try again in 10-15 seconds.
return Fail("BTC address input not found.");
}
SetText(addressInput, GetSetting("BTC"));
You can also store values in the settings that you can use to retrieve later. This next example stores the current date in a setting if it isn't there yet:
var claimTime = GetDateTimeSetting("ClaimTime");
if (!claimTime.HasValue)
{
SetSetting("ClaimTime", DateTime.Now);
}
Setting types
Text
EditorType.TextBox
and EditorType.Wallet
can be used for text input.
Password
EditorType.Password
can also be used for text input, but it won't be visible.
To retrieve the value of the password field you need to use GetPassword("Name")
Checkbox
EditorType.CheckBox
is used for true/false settings.
The value for the CheckBox can be retrieved by using GetBoolSetting("Name")
.
Combobox
EditorType.ComboBox
is used to generate a dropdown like this:
You can define the items in the dropdown like this:
new FaucetSetting {
Name = "AutoRedeem",
Display = "Auto redeem",
Type = EditorType.ComboBox,
Items = new List<string>
{
"None",
"1000% BTC Bonus",
"500% BTC Bonus",
"100% BTC Bonus",
"50% BTC Bonus",
"10% BTC Bonus"
},
Default = "100% BTC Bonus"
}
Check Combobox
The EditorType.CheckComboBox
is almost the same as the ComboBox but it allows multiple items to be selected:
Example how to define this dropdown:
new FaucetSetting() { Name = "Games", Display = "Enabled games", Type = EditorType.CheckComboBox, Items = new List<string> { "Turbofaucet", "Slots", "Wheel", "Dice", "Plinko" }, Default = "Turbofaucet;Slots;Wheel;Dice;Plinko;", Required = true },
The value of the setting will have ; separated the checked items. You can use this setting like this:
var games = GetSetting("Games");
//checkedGames is a string[] array that will hold the checked games.
var checkedGames = games.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
Numeric
EditorType.Numeric
can be used if you want the user to input a number.
new FaucetSetting() { Name = "DiceBet", Display = "Dice bet", Type = EditorType.Numeric, Default = 10 },
Will result in this setting:
You can get the number using GetIntSetting("Name")
:
var bet = GetIntSetting("DiceBet");
Log("The requested bet is: " + bet);
Login
The login part is divided into the following methods:
public override bool IsLoggedIn()
public override int BeforeLogin()
public override int DoLogin()
public override int AfterLogin()
IsLoggedIn
The IsLoggedIn method is the first method that is called after the Start method. In here you can check if Faucet Collector is ready to do the claims or if it still needs to login into the faucet. Example:
public override bool IsLoggedIn()
{
//If there is an element that has the class "accountBalance" then we are logged in, because that element is only present when you are logged in.
return ElementByClass("accountBalance") != null;
}
If the "accountBalance" element is found this method will return true and Faucet Collector will continue with claiming section.
If the element is not found then it will return false and Faucet Collector will automatically start the Login flow by calling the BeforeLogin
, DoLogin
and AfterLogin
methods.
Once these three methods are done it will call the IsLoggedIn
method again to check if the login attempt was successful.
BeforeLogin
The BeforeLogin
method can be useful if you want to do something right before you do the actual login. For example open a popup window where the username/password is visible.
public override int BeforeLogin()
{
//Look for the signin button
var signInButton = ElementById("PageContent_SignInButton");
if (signInButton == null)
{
//Signin button not found, return an error.
return Fail("Signin button not found.");
}
//Signin button found, now click it to open the login window.
Click(signInButton);
//let Faucet Collector continue.
return base.BeforeLogin();
}
DoLogin
Then in the DoLogin
you can do the actual login.
For example:
public override int DoLogin()
{
//Find the input field that holds the email address
var signInEmail = ElementById("SignInEmailInput");
if (signInEmail == null)
{
//We couldn't find it. Register it as a fail so it can reload the page and try again in 10-15 seconds.
return Fail("Signin email input not found.");
}
var signInPassword = ElementById("SignInPasswordInput");
if (signInPassword == null)
{
//We couldn't find it. Register it as a fail so it can reload the page and try again in 10-15 seconds.
return Fail("Signin password input not found.");
}
//Email and password input found, update the value of the input with the email address and password the user entered in Faucet Collector
SetText(signInEmail, GetSetting("Email"));
SetText(signInPassword, GetPassword("Password"));
//Now we search for the login submit button
var loginButton = ElementByXPath("//button[contains(@class,'btn btn-primary') and @type='submit']");
if (loginButton == null)
{
//We couldn't find it. Register it as a fail so it can reload the page and try again in 10-15 seconds.
return Fail("Login button not found.");
}
//We are ready to click the login button.
Click(loginButton);
//Let Faucet Collector continue
return base.DoLogin();
}
AfterLogin
Optionally you can use the AfterLogin
method to check if there is some error displayed.
For example:
public override int AfterLogin()
{
//Check if the login doesn't show an error message.
var failedLogin = ElementById("BodyPlaceholder_FailedSignInPanel");
if (IsVisible(failedLogin))
{
if (failedLogin.Text.Contains("is not registered with CoinPot"))
{
//Invalid email address entered. Log and disable this faucet.
Log("Please enter a correct coinpot.co email address.");
Disable();
}
return Fail("Login failed: " + failedLogin.Text);
}
//we are good to continue
return base.AfterLogin();
}
Captcha Solving
The captcha part is divided into the following methods you can override:
public override int BeforeSolveCaptcha()
public override int DoSolveCaptcha()
public override int AfterSolveCaptcha()
BeforeSolveCaptcha
The BeforeSolveCaptcha
can be used to do something right before the captcha is solved. For example to switch between SolveMedia or reCAPTCHA if the faucet allows that:
public override int BeforeSolveCaptcha()
{
//Check if the user wants to do SolveMedia or reCAPTCHA.
if (GetBoolSetting("UseSolveMedia"))
{
//Make sure SolveMedia is active by clicking the link.
Click(ElementByLinkText("Switch to SolveMedia captcha"));
}
else
{
//Make sure reCAPTCHA is active by clicking the link.
Click(ElementByLinkText("Switch to Recaptcha"));
}
//Wait a little (1 - 2 seconds) for the captcha to switch.
Wait();
//Return we are ready to proceed
return base.BeforeSolveFaucet();
}
DoSolveCaptcha
The DoSolveCaptcha
does the actual solving. If you override it don't forget to call base.DoSolveCaptcha();
Calling base.DoSolveCaptcha()
will first do a check if there is any CoinHive POW needed to be solved.
After that it will check if there is any SolveMedia Captcha present on the page. If it is found then it will automatically solve the SolveMedia Captcha using the settings entered in the bot.
When there is no SolveMedia present it will check if it can find reCAPTCHA on the page. If it does find reCAPTCHA then it will automatically try to solve it using the settings entered in the bot.
If that is fine you can leave your method like this:
public override int DoSolveCaptcha()
{
//We will let Faucet Collector handle the captcha solving.
return base.DoSolveCaptcha();
}
From anywhere in your script you can call SolveCaptcha()
to start the captcha flow (it will run BeforeSolveCaptcha
, DoSolveCaptcha
and then AfterSolveCaptcha
).
Or you can call DoSolveCaptcha()
directly to solve the captcha on the page and skipping BeforeSolveCaptcha
and AfterSolveCaptcha
.
If your faucet isn't using reCAPTCHA nor SolveMedia then you can use the DoSolveImageCaptcha
method to let the bot solve an image captcha.
For example:
public override int DoSolveCaptcha()
{
//check for the custom captcha image
var captchaImage = ElementByClass("captchasnet_captcha_content");
if (IsVisible(captchaImage))
{
//get the input where the result of the captcha needs to be entered.
var captchaInput = ElementByClass("captchasnet_captcha_input_box");
if (!IsVisible(captchaInput))
{
return Fail("ImageCaptcha input field not foundd");
}
//We can use this method to let Faucet Collector solve the image captcha and put the result into the captchaInput element
var sleep = DoSolveImageCaptcha(captchaImage, captchaInput);
if (sleep > 0)
{
return sleep;
}
//return we are done.
return 0;
}
else
{
//Let Faucet Collector continue. It will check for SolveMedia and reCAPTCHA.
return base.DoSolveCaptcha();
}
}
AfterSolveCaptcha
The AfterSolveCaptcha()
can be used to do something after the captcha is successfully solved. For example to close a button:
public override int AfterSolveCaptcha()
{
//Try to click the close button of the popup
var closeButton = ElementByClass("close");
Click(closeButton);
//Let Faucet Collector continue.
return base.AfterSolveCaptcha();
}
Claiming
The claiming part is divided into the following methods:
public override int BeforeSolveFaucet()
public override int DoSolveFaucet()
public override int AfterSolveFaucet()
BeforeSolveFaucet
The BeforeSolveFaucet
will be called right after you are successfully logged in.
In this method you can do something before you do the actual claim. For example open a popup window:
public override int BeforeSolveFaucet()
{
//Find the button to open the popup window where we can solve the captcha and claim on the faucet.
var claimButton = ElementByClass("claimButton");
if (!IsVisible(claimButton))
{
//We couldn't find the button, return we have a failure.
return Fail("Claim button not found or not visible.");
}
//Click the button to opent the popup window
Click(claimButton);
//Let Faucet Collector Continue.
return base.BeforeSolveFaucet();
}
DoSolveFaucet
In the DoSolveFaucet
method you can do the actual claiming on the faucet.
Most of the cases you need to find the submit button. Solve the captcha. And then click on the submit button.
Here is an example used on bitfun:
public override int DoSolveFaucet()
{
//Find the submit button to claim on the faucet
var submitButton = ElementByXPath("//div[@class='modal-footer']/button[contains(@class, 'btn btn-primary') and not(@data-dismiss)]");
if (!IsVisible(submitButton))
{
//Unable to find the submit button - return the failure.
return Fail("Submit button not found or not visible.");
}
//We need to solve the captcha on this page before clicking the Login button.
//We use the SolveCaptcha method for this. SolveCaptcha will call BeforeSolveCaptcha, DoSolveCaptcha and AfterSolveCaptcha
var result = SolveCaptcha();
if (result > 0)
{
//Unable to solve the captcha - return the failure
return result;
}
//The Captcha is solved, click the submit button
Click(submitButton);
//Let Faucet Collector continue its work
return base.DoSolveFaucet();
}
AfterSolveFaucet
Now that the faucet is solved you can do something after it did the claim.
If you got nothing to do, then you can leave it like this:
public override int AfterSolveFaucet()
{
//This faucet has nothing to do here. We will let Faucet Collector handle it.
return base.AfterSolveFaucet();
}
For example the moon faucets briefly show a processing modal. The AfterSolveFaucet
could be used to wait for the processing modal to go away. For example:
public override int AfterSolveFaucet()
{
//we create a counter so we don't wait forever
int attempts = 0;
//Find the element that is used for the "Processing" window.
var processing = ElementById("ProgressModal");
while (processing != null && processing.Displayed && attempts < 10)
{
//The "Processing" window is still there
//Increase the attempts, so we can exit after 10 attempts
attempts++;
//Wait one second before the next attempt
Wait(1);
//Now get the "Processing" window again.
processing = ElementById("ProgressModal");
}
//We are ready. The "Processing" window is gone or we did 10 attempts.
//Either way we let Faucet Collector continue.
return base.AfterSolveFaucet();
}