Love Triangle of Cashflow Cycle in Private Label

Amazon FBA Private Label – Cashflow Cycle

Private Label business on Amazon FBA have its own cashflow cycle. The amount we invest over inventory, require a flow at three points that is Factory, Transit & Warehouse. Once this cycle is complete, we are almost good for the longer period of time. The money invested at these three places will never come back to us for the life of product.

Cycle of Cashflow

  • Factory/Manufacturer/Supplier
  • Transit – Air/Ocean
  • Amazon FBA Warehouse


Shopping spree during Christmas, Easter, Black Friday, Cyber Monday, Amazon Prime Day etc we need inventory planning a head of time. If this is your first private label business over Amazon, you will need to find past history of your competitors during season with respect to high relevancy to item you are selling and around your organic keywords position in Search Results

Sales hike some niches, have their own increased sales at random month of year. Just like shopping spree, we need to take care of high sales months of our niche, for same inventory planning

Inventory Performance Index (IPI) is a metric at Amazon, that tells, if your inventory is becoming burden over Amazon, as you are not able to sell enough items? Therefore, while planning your inventory, take really good care of IPI score.

Amazon’s Storage Fees applies when you are unable to sell enough items for a given period of time. In order to keep our profits, we need to take really good care of stock level.

Minimum Order Quantity – MOQ

If production time of our item is a month and we are sending inventory via sea shipping, then usually it takes anywhere from 60 to 70 days for your inventory to reach Amazon FBA.

If you want to go slow, you will either order 2-month inventory at once or something, point is, you want to never go out of stock.

Proposed Solution

What if you order three months inventory? you will get good rates from supplier, you will have your inventory ready well ahead of time, no?

Pre Requisites:

  • You’ve confidence over your product’s success
  • You’ve estimated your inventory intelligently
  • Enough capital to buy 3 months inventory

So, if you meet the pre-requisites and order three months inventory in advance, you will be in good hands. All you will need is to order for 4th month, at second month of your launch. The fun part is that, you will not need to influx to order this 4th month’s inventory, rather, you will order from your earnings of 1st month. Thus a cycle of cashflow is maintained.

This three months inventory will definitely increase your investment, but you will be calm seas and enjoy smooth cashflow, down the road.

All the best!

Amazon FBA Private Label Product Launch Plan – Gantt Chart

Amazon FBA Private Label Workflow

Launching Private Label Product over Amazon, is not complex, yet, if we have some handy plan in hand, we not only keep track of our progress, but we will never miss an important step.


This phase will include product hunting and research. The intent will be to find a viable product.

  • Product Hunting & Research: Find viable product
  • Landing Cost Calculation: Product unit cost + Transaction Charges + Shipping Cost + Transaction Charges, per unit
  • Patent Check: Check patent yourself or hire someone off fiverr
  • Create Dummy Listing: Create a dummy listing over Amazon and confirm if there are any certificate requirements
  • Order Analysis: MoQ & Launch Cost: Find out what will be your initial inventory. We will calculate total launch cost here as well


We will contact our manufacturer/supplier during this phase and find if the product is according to our needs.

  • Shortlist Supplier: Find and communicate with few suppliers/manufacturers and shortlist them
  • Shortlist Freight Forwarders: Find and communicate with few freight forwarders (FF) and shortlist cost-effective yet dependable FFs
  • Call for Samples: Get samples delivered to your place
  • Call for Competitor’s product: Get items delivered to your doorstep
  • Evaluate Samples: Have samples and competitor’s item in hand, use, abuse and try to find quality & durability
  • Place Order: Once you are certain with the samples, place your order with supplier
  • Production: Start to end of Production
  • Inspection: Quality check of prepared inventory
  • Shipment: Picking up items from factory/port to Amazon FBA


This will go in parallel with sourcing phase.

  • Brand name: Get unique brand name, check if its not already registered over trademark registry
  • Logo Design: Get unique logo design that you can trademark down the road
  • Packaging Design: Make sure the packaging size/weight is within Amazon’s recommended specs
  • Website Setup: Prepare professional looking website


We will work on Product Listing over Amazon

  • Content Writing: Listing: Zero tolerance policy over quality of content
  • Photography: Get professional photography done
  • EBC: If you have plans for acquiring Brand Registry


We will try to cover ourselves by applying for trademark & patent.

  • Trademark Registration
  • Patent Registration


