Thursday 31 August 2017

How I managed to bring down my mobile app service hosting cost from $200+ PA to less than $10 PA using Azure

I developed a mobile app for Android & Windows mobile few years ago. At that point of time, I choose to host my App service (.Net web app) & Database (SQL server) in GoDaddy. My initial expectations are less than 100 active users per day. My hosting charges for Deluxe windows hosting for 2 yrs plan is 430 AUD. I felt which is fine and which can handle the traffic very easily. People started downloading & using the app. Database hosted on a shared hosting server. Which is a very painful thing when you have more than 10 active users trying to access the database through API and it always gets locked. Because of this issue, API didn't respond back to the user correctly and it created more damage to the reputation of the app.


 How did I FIX the issue:

So my App's main problem is Sustainability & Scalability.



To make the App sustainable & scalable, I take the decision to move my hosting to the cloud. I choose Azure because both app service & DB developed on Microsoft technologies. With the cloud support, I can easily scale my App service based on user activity. The following is the Azure estimate.


But my App is a very small app and has very less user base and with the above estimate, I'm damn sure I can't bear that much money.

After so much of thinking & planning, I came to a decision to move my resources to Cloud but not as it is. Let me give a cloud touch.

Changed Database SQL server to Azure Table storage:

First question, what is Azure table storage. Azure Table storage is

A NoSQL key-value store for rapid development using massive semi-structured data sets


Reference: https://azure.microsoft.com/en-gb/services/storage/tables/

When compared to SQL server, Azure table to very cheap and because of semi-structured data sets, maintaining a relational database schema structure is not a big deal. Scalability is not at all an issue.
So the decision was taken. Created a well-structured database & moved all my data to Azure Table storage which is No SQL and easy to use with C#.

Moved C# web app to Azure Functions:

Again the first question, what is Azure functions. Azure Functions is very useful to

Build apps faster with a serverless architecture
Accelerate your development with an event-driven, serverless compute experience. Scale on demand and pay only for the resources you consume.

Reference: https://azure.microsoft.com/en-gb/services/functions/

A mobile back-end is a set of HTTP APIs that are called from a mobile client using the WebHook URL. For example, a mobile application can capture an image, and then call an Azure Function to get an access token for uploading to blob storage. A second Azure Function is triggered by the blob upload and resizes the image to be mobile friendly.

The solution is very simple. I need to create separate functions to for each web API calls and write business logic and data access independent of each function. None of these functions are dependent.
Another good thing with Azure functions is you can build your business logic library Dll and upload it to each function. This way the code will be less redundant and more easily manageable.

And the best part with Azure functions is its maintenance cost. The first 400,000 GB/s of execution and 1,000,000 executions are free. Literally, for a small - medium scale app it is absolutely free.

Now the Azure cost estimation is



Next good thing is Application Insights:

Get actionable insights through application performance management and instant analytics


Reference: https://azure.microsoft.com/en-gb/services/application-insights/

   This is also a free product from Azure with some data cap limitation. I have to admit that the Analytics data is much more than what I needed.

Everything is well planned & executed. Now my App's daily active user count is around 100. All is well without any issues.

 KUDOS to Azure.

Sunday 24 July 2016

Complete Facebook bot messenger implementation & Integration in C#

Most of the messenger platforms already welcomed "BOTS" to their platforms. Facebook is one of them. With a whooping 1 billion active monthly users, it is a great platform for developers & businesses to develop "Bot" for FB messenger.

In this article I'm not going to discuss about what are bots and why do we need to implement.

This article will give you the idea on how to implement basic Bot in C#.

Setup C# project:

1) Create am empty WebApi project.




2) Prefer host it in cloud. (All microsoft developers get $25 free credit in Azure. Utilize it and create a free web app). Facebook needs a secure public URL for integration.

3) Once the project is created, create an empty webapi controller and give a proper name to it. This is a very important step. This controller is the only gateway to facebook. We need to configure this in FB webhooks as part of integration(That will come later).

4) We need to create two methods in the controller. One is "Get" and another is "Post". 
  • "Get" method will be called for the first time when we integrate webhook with the FB app. This will check that our secret key is matching the configured key. If matched FB app initiates the connection and sends all the messages to "Post" method of the WebApi controller.
public async Task<HttpResponseMessage> Get()  
     {  
       var verify_token = "Your_Verification_Token";  
       var hub_verify_token = string.Empty;  
       var challenge = string.Empty;  
       if (!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["hub.challenge"]))  
       {  
         challenge = HttpContext.Current.Request.QueryString["hub.challenge"];  
         hub_verify_token = HttpContext.Current.Request.QueryString["hub.verify_token"];  
       }  
       if (verify_token == hub_verify_token)  
       {  
         return new HttpResponseMessage()  
         {  
           Content = new StringContent(  
             challenge,  
             Encoding.UTF8,  
             "text/html"  
           )  
         };  
       }  
       return new HttpResponseMessage()  
       {  
         Content = new StringContent(  
             challenge,  
             Encoding.UTF8,  
             "text/html"  
           )  
       };  
     }  
  • "Post" method is the operation part. Each message from facebook will have "sender", "recipient" and "message" nodes. In the "Post" method we have to catch all the messages and send the appropriate message back to the sender. Sample Json message from FB is like below.



