Coding for fun: JavaScript based simple doodle

Here is a pure JavaScript based, basic drawing tool. It supports both mouse and tap.

Demo URL: https://ninethsense.github.io/code-share/Doodle/

image

001 <html>
002     <head>
003         <meta http-equiv="content-type" content="text/html; charset=utf-8">
004         <style>
005             body {
006                 margin0 0;   
007                 overflow:hidden;
008                 cursor:url(pencil1.cur), auto;
009                 touch-actionnone;
010             }
011             #d {
012                 displayflex;
013             }
014             #sb {
015                 background-color#ddd;
016                 box-shadow2px 2px 5px;
017                 padding2 2;
018                 position:absolute;
019                 top:0;
020                 left:0;
021             }
022             #sb input {
023                 min-width:100px;
024                 min-height:70px;
025             }
026             #sb input {
027                 font-familyArialHelveticasans-serif;
028                 font-size13pt;
029                 font-weight:bold;
030                 cursorpointer;
031             }
032         </style>
033     </head>
034     <body>
035     <div id="sb">
036         <input type="button" value="C L E A R" id="clear" />
037     </div>
038     <canvas id="d"></div>
039
040     <script>
041         var document.getElementById("d");
042         d.width window.innerWidth;
043         d.height window.innerHeight;
044         var ctx d.getContext("2d");
045         ctx.lineWidth 3;
046         px=0py=0;clk=false;
047
048   
049         
050         startdraw = function(e) {
051             px e.clientX d.offsetLeft;
052             py e.clientY d.offsetTop;
053             clk true
054         }
055
056         draw = function(e) {
057             
058             if (clk) {
059                 e.touches?e.touches[0]:e;
060                 ctx.beginPath();
061                 ctx.moveTo(px,py);
062                 px e.clientX d.offsetLeft;
063                 py e.clientY d.offsetTop;
064                 ctx.lineTo(px,py);
065                 ctx.strokeStyle '#ff0000';
066                 ctx.stroke();
067                 ctx.closePath();
068             }
069         }
070
071         document.getElementById("clear").addEventListener("click", function() {
072             if (confirm("Clear the whiteboard?")) {
073                 ctx.clearRect(0,0,d.width,d.height);
074             }
075         });
076        
077         d.addEventListener("touchstart"startdraw);
078         d.addEventListener("mousemove"drawfalse);
079         d.addEventListener("mousedown"startdrawfalse);
080         d.addEventListener("touchmove"drawfalse);
081         d.addEventListener("mouseup", function() { clk false });
082         d.addEventListener("touchend", function() { clk false });
083
084     </script>
085     </body>
086 </html>

View in GitHub | Made with wp-showgithubfile plugin

Bash script to backup using lftp

Can use below script to gzip a folder, and upload to a FTP site. We can use a cron task to schedule it.


#!/bin/bash
Fn=myvps-backup-$(date +%Y%m%d).tar.gz
tar cf - websites | gzip -9 - > $Fn lftp -u user@name,password myhostname.com << EOF
set ssl:check-hostname no
set ssl:verify-certificate false
cd /public_ftp
put $Fn
bye
EOF

A basic JavaScript drawing interpreter

Coding for fun… An attempt to make a fully JavaScript based canvas drawing interpreter in മലയാളം/Malayalam.

Try in action here – https://ninethsense.github.io/code-share/CanvasDrawing/

Source Code:

001 <html>
002     <head>
003         <meta http-equiv="content-type" content="text/html; charset=utf-8">
004         <style>
005             #c {
006               displayflex;
007                 width:100%;
008                 height:100%;
009             }
010             #t {
011               width:100%;
012             }
013             .col {
014               flex:1;min-height:80%;
015               background-color#eee;
016               margin:1px 1px;
017             }
018             #e {
019               font-familymonospace;
020               font-weightbold;
021               font-size:12pt;
022               caret-colorred;
023             }
024         </style>
025     </head>
026     <body>
027       <div style="display:flex;min-height:80%;border:solid 1px black;">
028         <div id="e" class="col" contenteditable>
029           മായ്‌ക്കുക<br>
030           രേഖ (ഇടത്=100മുകൾ=100വീതി=200ഉയരം =200)<br>
031           വൃത്തം (ഇടത്=200മുകൾ=200ആരം=50നിറം ="പച്ച" )<br>
032           ചതുരം (ഇടത്=50മുകൾ=50വീതി=300ഉയരം=200)<br>
033           ചതുരം (ഇടത്=50മുകൾ=50വീതി=300ഉയരം=200നിറം "ചുവപ്പ്")<br>
034           രേഖ (ഇടത്=100മുകൾ=100വീതി=200ഉയരം =300,  നിറം ="#0000ff")
035         </div>
036         <div class="col">
037           <canvas id="c"></canvas>
038             <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
039           </svg>
040         </div>
041       </div>
042       
043       <input type="button" value="Draw" id="ok" />
044       
045
046     <script>
047       var document.getElementById("c");
048       c.width c.offsetWidth;
049       c.height c.offsetHeight;
050       var cx c.getContext("2d");
051       
052       document.getElementById("ok").addEventListener("click", function(){
053         
054         var pgm document.getElementById("e").innerText;
055         var lines pgm.split("\n");
056         
057         lines.forEach(function(stmti) {
058           if (!stmt.trim()) return;
059           
060           var cmd stmt.split(/{|\(| /)[0];
061           
062           var params stmt.replace(cmd"" ).replace(/=/g,":").replace(/\(/g,"{").replace(/\)/g,"}");
063           
064
065           params params.replace(/ഇടത്|മുകൾ|ആരം|വീതി|ഉയരം|നിറം/gi, function(matched){
066                   return {
067                     "ഇടത്":"\"left\""
068                     "മുകൾ":"\"top\""
069                     "ആരം":"\"radius\"",
070                     "വീതി":"\"width\"",
071                     "ഉയരം":"\"height\"",
072                     "നിറം":"\"color\""
073                   }[matched];
074                 });
075           var col = {"പച്ച":"#00ff00""ചുവപ്പ്":"#ff0000""നീല":"#0000ff"};
076                 
077           var = {};
078           try {
079             JSON.parseparams );
080             
081           } catch {
082             if (cmd != "മായ്‌ക്കുക") {
083               Err();
084               return;
085             }
086           }
087
088           if ('color' in j) {
089             if (j.color in col) {
090               cx.strokeStyle col[j.color];
091             } else {
092               cx.strokeStyle j.color;
093             }
094           } else {
095             cx.strokeStyle "#000";
096           }
097           
098           cx.beginPath();
099           switch(cmd) {
100             case "മായ്‌ക്കുക":
101               cx.clearRect(0,0,c.offsetWidth,c.offsetHeight);
102               break;
103             case "വൃത്തം":
104               if ( !Number.isInteger(j.left) || !Number.isInteger(j.top) || !Number.isInteger(j.radius)) {
105                 Err();
106               }
107                 cx.arc(j.leftj.top,j.radius,0Math.PIfalse);
108               break;
109             case "രേഖ":
110               cx.moveTo(j.leftj.top);
111               cx.lineTo(j.widthj.height);
112               break;
113             case "ചതുരം":
114               cx.rect(j.leftj.topj.widthj.height);
115               break;
116             default:
117               Err();
118               break;
119           }
120           function Err() {
121             alert(`Syntax Error in "${cmd}" at line ${i+1}`);
122           }
123
124           if (cmd != "മായ്‌ക്കുക"cx.stroke();
125           cx.closePath();
126         });
127       });
128       
129     </script>
130     </body>
131 </html>

View in GitHub | Made with wp-showgithubfile plugin

Web based single-page, light weight HTML editor with auto-save, using HTML, JavaScript and PHP

image

Source Code:

001 <?php
002     /**
003      *  A lightweight, single page HTML editor with live preview and auto-save
004      *  Author: Praveen Nair @ http://blog.ninethsense.com/
005      *  
006      */
007
008     $f $fn "";
009     if (count($_GET) == 1)  {
010         $f key($_GET);
011         $fn "$f.html";
012     } else {
013         die();
014     }
015
016      if ( isset($_POST["c"]) )  {
017         $content $_POST["c"];
018         echo  (file_put_contents($fn$content))?"1":"-1";
019         die();
020     }
021    
022 ?>
023 <html>

024     <head>
025         <meta http-equiv="content-type" content="text/html; charset=utf-8">
026         <style>
027             #tb {
028                 margin-left: 5;
029             }
030             #editor, #preview {
031                 flex: 1 0 0;
032                 background:#eee;
033                 margin: 5 5;
034                 padding: 5 5;
035                 overflow:auto;
036             }
037             #editor {
038                 font-family: monospace;
039             }
040             #preview, a {
041                 font-family: Arial, Helvetica, sans-serif;
042             }
043             [placeholder]:empty::before {
044                 content: attr(placeholder);
045                 color: #ccc; 
046             }
047             #saved {
048                 font-size:8pt;
049                 margin-left:5px;   
050             }
051         </style>
052     </head>
053     <body>
054         <div id="tb">
055             <input type="button" value="Save" onclick="Save()" /><span id="saved"></span>
056             <a href="preview.php?<?=$f?>" target="_blank" style="float:right;font-size:8pt">[Preview]</a>
057         </div>
058         <div style="display: flex;height:90%">
059             
060             <div id="editor" contenteditable="true" onkeyup="LivePreview()" placeholder="Your HTML Code"></div>
061
062             <div id="preview" placeholder="Preview Area"></div>
063         </div>
064
065         <script>
066             var editor = document.getElementById("editor");
067             var preview = document.getElementById("preview");
068             var IsSaved = true;
069             editor.focus();
070             function LivePreview() {
071                 preview.innerHTML = editor.innerText;
072                 IsSaved = false;
073             }
074             function Save() {
075                 var xhttp = new XMLHttpRequest();
076                 xhttp.onreadystatechange = function() {
077                     if (this.readyState == 4 && this.status == 200) {
078                         if (xhttp.responseText == "1") {
079                             document.getElementById("saved").style.color = 'green';
080                             document.getElementById("saved").innerText = "Last saved at " + new Date() ;
081                             IsSaved = true;
082                         } else {
083                             ShowError();
084                         }
085                     } 
086                 };
087                 var formData = new FormData();
088                 formData.append("c", editor.innerText);
089                 xhttp.open("POST", "<?= $_SERVER["PHP_SELF"]. "?$f?>", true);
090                 xhttp.send(formData);
091
092             }
093             setInterval(() => {
094                 if (!IsSaved) {
095                     Save();
096                 }
097             }, 5000);
098
099             ShowError = function() {
100                 var ele = document.getElementById("saved");
101                 ele.style.color = 'red';
102                 ele.innerText = "Couldn't Auto-save. Will retry soon" ;
103             }
104             window.onload = function() {
105                 <?php
106                     $content "";                
107                     if ( $_SERVER['REQUEST_METHOD'] != 'POST' ) {
108                         if (file_exists($fn)) {
109                             $content file_get_contents($fn);
110                         } 
111                         echo "editor.innerText = `$content`;";
112                     }
113                 ?>
114                 LivePreview();

115             }
116             
117         </script>
118     </body>
119 </html>
120

View in GitHub | Made with wp-showgithubfile plugin

My wp-ShowGithubFile plugin is accepted by WordPress today!

Though I wrote the plugin initially for personal use, now the same is available for you to use in your WordPress sites.

Link: https://wordpress.org/plugins/wp-showgithubfile/

You can either download it from the directory, or install directly within your WordPress installation. Here is a live demo of the plugin:

001 package com.company;
002
003 import java.util.Arrays;
004
005 public class Main {
006
007     public static void main(String[] args) {
008
009         // New Customer wants to buy a bottle
010         Customer customer = new Customer();
011
012         // Customer Registration
013         customer.RegisterMe("+919999999999"PhoneType.APP ); // App or SMS?
014
015         // Assuming Registration successful
016
017         // Customer requests the token using a mobile app, or by sending SMS
018         String CustomerToken =  customer.giveMeAToken("695000"); // Pin code
019
020         if (CustomerToken != null) {
021             //  Assuming Customer gets the token and he goes to the Outlet
022         } else {
023             // Seems there are no slots available. Try again later.
024             return;
025         }
026
027
028         // At the Outlet, sales guy is scanning the token
029         Boolean OutletVerification = new Outlet().isTheTokenShownByCustomerValid(CustomerToken);
030
031         if (OutletVerification) {
032             // Assuming the validation is success
033             System.out.println("Customer says: Wow, I got the bottle!");
034         } else {
035             System.out.println("Sales guy says: Get lost!");
036         }
037     }
038
039     public enum PhoneType APPSMS };
040
041     private static class VQServer {
042         // Database
043         public String[] tokenDB = { "A""B","C","D","E" };
044         public String[] Outlets = {"Outlet1""Outlet2""Outlet3"};
045
046         public void registerCustomer(String phoneNumberPhoneType phonetype) {
047             // Register customer
048
049         }
050         public String requestNewTokenByCustomer(String pinCode) {
051             // Logic for - Token generation logic
052             // Logic for - Find nearest outlet using pinCode
053
054             // Send token by SMS if PhoneType is SMS
055
056             return "C"// Sample token
057         }
058
059         public Boolean validateTokenByOutlet(String token) {
060             return Arrays.asList(tokenDB).contains(token); // Validate
061         }
062     };
063
064     static VQServer vqServer = new VQServer();
065
066     private static class Customer {
067
068         public String giveMeAToken(String pinCode) {
069             return vqServer.requestNewTokenByCustomer(pinCode);
070         }
071         public void RegisterMe(String phoneNumberPhoneType phonetype) {
072             // Customer Registration
073             vqServer.registerCustomer(phoneNumberphonetype);
074         }
075     }
076     private static class Outlet {
077         public Boolean isTheTokenShownByCustomerValid(String token) {
078             return vqServer.validateTokenByOutlet(token);
079         }
080     }
081 }