Different people use different launch strategies. Following example shows, when we want to run multiple launch strategies

  • Facebook Ads Manager & Page Setup
  • ManyChat Setup & Inegration with FB Page
  • FB Ad Setup
  • Rebate Key Setup
  • Launchpad setup

Download Free Private Product Launch template

All the very best with your Private Label product launch.

Amazon Best Seller Rank (BSR) Explained

The only publicly visible metric of product performance by Amazon is Best Seller Rank associated with each product or its variation, in a particular category.

BSR on Product Detail page

How does BSR is calculated? I guess very few people at Amazon’s core development team would know better. Since Amazon never published any detailed document including all the factors effecting BSR, Amazon sellers always have guess, assumptions and estimations. Moreover these assumptions are result of their own experience from product ranking and observing BSR dance or technical analysis.

If BSR number is higher, it means, sales are low and if BSR is smaller number, it means sales are increased.

BSR & Keyword Ranking

BSR, for sure is a function of sales or no sales. When an item is listed and there is no sales, the BSR will never be displayed, for obvious reason.

BSR & Keyword Ranking

As depicted in above image, when you start, you will have no (or undefined) BSR, for obvious reason that, no item is sold, so far.

First order, you will have some big BSR jump. Primarily, it seems like, the jump height and distance will depend upon, how many sellers have made 1 sale in last X days. Plus the quality of sales will effect how much keyword ranking will improve.

At second order, Amazon will decrease your BSR (improved), how much? there will be couple of factors, including but not limited to just your sales but your competition as well. The keyword ranking will improve, you will move up depending upon, how many sales your competition made in last X days on same keyword.


Following are some main factors that contribute towards change in BSR;

  • Your sales or no sales & your sales history
  • Sales or no sales & sales history of your competition
  • Your or your competitor’s sales momentum
  • Quality of sales, during search did user came to your listing from Storefront page or search result page. The purchase was from Gift Card, the buyer was Prime or not etc
  • Number of returns and their types
  • Negative or Positive Reviews
  • Sales of other products in your main and sub categories
  • Time of day & day of week
  • Shopping Spree
  • Out of Stock shoots your BSR

Technical Analysis

Example #1

Following is a graph using Helium 10’s Chrome extension. The product is best seller in one of its sub category.

1st Organic Rank Product

The blue line is Selling Price, while pinkish is BSR. Notice the high spikes in the start. Notice down the road, the BSR got improved.

Example #2

Now look at this item, ranked at last of page 7. Notice how many fluctuations are there and BSR is not getting stable.

To me, seems like its images and listing content are not perfect and its not ranked over main keyword.

7th Page on Search Result, last organic product


Instead of worrying about your BSR, you should focus on factors effecting it

  • Rank on more keywords
  • Keep Sales Velocity & its Momentum up
  • Better have dispose-off return handling or recall them to some 3rd party warehouse
  • Keep your Review Ratings up. Do follow up with every review regardless of its ratings. Prove you care & respect your buyer’s opinion

Amazon PPC Basic

Amazon PPC Basic - Teemya

Amazon Pay Per Click helps you increase sales velocity, keep sales momentum or increase your profits. Prior starting your PPC, you need to understand not just Advertising screen under Amazon Seller Central, but core concepts behind.

Here are some key points;

  • Sponsored Ad Types
  • Campaign Types
  • Keyword Targeting
  • Search Terms
  • Negative Keywords
  • Product listing content
  • Psychological influencers
  • Profits
  • Campaign Budget and Bid

Sponsored Ad Types

Consider them as Sweet Spots. Definitely, Amazon made those spots, premium for a reason. Therefore, we will use them to achieve our goals.

  • Search Result Page
    • Brand Headline ASIN (top & bottom)
    • Sponsored Product (top, middle & bottom)
  • Product Detail Page
    • Brand Ad (below Bullet Points)
    • Product Display Ad (below Buy Box)
    • Sponsored Product Strip (above review section)

There are few more pages where Amazon display sponsored products like Lightning Deals page.

Campaign Types

There are two types of campaigns, based upon Goals, we use each or both types of campaigns.

  • Automatic Campaign: Let Amazon find keywords for you
  • Manual Campaign: Dictate Amazon with your own keywords.

Keyword Targeting

The Keyword Targeting define which types of search terms are acceptable. The use depend upon your goal.

  • Broad
  • Phrase
  • Exact

Keyword: mini refrigerator

Types of Keyword Targeting

