Web Marketing
Live Chat | Request a Quote

Cogniter Blog

Musings on design, development, and digital marketing

CSGO Gambling Skins Jackpot: How to Log into Steam’s Servers and Web Interface with a Node.js Bot?


Gaming has always been a fascinating segment of the world entertainment media. Valve Corporation developed Steam to cater to this same segment. Currently, its gaming platform hosts thousands of games and caters to gamers from not only the US, but Europe, Japan, and the rest of the world.

Counter-Strike Global Offensive (CSGO) a popular Steam game. Being popular, it has encouraged the game's programmers to develop and sell cosmetic “skins”, also known as Counter Strike skins. Skins are short snippets of software that integrate with players and make them more powerful. While some skins add only a minuscule power to a player's punch, others can decide the fate of an entire game. Naturally, those in the latter category command the highest prices in skins' marketplace. (Only game developers can develop skins.)

A lot of the players cannot or don't want to spend real dollars on purchasing skins. So they resort to skin gambling or CSGO betting. Several CSGO gambling sites exist where gamers hedge their skins in a winner-takes-all play. In fact, you can create your own jackpot website. All you need is a Steam account and familiarity with Node.js.

In this tutorial you will learn to implement a crucial part of developing a full-fledged Steam jackpot website: Creating a bot that can log into a Steam server, be an active resident there, listen to Steam events, and make API requests to other Steam servers with the goal to communicate and exchange trade offers between gamers. Such bots are at the root of many Steam-independent gambling websites. If the task seems ovewhelming, you can consult an expert from a Node.js development company, such as Cogniter.


Developing a CSGO betting bot at the root of a Steam gambling website is neither as easy as publishing hello, world nor as challenging as designing the C language. You will need a deeper-than-superficial familiarity with programming and the following tools:

  1. Node.js: a JavaScript framework, will be used to develop a bot for a Steam jackpot website. Familiarity required: Above beginner. So we are going to create a Node.js application.
  2. node-steam: A Node.js library for interfacing with Steam servers. Connects directly to the servers and provides well-thought abstractions without taking away the power to manipulate low-level procedures. Downloadable from GitHub.
  3. node-steam-totp: A Node.js library that generates a two-factor authentication code. This piece of code is essential for a secure login into a Steam server.
  4. node-steam-weblogon: A node-steam implementation, used to log into Steam's web servers.
  5. node-steam-web-api-key: A Node.js library, used to interact with Steamworks' API key.
  6. A Steam account. The APIs should be enabled.


Once the libraries have been downloaded and tested to be working, you can start off with implementation.

Create a Node.js Module

Keep node-steam, node-steam-totp, node-steam-weblogon, node-steam-web-api-key, and core Node.js library inside the module's scope.

  EventEmitter			= require('events').EventEmitter,
  Steam				= require('steam'),
  SteamWebLogOn			= require('steam-weblogon'),
  GetSteamAPIKey		= require('steam-web-api-key'),
  SteamTotp			= require('steam-totp'),
  Util				= require('util'),
  Fs				= require('fs'),
  Crypto			= require('crypto'),
  Path				= require('path'),
  Config			= require('./../../config/config.json');

Create a Bot Function

The bot function will be the Steam bot's constructor. The name associated with the Steam account will be passed as a parameter to the constructor.