Setup Facebook app:

1) Create a Facebook App and Page

Create a new Facebook App and Page or use existing ones. Go to the App Dashboard and under Product Settings click "Add Product" and select "Messenger."




2) Setup Webhook

In the Webhooks section, click "Setup Webhooks."



Enter a URL for a webhook(This is the URL for the project we hosted in the cloud. Eg: "https://mydemo.azurewebsites.net/api/webhook"), enter a Verify Token (We need to use the same token what we have used in the project WebApi "Get" method.) and select message_deliveries, messages, messaging_optins, and messaging_postbacks under Subscription Fields.



3) Get a Page Access Token

In the Token Generation section, select your Page. A Page Access Token will be generated for you. Copy this Page Access Token. Note: The generated token will NOT be saved in this UI. Each time you select that Page a new token will be generated. However, any previous tokens created will continue to function.

This token will be used in code to send back messages to FB app.


4) Subscribe the App to the Page

 In the Webhooks section, you can subscribe the webhook for a specific page.



Send & Receive messages:

Now the project is setup and  Facebook app & page are also setup. Now the main implementation of the app. When some one sends a message to the page, the message will be delivered to "Post" method in the WebApi.

We need to create two model classes for request and response.

FbRequest class:

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Web;  
 namespace FbBot.Models  
 {  
   public class FbRequest  
   {  
     public IEnumerable<Entry> entry { get; set; }  
   }  
   public class Entry  
   {  
     public long id { get; set; }  
     public long time { get; set; }  
     public IEnumerable<Messaging> messaging { get; set; }  
   }  
   public class Messaging  
   {  
     public Person sender { get; set; }  
     public Person recipient { get; set; }  
     public long timestamp { get; set; }  
     public Message message { get; set; }  
     public postback postback { get; set; }  
   }  
   public class Person  
   {  
     public string id { get; set; }  
   }  
   public class Message  
   {  
     public string mid { get; set; }  
     public string seq { get; set; }  
     public string text { get; set; }  
   }  
   public class postback  
   {  
     public string payload { get; set; }  
   }  
 }  


FbResponse class:

using Newtonsoft.Json;  
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Web;  
 namespace FbBot.Models  
 {  
   [Serializable]  
   public class FbResponse  
   {  
     public Person recipient { get; set; }  
     public ResponseMessage message { get; set; }  
   }  
   [Serializable]  
   public class ResponseMessage  
   {  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public string text { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public Attachment attachment { get; set; }  
   }  
   public class Attachment  
   {  
     public string type { get; set; }  
     public Payload payload { get; set; }  
   }  
   public class Payload  
   {  
     public string template_type { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public string text { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public IEnumerable<Button> buttons { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public IEnumerable<Element> elements { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public Address address { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public Summary summary { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public IEnumerable<Adjustment> adjustments { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public string recipient_name { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public string order_number { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public string currency { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public string payment_method { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public string order_url { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public string timestamp { get; set; }  
   }  
   public class Button  
   {  
     public string type { get; set; }  
     public string url { get; set; }  
     public string title { get; set; }  
     public string payload { get; set; }  
   }  
   public class Element  
   {  
     public string title { get; set; }  
     public string image_url { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public string item_url { get; set; }  
     public string subtitle { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public IEnumerable<Button> buttons { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public string price { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public string currency { get; set; }  
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]  
     public string quantity { get; set; }  
   }  
   public class Address  
   {  
     public string street_1 { get; set; }  
     public string street_2 { get; set; }  
     public string city { get; set; }  
     public string postal_code { get; set; }  
     public string state { get; set; }  
     public string country { get; set; }  
   }  
   public class Summary  
   {  
     public string subtotal { get; set; }  
     public string shipping_cost { get; set; }  
     public string total_tax { get; set; }  
     public string total_cost { get; set; }  
   }  
   public class Adjustment  
   {  
     public string name { get; set; }  
     public string amount { get; set; }  
   }  
 }  


These classes are very handy. These will be useful for strict binding.

Now the "Post" method:

[HttpPost]  
     // POST api/<controller>  
     public async Task<IHttpActionResult> Post([FromBody] FbRequest request)  
     {  
         
       FbResponse fbResponse = null;  
       foreach (var item in request.entry.LastOrDefault().messaging)  
       {  
         var messageEvent = item;  
         var sender = item.sender.id;  
         var messageText = item.message?.text ?? string.Empty;  
         if (!string.IsNullOrEmpty(messageText))  
         {  
           try  
           {  
             fbResponse = new FbResponse() { recipient = new Person { id = sender }, message = new ResponseMessage { text = "You sent " + messageText } };  
             if (fbResponse != null)  
             {  
               PostBackRequest(fbResponse);  
             }  
           }  
           catch (Exception ex)  
           {  
             logger.TrackException(ex);  
           }  
         }  
       }  
       return StatusCode(HttpStatusCode.OK);  
     }  

The above method just sends back the message what user sent. We will get the FbRequest as input to the Post method.

The following method, will send response back to the user.

private HttpStatusCode PostBackRequest(FbResponse fbResponse)  
     {  
       var accessToken = "Page_Access_Token_Generated";  
       var baseAddress = new Uri("https://graph.facebook.com/v2.6/me/messages?access_token=" + accessToken);  
       using (var httpClient = new HttpClient())  
       {  
         var input = JsonConvert.SerializeObject(fbResponse);  
         try  
         {  
           var response = httpClient.PostAsync(baseAddress, new StringContent(input.ToString(), Encoding.UTF8, "application/json"));  
           return response.Result.StatusCode;  
         }  
         catch (WebException e)  
         {  
           var httpResponse = (HttpWebResponse)e.Response;  
           if (httpResponse.StatusCode == HttpStatusCode.BadRequest)  
           {  
             logger.TrackException(e);  
           }  
         }  
       }  
       return HttpStatusCode.OK;  
     }  


The above code is a simple example that echo backs what user sent.

The FbResponse class is capable of sending Text, Image, Button, Generic, File & Receipt attachments.

All you need is create the proper response object as per the facebook reference guidelines.

Reference: https://developers.facebook.com/docs/messenger-platform/send-api-reference

I wish this will be very useful for beginners who would like to step into the bot programming.

Happy coding :)






Tuesday 10 May 2016

Delete Git remote branches using the powershell


Delete Git remote branches using the PowerShell:

Over the period of time GIT branches grow and it is unnecessary to maintain all the history of branches. But to delete all the remote merged branches there is no straight away method.

Here is the powershell script which is very handy and easily understandable to do all the stuff.



#Step 1: Navigate to git folder. This script should has to run the git repo folder
#Step 2: Before running the script make sure you comment the git push origin --delete command. Once all the branch names verified then uncomment and run again.

function gitBranchName {
    $currentBranch = ''
    git branch -r | foreach {
        
        if ($_ -like "*/Fix/*") {
            $currentBranch = $_
            $currentBranch = $currentBranch -replace "origin/", ""
            $currentBranch = $currentBranch -replace " ", ""
            Write-Output($currentBranch)
            git push origin --delete --force $currentBranch
        }
    }
}

gitBranchName


By running the above script in powershell it will delete all the remote branches containes branch name 'Fix'.

Happy coding :)

Sunday 13 December 2015

Handle back button using Javascript

Some times developers need to handle/disable the back button functionality. In situations like after payment screen or after logout, users going back using back button is a weird thing for any developer.

To handle this situation, add the following JavaScript code in your navigated page.

<script type = "text/javascript" >
        history.pushState(null, null, 'page_name');
        window.addEventListener('popstate', function(event) {
            history.pushState(null, null, 'page_name');
        });
</script>

Replace the "page_name" with your navigated page name.

Ex: If you are navigating from first.html to second.html. Add the above snippet in second.html page and replace "page_name" with "second.html".

That's it. 

Enjoy coding.

Sunday 29 November 2015

How to stop double click on form submission


It's a common and weird problem for many web application developers. How to stop double click and let users know the process is started.

Add the following properties to the asp button control. That's it.

OnClientClick="this.disabled = true; this.value = 'Submitting...';__doPostBack('btnConfirm','')" 

UseSubmitBehavior="false"

Happy coding!!!

Thursday 23 July 2015

JQuery and UpdatePanel issue in ASP.Net

This is a regular issue for all developers who are using UpdatePanel in their code. If you are the one using JQuery functionality inside an update panel then first time the client side script works. But If any async postback happened, then after that JQuery will not work. This is because UpdatePanel do partial postbacks, so it will not reload the JQuery script to execute. So when you try to execute the script after postback it will give you 'undefined' error.

To solve this you need to call the same functionality in the endRequest.

How to do it.

     var initialise = function () {
           $(function () {
               doSomething();
           });

           if (typeof (Sys) !== 'undefined') {
               Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args)             {
                   if (args.get_error() == undefined) {
                       var responseText = args.get_response().get_responseData();
                       doSomething();
                   }
               });
           }

           return _this;
       };

I am calling my doSomething method in the initialise and in Sys.WebForms.PageRequestManager.getInstance().add_endRequest as well. So for partial postbacks the script will load again.

Hope this helps...... Happy coding :)

Wednesday 13 May 2015

WCF service binding changes for HTTPS - 404 error


If you are the one who is using WCF services referring from same project evrything works fine until the security feature applied. With HTTPS domain probably all of your service requests fail with 404 error.

If that is the case then create a new binding like below

<binding name="webBinding">
       <security mode="Transport">
       </security>

     </binding>

And add the bindingConfiguration to your service end point.

bindingConfiguration="webBinding"

This will solve the issue.

Happy deployment :)