Regardless of targeting type single/plural, slight-misspelling, helper words like “for” are ignored.

In Automatic Campaigns, we would not provide Keyword Targeting since we do not provide keywords to target and leave everything on Amazon’s algorithm.

Search Terms

These are the words or phrases typed or selected (auto-suggest) by user. Depending upon their type of Keyword Targeting, our product listing may appear in front of them.

These search terms will appear depending upon Broad, Phrase or Exact match keyword targeting. In Automatic Campaign, since we do not provide any keyword, we will have random and wild search terms, regardless of keyword targeting.

Negative Keywords

The keywords, that do not achieve our goal(s) and established as non-worthy after 7 days, its wise to mark them as Negative Keywords.

We can put a keyword as negative at Campaign or Ad set levels.

The negative keyword will also have keyword targeting.

Generally, its a good practice to put keyword as negative in the source campaign or ad set prior moving to next.

Product listing content

The product listing content play an important role. Specifically, automatic campaign decides keywords from main/sub category, title, bullet points, description, backend search & platinum terms and product specifics. Some sellers believe keywords in reviews and EBC/A+ Content also play vital role in automatic keyword discovery.

Psychological influencers

Amazon badges influences buyer decision be it Best Seller or Amazon Choice or New Arrival. The digital coupon and Positive review rating 4.7+ will also put a positive impact on your buyer’s buying decision.


Particularly in Amazon PPC, profits is not always limited to just monetary value. Impressions, clicks, click-thru-rate (CTR), Conversion Rate (RA), sales etc will aide your decision regarding keeping the keyword or stop it.

ACoS – Advertisement Cost of Advertisement

This is a percentile metric use to find performance of ad spend over Amazon PPC.

ACoS = Ad Spend ÷ Ad Revenue x 100

Suppose, it cost $25 as spending over ad to get orders worth $100. We will find our ACoS as follows;
ACoS = ( $25 ÷ $100 ) x 100
ACoS = 0.25 x 100
ACoS = 25%

What ACoS is good?

Its relative to your goal, but generally, your profit is your target ACoS. This is how you will identify, if your spendings are more.

Campaign Budget and Bid

I would say, start with minimum. Like if your budget is just $10, start just 1 automatic campaign with $10 budget. However, if you have $30 budget, then start 3 automatic campaign. If you want to start manual campaign with your own keywords, then distribute the initial budget into all of your campaigns, $10 each.

Keyword bid should be little over suggested big, because most of the people will be doing the same. In order to be ahead of competition, you should apply $0.02 to $0.03 more than suggested bid.

Amazon Advertising Interface

Get familiar yourself with Amazon Advertising Interface. Play around.

Whats next?

Once you are equipped with basic knowledge you should move to identify your expectations with Amazon PPC, plan your goals.


Amazon PPC Goals

Amazon PPC Goals
Amazon PPC Goals

Lets be honest, Amazon Pay Per Click is one legitimate and effective way to rank keywords of your newly listed. Yeah, I agree, it takes time, but hey, hustles are fun, no?

The successful PPC Campaign is NOT just about, if you are earning profits as in monetary term. The success is when you are achieving your goals. Don’t get me wrong, the ultimate goal remain profits, but, its relative and we reach there, one step at a time.


Your goals literally define if your PPC is doing good or not.

You can look at your goals from any perspectives, but since its all about Keywords and Search Terms, I would set my goals depending upon my keywords.

  • Discovery
  • Scalability
  • Profitability


To me, the PPC starts with Discovery goal where, we will just focus on identification of our keywords. To aide, I will use both Automatic and Manual Campaigns

Either create just single Automatic campaign with $100 budget or create 10 campaigns with $10 budget each. Multiple automatic campaigns will put Amazon at work, really. After a week or so, you will have winner and looser automatic campaigns. You will be free to keep or remove any number of campaigns.

Since Amazon algorithm in reality is Artificial Intelligence based upon whatever information, we’ve provided to Amazon. Its completely natural to not stuff your content with all keywords or miss the important keywords.

Manual campaign will be filled with hand picked keywords. Thats how you take control of your fate in your hands and rather dictate Amazon to find if our researched keywords are worthy.

Since Automatic Campaigns are suppose to work during whole life of a product, we should never stop them.

Once you see good number of keywords after 7 days, you will move them to another Manual Campaign’s adset as phrase. Its upto you, if you plan to move as broad, but definitely you will not move them as exact at this stage.