View in GitHub | Made with wp-showgithubfile plugin

My Groovy HelloScript contribution to community

Here goes my contribution to HelloScript project by Praseed Pai.

GitHub: https://github.com/praseedpai/HelloScript_files/blob/master/Groovy/HelloScript.groovy

Source Code:

001 /**
002  * HelloScript.groovy
003  */
004
005 //  A Simple Console Output
006
007     println "Hello World"
008
009 //  Some more
010     print ("Hello World")
011     System.out.println("K-Mug"); // Java style also works
012
013 // Declare variables
014     def a 100 // a number, def is about scope
015     100// another number
016     year "Twenty Twenty" // a string
017
018 // String formatting & interpolation
019     println "This is ${a}${b}, and " year;
020
021 // Reassign a variable
022     year 2008// dynamic typing
023
024 // if-else
025     if (year 2008)
026         println "Welcome to the future - yes, we have flying cars!"
027     else if (year 2008)
028         printLN "The past - please don't change anything. Don't step on any butterflies. And for the sake of all thats good and holy, stay away from your parents!"
029     else
030         println "Anything wrong with your time machine? You have not gone anywhere, kiddo."
031
032
033 // Range based for loop
034 for (i in 0..3) {
035     println "$i Hi there!"
036 }
037
038 // Copying range value to a variable
039     range_array = (0..10)
040     print range_array;
041
042 // Array demo
043     rules = ['Do no harm','Obey','Continue Living']
044     println rules;
045
046     rules << "Be Honest" // add one more item
047     println rules
048
049 // Array demo, with mixed types
050     more_rules = ['Do no harm','Obey','Continue Living'404403500100f]
051     println more_rules;
052
053 // Loop through Array
054     0
055     while (rules.size()) {
056         print "Rule " + (1) + " : " rules[i]
057         += 1
058     }
059
060     println() // just a newline
061
062 // Associating array
063     associated = [
064         'hello'    :    'world',
065         'foo'    :    'bar',
066         'lorem'    :    'ipsum'
067     ]
068
069     for (ele in associated) {
070         print ele.key " : " ele.value
071     }
072
073     println() // just a newline
074
075 // Example of a Nested Loop
076 // To calculate Pythagorean Triplets
077     10
078     println "-------------------------------------"
079     for (va in (1..n)) {
080         for (vb in (va..n)) {
081             Integer c_square va**vb**2
082             Integer vc Math.sqrt(c_square)
083             if ((c_square vc**2) == 0) {
084                 println va " " vb " " vc
085             }
086         }
087     }
088     println "----------------------------------"
089
090 // Iterating over a list using range and size
091     println "-------------------------------------"
092     fibonacci = [0,1,1,2,3,5,8,13,21]
093     for (i in (0..fibonacci.size()-1)) {
094         println i " " fibonacci[i]
095     }
096     println "---------------------------------------"
097
098 // Parsing a line - split and join
099     csv_values "hello,world,how,are,you".split(",")
100     println csv_values;
101     println csv_values.join(":")
102
103 // A Single Argument Function
104     def hello(name) {
105         return "Hello ${name}!"
106     }
107     println hello("Praveen")
108
109 // A simple class
110     class Movie {
111         String name ""
112         Integer rating 0
113
114         def Movie(movieName) {
115             this.name movieName
116             this.rateMovie()
117         }
118
119         def rateMovie() {
120             this.rating = (this.name.length() % 10) + 1     // IMDBs rating algorithm. True story!
121         }
122         def printMovieDetails() {
123             println "Movie : " +   this.name
124             println "Rating : " '*'.multiply(this.rating)  +  "(" this.rating +")"
125         }
126     }
127
128 // Create the Object
129     ncfom = new Movie("New Country for Old Men");     // It's a sequel!
130     ncfom.printMovieDetails()
131
132 // Closures in action
133     myList = ["Hello","My","World","What's","Up"]
134     myList.each {
135         print it "-" // it is special
136     }
137
138 // Multiplication table
139     (1..10).each {
140         println "${it} x 2 = ${it*2}"
141     }
142
143     println() // just a newline
144
145 // Tuples
146     myTuple = new Tuple(1'two'3'four')
147     println myTuple
148
149 // File IO - Create a new file
150     myFile = new File("myfile.txt");
151     myFile.text "Hello World! - from the file"
152     myFile.createNewFile()
153
154 // File IO - Read from file
155     println myFile.text
156
157 // File IO - With closure
158     myFile.eachLine {
159         -> println l.toUpperCase()
160     }
161
162 // Regular Expressions
163     import java.util.regex.Pattern
164     Pattern pattern = ~/World/
165     str "Hello World, this is Universe, not your World!"
166     println "Found " pattern.matcher(str).size() + " mathes."