function Bot(accountName) {
  if (!accountName) {
    throw new Error("Bot account name is required.");

Add EventEmitter to the Bot Function

Through EventEmitter, the Steam bot can communicate with other services through its listener and emitter events.

  this._client = new Steam.SteamClient();
  this._user = new Steam.SteamUser(this._client);
  this._web = new SteamWebLogOn(this._client, this._user);
  this._account = accountName.trim().toLowerCase();
Util.inherits(Bot, EventEmitter);
module.exports = Bot;

Create a SteamClient Object

Store the object inside the bot's this._client.

Create SteamUser and SteamWebLogOn

SteamUser requires a Steam client to function. SteamWebLogOn requires a Steam client and several SteamUser objects to work flawlessly. The last two lines of the code in Image 3 show that each Bot instance inherits the all of EventEmitter.

Let the World See Your Bot

The statement module.exports = Bot; statement reveals the Bot object to the outside world.

Log into Steam with getBotDetails()

getBotDetails() extends the bot constructor and fetches the details needed to log into a Steam account through a bot. Details like a shared secret (used for two-factor authentication) and identity secret are utilized for trade confirmations. Account name and password are also fetched to log into a Steam server. The data needed for configuration is taken from config.json (Image 1).

var options {…} creates a structure to store login data. The structure is then passed to a SteamUser instance's logOn().

Bot.prototype.getBotDetails = function () {
  var profile = Path.resolve('../config/profiles/' + Config.bot[this._account].account_name + '.json');
  if (Fs.existsSync(profile)) {
    var _2fa = JSON.parse(Fs.readFileSync(profile, 'utf8'));
    this.shared_secret = _2fa.shared_secret;
    this.identity_secret = _2fa.identity_secret;
  } else {
    throw new Error('Bot profile file not found.');
  var options = {
    account_name: Config.bot[this._account].account_name,
    password: Config.bot[this._account].password,
    two_factor_code: SteamTotp.generateAuthCode(_2fa.shared_secret)
  return options;

Log into a Steam Server

Bot.logIn() function is doing the actual bot account logon to the Steam server and Steam web community (or Node.js server). A connection to the server is initiated by executing connect() of a SteamClient object.

A "connected" event is emitted as soon as the connection is established. SteamClient can listen to the emission through the "on" method.

Bot.prototype.logIn = function () {
  this._client.on('connected', () => {
  this._client.on('logOnResponse', (logonResp) => {
    if (logonResp.eresult === Steam.EResult.OK) {
      this.emit('loggedIn', logonResp);
      this._web.webLogOn((sessionID, newCookie) => {
        this._sessID = sessionID;
        this._wcookie = newCookie;
          sessionID: sessionID,
          webCookie: newCookie
        }, (err, APIKey) => {
          this._APIKey = APIKey;
    } else {
      this.emit('LoginFailed', logonResp);

Inside the "connected" event listener, a SteamUser object's logOn() is executed. The details are passed to logOn() through getBotDetails().

SteamClient remits logOnResponse() when an attempt to log in is made. After being listened to, the event passes a logOnResp parameter. If eresult == Steam.EResult.OK, the login was successful.

Log into Steam's Web Interface

steam-tradeoffer-manager is used to log into Steam's web interface. Call weblogon() from the SteamWebLogOn library. weblogon() accepts a callback function with two parameters: session ID generated for the web logon and cookies that identify the bot. Once the session ID and cookies are fetched, you can get an API key for your account by calling GetSteamAPIKey() of node-steam-web-api-key. The API key is used by libraries to utilize Steam community features.

Voila – The Bot is Ready

Your steam trade bot is ready to run in the background with minimal functionality. The functionality can be enhanced to create jackpot websites and trade skins.


This short guide contains information for any intermediate level Node.js developer to code a bot. If you find the task overwhelming, or if your business needs a bot developed reliably and quickly, consider hiring our Node.js developers. We have several years' experience in working in Node.js, and have developed multiple Steam bots for our clients during this period.

Posted By Chetan Anand at
Like Cogniter on Facebook Share on Google+ Cogniter on Pin It

A Guide to Input File Structure used in Royal Bank of Canada’s ACH Direct Payments


ACH Direct Payments is one of the five methods available to the Royal Bank of Canada (RBC) commercial account holders accepting regular payments from their clients. It eases receivables management for businesses but for developers, working with ACH Direct Payments is a challenge.

Imagine no pre-built SDKs, no sandbox environment, and no API interface. You are supposed to work under these constraints and be perfect because money is involved. The challenge is huge but not insurmountable.

We wrote 3 Techniques to Simplify Working with Royal Bank of Canada’s ACH Direct Payments for developers who are working with this payment system for the first time. This blog is a continuation of that series. Today we will share with you the Input File Structure.
What is an Input File? And Why Should You Care?
The RBC’s servers accept data as Flat, EDI, or XML files. These files are also known as input files because they contain the information that identifies a customer, such as her name, address, transaction amount, etc.

The Input Files follow a strict format which has been detailed on the RBC’s official website. Any deviation from the recommended standard may lead to bugs, or worse. Avoid such a scenario with our overview.

Input Files are Divided into Sections or Records
An input data file is divided into separate sections some of which store the file’s purpose and identify its type. Each file contains a record in each line. In a line character position is used to identify the starting and ending of different kinds of data. For example, the first 16 characters can carry a person’s first name, the second set of 16 characters can store an account holder’s last name, and the third set of 16 characters can represent a client’s account balance.

Four Essential Records
Each payment file has at least four kinds of records:

1.    Routing Record
2.    Header Record
3.    Basic Payment Record
4.    Trailer Record

Let’s view them one at a time.

Routing Record
The very first record in an input file, used by the RBC to decide if the information is a credit or a debit file. Each line in this record stores:

1.    File type: credit or debit
2.    File format
3.    File’s purpose: test or real-life
4.    File’s length, which can be 152 or 80 characters

The characters are put together in a fixed format which looks like:

•    Green tells whether a record is a debit or a credit file. AAPA will mean you want to collect money from customers and AAPD refers to the transfer money from you to your customers.
•    Orange tells the format of the file to be followed and the length of each record. Here, it tells that the input data file is in standard format and the length of the record should be 152 characters per line.
•    Blue text marks the record as a test file, so it will not be processed in production environment.
•    Red “NL” specifies that the records will span the full length of the standard i.e. 152, other possible value for NL is the 80. In that case, records length could be 80 characters.

Header Record
Header record explains the details of basic payment records, such as: How many payment records are included? And what is file creation number and file creation date?

A file creation number is the unique number assigned to each input data file that you create. This number can be used to identify the data from the reports produced by the RBC.

ACH Direct Payments is a batch processing system. The RBC does not respond immediately. So do not upload multiple input data files if you don’t notice an immediate response. Responses will appear after an interval of 4–5 hours.

The file creation number and file creation date are a good candidate to identify the response and associate it with your input data file for further automating the payment process.

The header record also contains the client’s number and name. Once you sign up for an RBC account capable of processing ACH payments, you are assigned two client numbers both having a different functionality. The first is used in your debit file and the second in your credit file.

•    For everything to work as planned, it is important to ensure a valid combination of Routing Record and client numbers is used in the Header Record.
•    Apart from all this, it’s crucial to stick to the format touched upon Routing Record.
•    Header Record follows Routing Record in the data file.

Routing and header records would look like the one below inside your flat input data file before encryption.


Basic Payment Record
Basic payment record is the actual payment transaction record. These are the individual’s monetary transactions that can be processed through RBC if the developer has access to data, such as a customer’s banking information, record number, customer number, amount to be deducted, and currency information.

To uniquely identify a payment and to backtrack (confirm) it from our own database we used the file creation number, customer number, and payment number field to create a unique number.

Then the fields can be used in the output data file (reports) from RBC to track the success and failure of the payments. You need to make sure that you have correctly placed the data in their required columns in your flat file as per the format guides. Otherwise, you are going to get errors back in the report. If you get error back from RBC you can check the proper reason on this link https://www.rbcroyalbank.com/ach/cid-212259.html

Some columns would have less data than the actual character length allows. In such a case, you would have to pad those places with blank value. You will get the padding and filler instructions inside the guides. Your basic payment record would look like the one below:


Trailer Record
Trailer record is the last record in the file. This record tells that how many payment records there are in the file and what the total payment amount is. The trailer record will look something like this.


Your completed non-encrypted file would look like the one below:

After the input data file has been created, encrypt it using public-key encryption and then upload it to the SFTP location for the RBC to process. When you upload the input data file to RBC it will automatically detect the new file and process it. Usually it takes few hours to schedule the processing of the file and provide you results back.

Below is the sample code to upload the input data file to RBC SFTP. This code is in PHP and is using cURL extension of PHP.

We hope that this post will get you started on the way to developing a solid understanding of Input Data files. For questions and suggestions, feel free to comment or write to us at consultation@cogniter.com

Posted By Chetan at
Like Cogniter on Facebook Share on Google+ Cogniter on Pin It

3 Techniques to Simplify Working with Royal Bank of Canada's ACH Direct Payments

TUESDAY, JUNE 20, 2017

 Commercial account holders at the Royal Bank of Canada (RBC) can stay on top of receivables—who has paid and who still owes them—through ACH Direct Payments, RBC Express Incoming Wires Reporting, Electronic Chargeback, Corporate Creditor Bill Payment Service, and Whole Lockbox. For a developer, working with any of these systems is a challenge but none poses more difficulties than ACH Direct Payments.
As if the absence of pre-built SDKs wasn’t a challenge in itself, for some unfathomable reason the RBC decided to go a step further and complicate things even more by not providing a sandbox environment and an API interface. So when a Canadian client asked us to integrate ACH Direct Payments with his website so he could accept recurring payments, we knew we had an uphill task in front of us. Nonetheless, we accepted the challenge. Two months later the system is up and working without a hitch.
Yet another successful and on-time delivery. Yet another happy client. But we wanted more this time… for you. So we asked our star developers, who worked on integrating ACH Direct Payments with a website, to share three techniques that will make future developers’ job easier.
If you have a Canadian client wanting to collect payments from her customers on a regular basis through the RBC’s ACH Direct Payments, reading these three tips can save you hours of frustration.

Technique 1: Keep Things Simple

The RBC provides five connectivity methods and accepts three data formats.
Connectivity Methods Data File Formats
1.      RBC Express File Transfer
2.      Secure FTP ?
3.      Connect: Direct Secure+
4.      A/P Link / Receivables Link
5.      AS2
1.      Flat Files ?
2.      EDI Files
3.      XML Files

In our experience, Secure FTP is the simplest way to connect to the RBC’s servers and Flat Files is the most straightforward format.
In fact, for our implementation, we opted for Secure FTP (SFTP) and if you choose SFTP, like us, you will need an IP, a username, a password, and a port to connect. As to the data files, they will be uploaded and stored on the RBC server. The server will then process your input files to create a report data file. The report data file will be placed in a different folder on the same server.

Technique 2: Understand Data Files

Payments in the RBC environment are handled through input data files, one type for receiving and the other for transferring the funds. An input data file is divided into separate sections some of which store the file’s purpose and identify its type.  Each file has at least four kinds of records:

1.      Routing Record
2.      Header Record
3.      Basic Payment Record
4.      Trailer Record
Although the data layout in the files has been standardized by the RBC (https://www.rbcroyalbank.com/ach/cid-212260.html), the absence of samples and references still pose a challenge in formatting. To ease things, we have created a short guide explaining Input Data files.

Technique 3: Stick to the Data File Structure on the RBC Server

Data files are uploaded and stored on the RBC server for processing. The input files are stored in /inbound and the output data—that is produced after server processing—is kept in /outbound/AAPA or /outbound/AAPD; the exact location dependant on whether the input file is a credit or a debit.
This overview of the directory structure will help you create a mental map:


Working with ACH Direct Payments is not easy. Keep things simple. Stick with the simplest connectivity method and file format, take time to understand Data File structure, and follow the data file structure on the RBC server. It will reduce the probability of bugs sneaking in and you can deliver the project in time.

Posted By Chetan at
Like Cogniter on Facebook Share on Google+ Cogniter on Pin It

3 Advanced Google Search Features for Webmasters


When it comes to technology, digital marketing in 2017 is lightyears ahead of traditional marketing. Google, Facebook, and other Silicon Valley companies have gathered so much data about consumers that—if you have access to the right tools—you can easily promote colour books to new parents, market flagship smartphones to high-flying executives, or find clients interested in your services right from your couch.

A lot of these powerful marketing tools require you to subscribe to a plan, but others are completely free. Google Search is one of the most powerful free research tools available to webmasters. Well utilized, it can provide content ideas, help you in keyword research, and tell you how your competitors are performing.
Take me to the Nth Link

Let’s start with a challenge we all can relate to: How to see beyond the hype?

The large platforms—Twitter, Facebook, Google, and others—are geared towards providing you the latest, the most shared content for each of your search queries which comes handy if that’s what you are looking for.

However, if you want to discover sites that just don't make it to the top of the search engine results for whatever reason and access that wealth of untapped information, develop a habit to append Google search URL with &start=NUMBER, where NUMBER is the top ranking websites you want to remove from search results. You can enter any integer between 0 and 999 and it will work.


Million Short is a nice alternative if you want to remove more than 1000 top links. Its interface is easier, too, and you don’t feel like coding.

Show Me x Results on a Page

This feature is related to &start=NUMBER and can be used with it. We are all aware that you can tell Google to display more than 10 results on a page. Set your preferences and voila! All your future search queries will display the results you want to see.


So far, so good.

But what if you want to see, let’s say, 50 results for one keyword and 70 for another. Changing Preferences is really a cumbersome way to go about it. A convenient method is to append &num=NUMBER to the search URL. The NUMBER can be between 0 and 100. For instance, &num=25 will return the top 25 results for a search query.


When used with &search=NUMBER, &num=NUMBER can be really powerful. The above image shows you the links ranking between 51 and 55 for the search query “life on Mars.”

Limit Results from a Country

Google’s Advanced Search allows you to limit your results to websites hosted in a specific country. The trouble is the ease of use, or its lack thereof.

Every time you want to limit your search to a country, you will have to access Advanced Search and select the country from a dropdown. It’s OK if you need country-specific result once or twice in a day. But if you are a webmaster, your frequency will be much higher.

A faster alternative will be to append &cr=countryUK or &cr=countryUS. These tags will limit your results to the UK or the US. Tags are available for most countries.

I Search From provides a more powerful and user friendly tool for country-specific search. You can even choose your device and city. An excellent way to see how your website is performing locally.


Google Search is a powerful tool that can make a lot of everyday SEO tasks easier. Don’t discount it. In upcoming posts, we will reveal more powerful features of Google.

Posted By Chetan at
Like Cogniter on Facebook Share on Google+ Cogniter on Pin It
Next >  Page: 1 of 5 

Blogs by Categories

Blogs by Years

Recent Posts