It can be either separate Manual Campaign with its own single adset or one adset in a Manual Campaign. Some expert suggest to have keyword niche related campaign or adset.

The goal is to nurture good keywords separately. This is the stage where we will scale up keyword, we will try fine tuning keyword targeting, bid up/down, campaign budget testing, adding keyword to our content etc.

Moved keywords from Discovery Campaigns will be either broad or phrase, depending upon your strategy.

Once we find, the keyword is scaled up and no further optimization can be applied, we will move it to Profitability Campaign.

Same as in Discovery Campaign, we should move the keyword, means, put as negative keyword with Right match type in source campaign or ad set.


It is the Ultimate Goal of whole Amazon PPC drill and bottom line.It can be either another adset in existing Manual Campaign or single adset in its own Campaign.

Similar to Scalability, you have liberty, put proven keywords with lowest possible ACoS in last few weeks.

These can be phrase or exact, but chances are high, most of the keywords will be Exact match type.

Like always, never forget to put same keyword with right match-type as Negative keyword in previous adset or campaign.


Watch closely, keep an eye over keywords and their performance and based upon your goal, add or remove keywords.

Amazon PPC, will ideally go on and on until your item is live and you’ve intentions to keep selling. PPC Discovery, Scalability and Profitability are more like operations than time-specific project.

Best of luck with your PPC hustle.

P.S: Feel free to post your questions in comments. Or you can always contact me over for free advise and tips.

Open Letter to ScrapingHub for Evaluating Trial Project

Who is ScrapingHub and what they do?
ScrapingHub is the company behind Scrapy framework. The location of candidate determines who is going to be full time employee or contract basis, most of employees work remotely. Their job listing page covers all open positions.

Regardless of reservations with ScrapingHub, I do appreciate them for following;

  • Scrapy framework is amazing
  • ScrapingHub Cloud services are really good
  • Providing reason, why you’ve rejected the candidate
  • Prompt communications during whole process

Open Letter to ScrapingHub

I applied to your job ad for the Python Developer position. Within a week of applying online, I received an email that I’ve to submit a trial project. I completed the project at weekend and submitted on next working day. Within a week I received reply from my point of contact that “Trial does not meet the required criteria to progress to the next stage of our hiring process on this occasion.” One of my friend applied at their job ad and he was informed that his code was not PEP8 compliant.

Review from ScrapingHub of my Trial Project submission

When dealing with data that’s structured hierarchically it is best if the call structure follows, because that makes understanding and maintenance easier. Single methods/functions with complex conditionals are difficult to understand and debug. The number of items in the job’s output is below the known total, and field coverage is 100%, which is against requirements; taking more time to review the results would have helped with that.

My reservations

  • When dealing with data that’s structured hierarchically it is best if the call structure follows: Completely agree. However I tried to google atleast one script that will help me here, but was not able to find. I assumed it will be forgiven due to extensive comments 🙂 But I take complete responsibility here
  • Single methods/functions with complex conditionals are difficult to understand and debug.: Agreed, that is why I mentioned this already in the assumptions file and as inline-comments in the spider itself. I did distributed logic in the pipelines classes for most of the data filtering. Did you guys checked it? While I was googling, I find a git hub bug page over Scrapy project where it was recommended to not send response object in Pipeline class I note it down in assumptions file too that is the reason image was filtered in spider class
  • The number of items in the job’s output is below the known total: That could be only known to you guys becuase you’ve the database and you guys have setup the website, it was not mentioned within html anywhere. First thing, in order to know the total-number of records I’ve to first run the spider to collect whole data. Secondly, the sample website had individual items within multiple categories. Third, perhaps you guys forgot, it was a test project that usually completed in 9-10 hours according to you guys and you guys already mentioned if it takes more than 16 hours, the candidate should stop and submit whatever he has. I completed the trial project within 10 hours, running multiple times (each run could take upto 10 minutes) locally and on ScrapingHub Cloud (which has limited number of Free credits)
  • field coverage is 100%, which is against requirements: First of all, what is field coverage? and No, it is not mentioned in the requirements as-is, do you guys want me to put that requirements public?
  • taking more time to review the results would have helped with that.: Alright, then say it, modify your requirements so that it clearly mentions that for a non-paid (you guys already mentioned this) put as many as hours possible to find complete results. For your information, each execution of result takes upto 10 minutes. I ran the spider multiple times with -l ERROR to see if result is complete, I submitted the project only when it has no error