View in GitHub | Made with wp-showgithubfile plugin [Code generated by wp-ShowGithubFile plugin]

WordPress plugin – Show your source code directly from GitHub in your blog/website

Show a file, preferably source code file content in a WordPress blog post or page.  This plugin shows always the latest code from GitHub.

Visit my GitHub repository to download the plugin for free – https://github.com/ninethsense/wp-ShowGithubFile

screenshot

Source Code: (Live Example directly from GitHub 🙂

001 <?php
002 /**
003  * Plugin Name: wp-ShowGithubFile
004  * Description:       Show a file, preferably source code file content in a WordPress blog post or page
005  * Version:           1.0.0
006  * Author:            NinethSense
007  * Author URI:        https://blog.ninethsense.com/
008  * License:           GPL v2 or later
009  */
010
011
012     add_shortcode"GitHub""ShowGitHub" );
013     function ShowGitHub($atts) {
014         if (!isset($atts["file"]) && !strpos(strtolower($atts["file"]), "https://raw.githubusercontent.com/" )) {
015             // Also, I want only files from GitHub. Modify this to show file from any URL
016             return "[Invalid GitHub Raw file]";
017         }
018         
019         $fh = @get_headers($atts["file"]);
020         
021         if (strpos($fh[0],"200") == 0) {
022             return "[Invalid file]";
023         }
024         
025         $fcontents file_get_contents(trim($atts["file"]));
026         $notphp false;
027         
028         if (strpos($fcontents"?php") == false) {
029             $fcontents "<?php ".$fcontents;
030             $notphp true;
031         }
032         
033         // Make use of PHP syntax highlighing. Something is better than nothing.
034         $fcontents highlight_string($fcontentsTRUE);
035         
036         if ($notphp) {
037             $fcontents str_replace("&lt;?php&nbsp;""",$fcontents);
038             $notphp false;
039         }
040
041         $fcontents str_replace(["<code>""</code>"], "",$fcontents);
042         
043         $fcontents explode("<br />",$fcontents);
044         
045         $style = (isset($atts["style"])) ?$atts["style"]:"";
046         $ret "<div style='font-family:monospace;background-color:#dcd7ca;width:100%;overflow:auto;white-space:nowrap;border:solid 1px #aaa;font-size:10pt;$style'>";
047         for ($i=0;$i<sizeof($fcontents);$i++) {
048             $line $fcontents[$i];
049             $ret .= "<span style='font-size:10pt;display:block;width:40px;background-color:#aaa;float:left'>" 
050                 str_pad($i+13,'0',STR_PAD_LEFT) ." </span><span style='margin-left:10px;width:100%;inline-block'>" $line "</span><br />";
051         }
052         $ret .= "</div>";
053        
054         file_put_contents("D:\\test.txt"$ret);
055         return $ret;
056
057         
058     }
059 ?>