Trial Acceptance Suggestions
If you guys are sincerely looking for a resource, here are my suggestions;

  • Add Best Practices section under’s documentation section
  • Its good that you have requirements to submit assumptions file, do read it as well
  • Do not say that on average it takes 9-10 hours to complete the project, specially to a person who is going to write Scrapy spider code for the first
  • The maximum 16 (or 20) hours limit do not work, clearly mention that you’re expecting a true Scrapy spider comparable to one written by your full time developer who have spent years with you guys. This will help those who are hustler and could write finest piece of code
  • After submission of trial project, if you guys think candidate can improve or willing to, give a choice to either spend more time to improve the code quality of trial project (non paid) or just let it go

General Suggestions

  • If your hiring process has to reject someone based upon their age or geographical location, atleast do not waste their time, do not reply at all like rest or say it loud in email
  • Clearly mention in which Geographical Locations you are hiring for a full time or on-going contract job. Reference ScrapingHub reviews at Glassdoor

Skype Broadcast Message Tool – Replacement of Babel Fish

SkyMass is a message broadcast tool that sends message to your Skype contact list. Since after the Babel Fish stopped working and specially after the launch of Skype ver8, we’ve been strugling to find a tool. When we were not able to find one, we built one for ourself.


  • Pause or Resume broadcast
  • JSON Formatted config file will store your Skype credentials, message and other settings
  • Test before you start your broadcast campaign
  • If your broadcast fails during run, upon restarting it will continue after the contact, last message has been sent to


  • Export your Skype contact list from Skype’s web interface
  • Setup your config.json file
  • Run SkyMass as Administrator


  • Unzip anywhere on your computer
  • Make sure config.json & contacts.csv files, exist within same directory where skymass.exe resides
  • If you want, set “testing”: “true” in config.json file

config.json Explained

	"username": "YOUR_SKYPE_USERNAME",
	"password": "YOUR_SKYPE_PASSWORD",
	"contact_csv_file": "contacts.csv",
	"refresh_report_file": false,
	"testing": true,
	"wait_for_skype_open": 290,
  1. Enter your Skype Username, make sure its enclosed with double quotes (“) without any space
  2. Enter your Skype Password, make sure its enclosed with double quotes (“) without any space
  3. contact_csv_file: Make sure your Exported contact (csv) file name match here
  4. message: Message you want to broadcast
  5. refresh_report_file: If you want to empty existing-contact-message file then set it as true. It will cause sending message again and again, in case of restarting SkyMass software. Its better to set it as false, this way you would not be spaming your contact with same message agian & again
  6. testing: If you want to first test the software, you should set it as true, this way it will run software but will never send message to your contacts
  7. wait_for_skype_open: If Skymass is unable to start Skype, check logs and increase this timer if required
  8. wait_for_login: If your skype hangs after login due to very huge contact list, increase it accordingly


  • This program search for Skype, make sure no other window on the computer is named Skype.
  • This program works with active Skype window, so you should run this program on a machine which can be dedicated for this purpose
  • During run do not try to use the computer, otherwise this software may break and might click controls other than Skype
  • Use this software on your own responsibility, we could never be held for any loss of data or software/hardware failures


version 1.1

  • Delays while opening Skype & after login is now configurable

version 1.0

  • Initial Release

Automate Skype Login using AutoIt

Since Microsoft laucnhed Skype ver8.23.0.10, it was not appreciated by the community, primarily due to its user-interface and do not respect what Skype user want. Some of these people criticize Microsoft when they acquired GitHub, because they suspect Microsoft will do the same with GitHub as what they did to Skype.

Major Changes in Skype 8

  • From AutoIt automation point of view, previously we were logging into Skype using _IEAttach() function while now we login using _UIA_getFirstObjectOfElement found within a user-defined AutoIt Library IUIAutomation MS framework
  • Another significant difference is that now there is no way to export your contacts, nor they are stored in c:\Users\WIN_USERNAME\AppData\Roaming\Skype\SKYPE_USERNAME\main.db any longer. However you can export your contacts only if you login to their web-interface.
  • The third change is that now Skype program contian within Microoft directory instead of Skype’s own directory, like C:\Program Files (x86)\Microsoft\Skype for Desktop\Skype.exe

Pre-requisites to automate Skype Login

Skype Login Automation AutoIt Script

#include "UIAWrappers.au3"
; #INDEX# =======================================================================================================================
; Title .........: Skype Login Automation
; AutoIt Version : 1.0
; Language ......: English
; Description ...: Login to Skype ver
; Author ........: Ahmed Shaikh Memon 
; Requirements...: AutoIt v3.3.12, Developed/Tested on Windows 7 Ultimate SP 1
; ===============================================================================================================================
; #CONSTANTS# ===================================================================================================================
Global Const $cDocument ="controltype:=Document"
; ===============================================================================================================================
; #LOCAL VARIABLES# ============================================================================================================
Local $Username	= "YOUR_SKYPE_USERNAME"
Local $Password	= "YOUR_SKYPE_PASSWORD"
; ===============================================================================================================================
; Start Skype
Local $ProgramFileDir
Switch @OSArch
	Case "X32"
		$ProgramFileDir = "Program Files"
	Case "X64"
		$ProgramFileDir = "Program Files (x86)"
$ProgramFileDir = @HomeDrive & "\" & $ProgramFileDir
Run($ProgramFileDir & "\Microsoft\Skype for Desktop\Skype.exe")
Local $bIsLoggedIn = False
; Is Skype running?
If Not WinExists("[Class:Chrome_WidgetWin_1]") Then
	ConsoleWrite("Unable to find Skype")
; Get Skype window object
Local $oChrome = _UIA_getFirstObjectOfElement($UIA_oDesktop,"class:=Chrome_WidgetWin_1", $treescope_children)
; Click Proceed to login form
Local $oDocument = _UIA_getFirstObjectOfElement($oChrome, "controltype:=" & $UIA_DocumentControlTypeId, $treescope_subtree)
Local $oAnotherUser = _UIA_getObjectByFindAll($oDocument, "name:=Use another", $treescope_subtree)
If IsObj($oAnotherUser) Then
	$bIsLoggedIn = True
	Local $oSignInWithMS = _UIA_getObjectByFindAll($oDocument, "name:=Sign", $treescope_subtree)
	If IsObj($oSignInWithMS) Then
		$bIsLoggedIn = True
If Not $bIsLoggedIn Then
	ConsoleWrite("Unable to login")
; Write Username
Local $oDocument = _UIA_action($cDocument, "object")
Local $oElement = _UIA_getObjectByFindAll($oDocument, "controltype:=UIA_EditControlTypeId", $treescope_subtree)
If Not IsObj($oElement) Then
	ConsoleWrite("Unable to get Username element")
_UIA_action($oElement, "leftclick")
Send($Username & "{ENTER}")
; Write Password
Local $oDocument = _UIA_action($cDocument, "object")
Local $oElement = _UIA_getObjectByFindAll($oDocument, "controltype:=UIA_EditControlTypeId", $treescope_subtree)
If Not IsObj($oElement) Then
	ConsoleWrite("Unable to get Username element")
_UIA_action($oElement, "leftclick")
Send($Password & "{ENTER}")

Checkout all scripts and compile into your AutoIt.

We can use _UIA_DumpThemAll($oChrome, $treescope_subtree) to find the name or element type id associated with particular control over Skype screen. Download examples zip on IUIAutomation MS framework.


  • controltype:=Document in Global Const $cDocument will be used to get access to document object of Skype’s screens change during login process.
  • $ProgramFileDir points to right 32-bit Program Files on this script host computer.
  • _UIA_getFirstObjectOfElement will give access to Skype screen and will try to find it using UI_Automation class name Chrome_WidgetWin_1. We will find this name using Inspect tool
  • $oDocument will be used to find particular elements on Skype app. We can get list of all available elements UI Automation control-type, name, index etc using _UIA_DumpThemAll($oChrome, $treescope_subtree) or _UIA_DumpThemAll($oDocument, $treescope_subtree)
  • _UIA_getObjectByFindAll($oDocument, "name:=Use another", $treescope_subtree) will return element object (if exist) that has text “Use another account”. This will be displayed on Skype login screen if and only if you’ve previously logged in to Skype and logout. Otherwise it will display Sign in
    Skype 8 Automation - Use Another Account
    Skype 8 Automation – Use Another Account
    Skype 8 Automation - Sign in with Microsoft
    Skype 8 Automation – Sign in with Microsoft
  • _UIA_action($oAnotherUser,"leftclick") will trigger leftclick event on Skype screen, this particular line will click “Use another account” link
  • _UIA_getObjectByFindAll($oDocument, "name:=Sign", $treescope_subtree) is added as fail-safe. This piece of code will work when there is no “Use another account” link is visible on Skype login screen.
  • _UIA_getObjectByFindAll($oDocument, "controltype:=UIA_EditControlTypeId", $treescope_subtree) will return Username text-field element.
  • _UIA_action($oElement, "leftclick")
    Send($Username & "{ENTER}")

    In a perfect world, we could have used just single line;

    _UIA_action($oElement,"setvalue using keys", $Username & "{ENTER}")

    But setvalue using keys work in following sequence;

    1. put element into focus
    2. select all text within element
    3. send text to control using Send()

    setvalue using keys is not working as expected on Skype screen. Because as soon as Send() is called, it looses the focus, thus no text is written to the element in question

    While my 3 lines code above, always work, as I am triggering left-click on element instead of focus

    Personally I dont like using Send(), as it require window to be active, which might disturb control being sent to incorrect window, however it seems like the need until we get better solution.