View in GitHub | Made with wp-showgithubfile plugin

PHP PortPing script – check host connectivity

Here is a script in PHP I wrote to check if a remote host and port are open for you to connect. Do not mistake this as an equivalent to ping command because ping uses ICMP and I used TCP using PHP’s famous fsockopen() function, and a small piece of AJAX.

PortPing

You can get the latest source code from my GitHub code share page – https://github.com/ninethsense/code-share/

PHP:

function ping($host, $port) {
         $startTime = time();
         if ($fs = fsockopen($host, $port, $errCode, $errStr, 1)) {
             $timeTaken = (time()-$startTime)/1000;
         echo "Reply from $host:$port time={$timeTaken}ms";
             fclose($fs);
         } else {   
             echo "Request timed out.";
         }
         echo "<br>";
     }

JavaScript:

var count = 0;
             var intervalID = setInterval(function PortPing() {
                 var xhttp = new XMLHttpRequest();
                 xhttp.onreadystatechange = function() {
                     if (this.readyState == 4 && this.status == 200) {
                         document.getElementById("console").innerHTML += this.responseText;
                     }
                 };
                 xhttp.open("GET", "PortPing.php?source=self&host=<?=$host?>&port=<?=$port?>", true);
                 xhttp.send();
                 if (++count > <?=$t-1?>) {
                     clearInterval(intervalID);
                 }
             },2);