Best practises implemented

  • Well commented code
  • Use of @OSArch & @HomeDrive to build system architecture specific directory
  • Saved two interactions and instead passed [ENTER] keystroke while writing username & password
  • Used generic condition controltype:=UIA_EditControlTypeId for _UIA_getObjectByFindAll to find username & password elements. Deliberately did not used the name or title to find them

Windows Desktop Applications Automation using AutoIt

Write AutoIt Script Like a ProAutoIt is a language & framework to automate (mainly) Windows GUI application interactions. Though it has its own language but there are wrappers available for Python, C# etc too.

This write up target developers who want to automate Windows Desktop Applications but either do not know the right tool or want to enhance their skills using AutoIt.

Just like with any thing, there is either informed or amateur approach towards solving a problem. Developers who have never written Windows GUI applications will write AutoIt code that will depend too much on interactions with active GUI. While we can get maximum out of AutoIt when we rely less over such interactions. This amateur approach creates real issue when we have to interact with multiple desktop applications within same AutoIt script.

One solution to address these issues is to use _WinAPI_PostMessage function, where applicable. We will primarily use this function to interact with menus, otherwise our interactions may occur on wrong window.


Want to automate Notepad;

  • change display font
  • write some text and
  • save file


GUI Inspection:

In order to control GUI elements we will need the Windows Name, Controls ClassNameNN & Automation Ids of Notepad application. If you dont know how to find them using AutoIt Window Info and Inspect tools, watch this video (enable captions, if you want).

AutoIt Script

#include "WinAPI.au3"
#include "WindowsConstants.au3"
; #INDEX# =======================================================================================================================
; Title .........: Windows Desktop Applications Automation using AutoIt
; AutoIt Version :
; Description ...: Automate Notepad for changing display font, writing some text and save file
; Author(s) .....: Ahmed Shaikh Memon (ahmedshaikhm)
; ===============================================================================================================================
; #VARIABLES# ===================================================================================================================
Local $hWnd, $hWndFont, $hWndSaveAs
Global $sFontName = "Arial"
Global $sFileName = "tutorial_1"
; #CONSTANTS# ===================================================================================================================
Global Const $__IDM_FONT = 33
Global Const $__IDM_SAVE = 3
Global Const $__IDC_FONT_NAME = 1001
; Open Notepad
; Get Notepad's handle
$hWnd = WinGetHandle("[Class:Notepad]")
; Display Font Change
; Click Format > Font menu
_WinAPI_PostMessage($hWnd, $WM_COMMAND, $__IDM_FONT, 0)
; Handle Font window
$hFontWin = WinGetHandle("Font")
; Select display font
ControlSend($hFontWin,"", $__IDC_FONT_NAME, $sFontName)
; Save display font
ControlClick($hFontWin, "", "Button5")
; Write text in Notepad
ControlSend($hWnd, "", "Edit1","This is informed approach towards solving a problem")
; Save file
; Click File > Save menu
_WinAPI_PostMessage($hWnd, $WM_COMMAND, $__IDM_SAVE, 0)
; Enter file name in the file open dialog box
$hWndSaveAs = WinGetHandle("Save As")
ControlSend($hWndSaveAs, "", "Edit1", $sFileName)
; Press the Save button on Save As prompt
ControlClick($hWndSaveAs, "", "Button1")

This code is available as gist here


WinAPI.au3 & WindowsConstants.au3 contain definition or constants that will help to communicate particular command to window without visible interaction.

Global variables $hWnd, $hWndFont & $hWndSaveAs will hold handles of Notepad Application, Font window & Save As windows, respectively. While s in $sFontName & $sFileName indicates that they are string. The advantage of following Naming Convention is that it helps create team factor in individuals thus a guess work can be utilized when multiple people are working on same code. Another benefit is that even if you open code after months, you can instantly recognize why particular variable was used.

$__IDM_FONT & $__IDM_SAVE are Menu IDs for sub-menus Font and Save respectively. We’ve identified them using Inspect tool. $__IDC_FONT_NAME is the Control ID for text field for font name.

Run("notepad.exe") is use to open the Notepad application. We can further improve it by using Run("notepad.exe", "", @SW_MAXIMIZE), this will make sure when Notepad is opened up, its window is minimize by default, specially useful when active window will disturb other application or if the computer (where this AutoIt script is being executed) distracts the person using it.

WinGetHandle() is used so that we can send control actions or PostMessage() to just related Window.

_WinAPI_PostMessage() is a wraper to Win 32 API function PostMessage(), this will click sub-menu item without need to have Notepad activated and visible. The function definition is within WinAPI.au3, that is why it is included at the top. WindowsConstants.au3 contain the associated integer for $WM_COMMAND constant

We’ve used ControlSend() function, with particular window handle, so that control command is executed within specific window, otherwise Send() function just send control command, even if (for any reason) your target window is not visible (minimized or something), the control might execute on wrong target if you use Send().

Sleep() functions are used multiple times, because it take few milliseconds to load or close a window, for example Font & Save As windows open after some milliseconds, same while Font window is getting closed. If we dont use them the automation might not work properly.

Known Limitations:

The code is as brief as possible, there is a room to enhance and make it more professional

  • We can open Notepad minimized
  • The Font & Save As windows will be maximized by-default even if Notepad is opened minimized, therefore we can use WinSetState() function to explicitly minimize these windows
  • If the file already exist, we can add few lines of code to test if its asking for overwriting and then peform the desired action
  • We can close Notepad after the automation using WinClose()
  • If your script is going to be deployed on variety of Windows oeprating system versions and different hardware specification machines, then add checks to see if intended control has successfuly executed. For instance, if I’ve to check if Notepad is really opened after Run("Notepad.exe") I would add something like;
    If Not WinExists($hWnd) Then
    	ConsoleWrite("Notepad is not opened" & @CRLF)

Code Execution

Following animated gif shows what happen when you execute this code

Further Reading

For those who are interested in learning more should visit AutoIt’s official wiki & forum or search over StackOverflow, however make sure that you are coming up with intelligent (specific) question

Checkout Automate Skype Login using AutoIt post for a more practical example.


  1. Matt has pointed towards use of PostMessage() Menu IDs
  2. AutoIt Forums got bunch of helpful guys who respond promptly

6 Tips Before You Hire Web Scraping Services

6 Tips Before You Hire Web Scraping Services

Why do I need these advice?

  • There are some facts & limitations to Web-Scraping that you must be aware of
  • An educated & informed job description will put your developer in comfort zone
  • Your developer will not be able to fool you
  • You will know in advance the limitations & ways to pass-thru

Web Automation Tips for buyers:

Following tips will help you identify possibilities & limitations of scraping a website.

  1. Web scrapers use target website’s source code (HTML) as hooks. Therefore even minor change in HTML might stop your scraper. Ask your professional to use less HTML hooks. This way, your web-scraper script or application will work (most of the time)
  2. Make sure professional adheres naming convention, indent code & write necessary comments within code. This practice will help in quickly grasping the internal working of a script to both same or new developer.
  3. Most websites restrict access, if same IP Address is being used to crawl their website. If you use sequential IPs, it might block whole IP-Block. Make use of Socks or HTTP proxies from different IP-blocks. Some websites might need you to use just residential IP addresses. Confirm with your proxy service provider if they residential IP addresses
  4. If your web-scraper takes care of target website resource, chances are your scraper could use same IP Address for longer period of time. Use of delays will play vital role here
  5. Some websites use fingerprinting techniques to identify same person, make sure your developer know how to handle this.
  6. Clock Skew is another technique to identify same visitors, though chances are you will never get to this point of scraping, but if you reach there, you will have to use different computers with different internet service providers to perform your scraping task

My friend Bill Hess of PixelPrivacy has shed more light on the subject, have a look at it and let me know if you like it.