A simple Folder Watcher for windows

Here is a simple file system watcher for windows. I wrote a script to monitor a folder for a specific purpose, but then thought to make this a generic tool so someone will benefit if I host in GitHub.

FolderWatcher

 

Find full project at https://github.com/ninethsense/FolderWatcher

 

Source Code:

private void Form1_Load(object sender, EventArgs e)
{
    toolStripLabel.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

    StartMonitoring();
}

private void StartMonitoring()
{
    watcher = new FileSystemWatcher(toolStripLabel.Text)
    {
        IncludeSubdirectories = true,
        EnableRaisingEvents = true
    };
    watcher.Created += Watcher_Handler;
    watcher.Deleted += Watcher_Handler;
    watcher.Renamed += Watcher_Handler;
    watcher.Changed += Watcher_Handler;
}

private void Watcher_Handler(object sender, FileSystemEventArgs e)
{
    Invoke(new Action(() =>
    {
        listBoxLog.Items.Add($"[{DateTime.Now}][{e.ChangeType}] {e.FullPath}");
    }));
}

private void ToolStripClearButton_Click(object sender, EventArgs e)
{
    listBoxLog.Items.Clear();
}

private void ToolStripChooseFolderButton_Click(object sender, EventArgs e)
{
    watcher.EnableRaisingEvents = false;
    folderBrowserDialog.SelectedPath = toolStripLabel.Text;
    var dlg = folderBrowserDialog.ShowDialog();

    if (dlg == DialogResult.OK)
    {
        string OldPath = toolStripLabel.Text;

        try
        {
            watcher.Path = folderBrowserDialog.SelectedPath;
            watcher.EnableRaisingEvents = true;
        } catch (FileNotFoundException ex)
        {
            toolStripLabel.Text = OldPath;
            watcher.Path = OldPath;

            MessageBox.Show($"Seems you don't have permission to access folder        {folderBrowserDialog.SelectedPath}. Try starting this app as Administrator\n\nDetails:\n{ex.Message}", "Error", MessageBoxButtons.OK);
            watcher.EnableRaisingEvents = true;
        }
            toolStripLabel.Text = watcher.Path;

    }

}

Create AWS Lambda function with .NET Core / C# and create a HTTP API Gateway trigger | Part #2

In this Part #2 of blog I will be creating a new .NET Core function in local machine and will upload to AWS using console interface. There are different ways you can develop and deploy but I will be talking in this blog only about the CLI way.

I am assuming you know how to create a Lambda function in AWS console already and if not, please read the Part #1 first.

Open the Command prompt and follow below steps:

Step 1: Install Lambda Templates for .NET Core

dotnet new -i Amazon.Lambda.Templates

Step 2: Create an empty function

dotnet new lambda.EmptyFunction –name MyTestLambdaFun


You should be able to see a folder structure like this is created.

image

under src\projectname you can see a Function.cs file which is our starting point.

Code will look like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Amazon.Lambda.Core;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace MyTestLambdaFun
{
     public class Function
     {
        
         /// <summary>
         /// A simple function that takes a string and does a ToUpper
         /// </summary>
         /// <param name="input"></param>
         /// <param name="context"></param>
         /// <returns></returns>
         public string FunctionHandler(string input, ILambdaContext context)
         {
             return input?.ToUpper();
         }
     }
}

Step 3 – Modify the code to return HTTP 200 status code.

It is necessary for lambda functions to return 200 status code, or else the function will work in AWS console when you “Test”, but the API Gateway endpoint will not.

After adding the StatusCode property, the function will look like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Amazon.Lambda.Core;

using Amazon.Lambda.APIGatewayEvents;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace MyTestLambdaFun
{
     public class Function
     {
        
         /// <summary>
         /// A simple function that takes a string and does a ToUpper
         /// </summary>
         /// <param name="input"></param>
         /// <param name="context"></param>
         /// <returns></returns>
         public APIGatewayProxyResponse FunctionHandler(ILambdaContext context)
         {
             return new APIGatewayProxyResponse
             {
                 Body = "Hello Lambda, from Praveen",
                 StatusCode = 200
             };

            
         }
     }
}

Do:

dotnet build


Now, if you are getting an error on APIGatewayProxyResponse, then you will have to install the dependency. Below command will help you:


dotnet add package Amazon.Lambda.APIGatewayEvents 

(Refer to nuget page)

Try again dotnet build, and I am expecting to have the build succeeded.

image

Step 4 – Package the function

If you have not installed Lambda tools, then install it first:

dotnet tool install -g Amazon.Lambda.Tools

Then use the command:

dotnet lambda package

image

Notice the last line, you will get path to a zip file which you have to upload to AWS Lambda.

Step 5 – Upload the package to AWS console

Login to AWS Console and navigate to your lambda function. In this example I am going to use the same function we created in Part #1.

Scroll up and you should see a “Function Code” section like this:

image

Upload your ZIP file by clicking the upload button.

Next, you have to do one important task. Go to the source code folder again and open a file named “aws-lambda-tools-defaults.json”.  You will have to copy the function-handler property value to the “Handler” textbox in “Function code” section.

image

image

image

Then click “Save” button.

Step 6 – Test the function

Click “Test”. You should see the test result like this: (Our function is not expecting an input parameter so you can create a dummy test event)

image

As a bonus, let us see how we can create a HTTP endpoint to this function.

Step 7 – Create API Gateway

Click “Trigger” button:

image

In the next screen, make these selections and click “Add”:

image

You will be redirected back to the dashboard. Scroll up and you will see a new section “API Gateway” with a new API endpoint URL. Use the link in browser to test.

image

image

Happy Lambda development!

You have noticed that I was rushing to finish the blog by not explaining in detail each step. I am leaving the rest to you as home work intentionally.

Refer to official .NET Core CLI documentation here.