All posts by Mayur Ariwala

jQuery-Ajax-Image-Upload-with-progress-bar

jQuery Ajax File Upload with Progress Bar

File upload should always have a progress bar. It is a feature that most of the developers ignore. It should be seen as part of the functionality. The users cannot sit in the dark and keep guessing about the background progress.

When the user requests the server to perform some operation, it is good to show them about the progress. It is a good UI/UX behaviour. The progress bar is one of the best ways to show the status of the in-progress operation. In this example, let us learn to create a progress bar using jQuery while uploading a file via AJAX.

A file input option is used to choose the file and the file binaries are posted to the server via AJAX. After sending the file upload request to the server, the AJAX script initializes jQuery animation to show the file upload progress bar. The progress bar will highlight the progressing percentage with jQuery animation. The jQuery Form plugin is used in this example code to handle the AJAX image upload with progressive status.

HTML Form with File Upload

The landing page will show a HTML form with the file input. Users will choose the file and post the file data by submitting the form via AJAX. The jQuery and jQuery Form library is included at the beginning of the script. A minimal jQuery validation script is added to check if the image file had been chosen before submitting the form.

<!DOCTYPE html>

<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">

<link rel="stylesheet" type="text/css" href="style.css">
https://code.jquery.com/jquery-3.3.1.min.js
http://jquery.form.min.js
http://uploadFile.js

</head>
<body>
    <h1>jQuery Ajax Image Upload with Animating Progress Bar</h1>
    <div class="form-container">
        <form action="uploadFile.php" id="uploadForm" name="frmupload"
            method="post" enctype="multipart/form-data">
            <input type="file" id="uploadImage" name="uploadImage" /> <input
                id="submitButton" type="submit" name='btnSubmit'
                value="Submit Image" />

        </form>
        <div class='progress' id="progressDivId">
            <div class='progress-bar' id='progressBar'></div>
            <div class='percent' id='percent'>0%</div>
        </div>
        <div style="height: 10px;"></div>
        <div id='outputImage'></div>
    </div>
</body>
</html>

AJAX Form Submit to Request Server File Upload with Progress bar

The jQuery form library is used to submit the form via AJAX with an animated progress bar. The ajaxForm() function is used to submit the image file binaries to the PHP. The progress of the image upload is shown with a progress bar in the uploadProgress callback function. Also, the jQuery animate() method is called to create the progressing effect on the progress bar element.

$(document).ready(function () {
    $('#submitButton').click(function () {
    	    $('#uploadForm').ajaxForm({
    	        target: '#outputImage',
    	        url: 'uploadFile.php',
    	        beforeSubmit: function () {
    	        	  $("#outputImage").hide();
    	        	   if($("#uploadImage").val() == "") {
    	        		   $("#outputImage").show();
    	        		   $("#outputImage").html("<div class='error'>Choose a file to upload.</div>");
                    return false; 
                }
    	            $("#progressDivId").css("display", "block");
    	            var percentValue = '0%';

    	            $('#progressBar').width(percentValue);
    	            $('#percent').html(percentValue);
    	        },
    	        uploadProgress: function (event, position, total, percentComplete) {

    	            var percentValue = percentComplete + '%';
    	            $("#progressBar").animate({
    	                width: '' + percentValue + ''
    	            }, {
    	                duration: 5000,
    	                easing: "linear",
    	                step: function (x) {
                        percentText = Math.round(x * 100 / percentComplete);
    	                    $("#percent").text(percentText + "%");
                        if(percentText == "100") {
                        	   $("#outputImage").show();
                        }
    	                }
    	            });
    	        },
    	        error: function (response, status, e) {
    	            alert('Oops something went.');
    	        },
    	        
    	        complete: function (xhr) {
    	            if (xhr.responseText && xhr.responseText != "error")
    	            {
    	            	  $("#outputImage").html(xhr.responseText);
    	            }
    	            else{  
    	               	$("#outputImage").show();
        	            	$("#outputImage").html("<div class='error'>Problem in uploading file.</div>");
        	            	$("#progressBar").stop();
    	            }
    	        }
    	    });
    });
});

 

VOIP In Matrix JS SDK

This module outlines how two users in a room can set up a Voice over IP (VoIP) call to each other. Voice and video calls are built upon the WebRTC 1.0 standard. Call signalling is achieved by sending message events to the room. In this version of the spec, only two-party communication is supported (e.g. between two peers, or between a peer and a multi-point conferencing unit). This means that clients MUST only send call events to rooms with exactly two participants.

For a complete overview of Matrix Javascript SDK configuration, please go to our Matrix Javascript SDK.

Matrix Javascript SDK

Establish a call

This method is call by the caller when they wish to establish a call.

matrixCall = matrixcs.createNewMatrixCall(
        MATRIX_CLIENT_OBJ, ROOM_ID
);

For voice call

matrixCall.placeVoiceCall();
matrixCall.setRemoteAudioElement(document.getElementById("remote-audio"));

For video call

matrixCall.placeVideoCall(
    document.getElementById("remote-video"),
    document.getElementById("local-video")
);

Incoming call event for callee

client.on("Call.incoming", function(c) {
    console.log("Call ringing");
    console.log("Incoming call");
});

Callee answer the call

This method is call by the callee when they wish to answer the call.

call.answer();

Hangup the call

Method call by either party to signal their termination of the call. This can be sent either once the call has has been established or before to abort the call.

call.hangup();

Examples

<html>
<head>
<title>VoIP Test</title>
http://lib/matrix.js
http://call.js
</head>
<body>
	You can place and receive calls with this example. Make sure to edit the
    constants in <code>call.js</code> first.
    <div id="config"></div>
    <div id="result"></div>
    <button id="call">Place Call</button>
    <button id="answer">Answer Call</button>
    <button id="hangup">Hangup Call</button>
    <div id="videoBackground">
        <div id="videoContainer">
            <video id="remote"></video>
        </div>
    </div>
    <div id="videoBackground">
        <div id="videoContainer">
            <video id="local"></video>
        </div>
    </div>
</body>
</html>
console.log("Loading browser sdk");
var BASE_URL = "https://matrix.org";
var TOKEN = "accesstokengoeshere";
var USER_ID = "@username:localhost";
var ROOM_ID = "!room:id";


var client = matrixcs.createClient({
    baseUrl: BASE_URL,
    accessToken: TOKEN,
    userId: USER_ID
});
var call;

function disableButtons(place, answer, hangup) {
    document.getElementById("hangup").disabled = hangup;
    document.getElementById("answer").disabled = answer;
    document.getElementById("call").disabled = place;
}

function addListeners(call) {
    var lastError = "";
    call.on("hangup", function() {
        disableButtons(false, true, true);
        document.getElementById("result").innerHTML = (
            "<p>Call ended. Last error: "+lastError+"</p>"
        );
    });
    call.on("error", function(err) {
        lastError = err.message;
        call.hangup();
        disableButtons(false, true, true);
    });
}

window.onload = function() {
    document.getElementById("result").innerHTML = "<p>Please wait. Syncing...</p>";
    document.getElementById("config").innerHTML = "<p>" +
        "Homeserver: <code>"+BASE_URL+"</code><br/>"+
        "Room: <code>"+ROOM_ID+"</code><br/>"+
        "User: <code>"+USER_ID+"</code><br/>"+
        "</p>";
    disableButtons(true, true, true);
};

client.on("sync", function(state, prevState, data) {
    switch (state) {
        case "PREPARED":
          syncComplete();
        break;
   }
});

function syncComplete() {
    document.getElementById("result").innerHTML = "<p>Ready for calls.</p>";
    disableButtons(false, true, true);

    document.getElementById("call").onclick = function() {
        console.log("Placing call...");
        call = matrixcs.createNewMatrixCall(
            client, ROOM_ID
        );
        console.log("Call => %s", call);
        addListeners(call);
        call.placeVideoCall(
            document.getElementById("remote"),
            document.getElementById("local")
        );
        document.getElementById("result").innerHTML = "<p>Placed call.</p>";
        disableButtons(true, true, false);
    };

    document.getElementById("hangup").onclick = function() {
        console.log("Hanging up call...");
        console.log("Call => %s", call);
        call.hangup();
        document.getElementById("result").innerHTML = "<p>Hungup call.</p>";
    };

    document.getElementById("answer").onclick = function() {
        console.log("Answering call...");
        console.log("Call => %s", call);
        call.answer();
        disableButtons(true, true, false);
        document.getElementById("result").innerHTML = "<p>Answered call.</p>";
    };

    client.on("Call.incoming", function(c) {
        console.log("Call ringing");
        disableButtons(true, false, false);
        document.getElementById("result").innerHTML = "<p>Incoming call...</p>";
        call = c;
        addListeners(call);
    });
}
client.startClient();

 

React Quickstart Tutorial

React is a JavaScript library created by Facebook.
ReactJS is a tool for building UI components.

Adding React to an HTML Page

This quickstart tutorial will add React to a page like this:

Example

<!DOCTYPE html>
<html lang="en">
<title>Test React</title>

<!-- Load React API -->
https://unpkg.com/react@16/umd/react.production.min.js
<!-- Load React DOM-->
https://unpkg.com/react-dom@16/umd/react-dom.production.min.js
<!-- Load Babel Compiler -->
https://unpkg.com/babel-standalone@6.15.0/babel.min.js

<body>


    //  JSX Babel code goes here


</body>
</html>

What is Babel?

Babel is a JavaScript compiler that can translate markup or programming languages into JavaScript.

With Babel, you can use the newest features of JavaScript (ES6 – ECMAScript 2015).

Babel is available for different conversions. React uses Babel to convert JSX into JavaScript.

Please note that is needed for using Babel.


What is JSX?

JSX stands for JavaScript XML.
JSX is an XML/HTML like extension to JavaScript.

Example

const element = <h1>Hello World!</h1>

As you can see above, JSX is not JavaScript nor HTML.

JSX is a XML syntax extension to JavaScript that also comes with the full power of ES6 (ECMAScript 2015).

Just like HTML, JSX tags can have a tag names, attributes, and children. If an attribute is wrapped in curly braces, the value is a JavaScript expression.

Note that JSX does not use quotes around the HTML text string.

React DOM Render

The method ReactDom.render() is used to render (display) HTML elements:

Example

Hello World!
ReactDOM.render( <h1>Hello React!</h1>, document.getElementById('id01'));

JSX Expressions

Expressions can be used in JSX by wrapping them in curly {} braces.

Example

Hello World!
const name = 'John Doe'; ReactDOM.render( <h1>Hello {name}!</h1>, document.getElementById('id01'));

React Elements

React applications are usually built around a single HTML element.

React developers often call this the root node (root element):

React elements look like this:

const element = <h1>Hello React!</h1>

Elements are rendered (displayed) with the ReactDOM.render() method:

ReactDOM.render(element, document.getElementById('root'));

React elements are immutable. They cannot be changed.

The only way to change a React element is to render a new element every time:

Example

function tick() {
    const element = (<h1>{new Date().toLocaleTimeString()}</h1>);
    ReactDOM.render(element, document.getElementById('root'));
}
setInterval(tick, 1000);

React Components

React components are JavaScript functions.

This example creates a React component named “Welcome”:

Example

function Welcome() {
    return <h1>Hello React!</h1>;
}
ReactDOM.render(<Welcome />, document.getElementById('root'));

React can also use ES6 classes to create components.

This example creates a React component named Welcome with a render method:

Example

class Welcome extends React.Component {
    render() { return(<h1>Hello React!</h1>); }
}
ReactDOM.render(<Welcome />, document.getElementById('root'));

React Component Properties

This example creates a React component named “Welcome” with property arguments:

Example

function Welcome(props) {
    return <h1>Hello {props.name}!</h1>;
}
ReactDOM.render(<Welcome name="John Doe"/>, document.getElementById('root'));

React can also use ES6 classes to create components.

This example also creates a React component named “Welcome” with property arguments:

Example

class Welcome extends React.Component {
    render() { return(<h1>Hello {this.props.name}</h1>); }
}
ReactDOM.render(<Welcome name="John Doe"/>, document.getElementById('root'));

 JSX Compiler

The examples on this page compiles JSX in the browser.

For production code, the compilation should be done separately.


Create React Application

Facebook has created a Create React Application with everything you need to build a React app.

It is a a development server that uses Webpack to compile React, JSX, and ES6, auto-prefix CSS files.

The Create React App uses ESLint to test and warn about mistakes in the code.

To create a Create React App run the following code on your terminal:

Example

npx create-react-app react-tutorial

Make sure you have Node.js 5.2 or higher. Otherwise you must install npx:

Example

npm i npx

Start one folder up from where you want your application to stay:

Example

C:\Users\myUser>npx create-react-app react-tutorial

Success Result:

npx: installed 63 in 10.359s
Creating a new React app in C:\Users\myUser\react-tutorial.
Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts...
+ react-dom@16.5.2
+ react@16.5.2
+ react-scripts@2.0.4
added 1732 packages from 664 contributors and audited 31900 packages in 355.501s
found 0 vulnerabilities+ react@16.5.2

Success! Created react-tutorial at C:\Users\myUser\react-tutorial
Inside that directory, you can run several commands:

npm start
Starts the development server.

npm run build
Bundles the app into static files for production.

npm test
Starts the test runner.

npm run eject
Removes this tool and copies build dependencies, configuration files
and scripts into the app directory. If you do this, you can't go back!

We suggest that you begin by typing:

cd react-tutorial
npm start

Matrix Javascript SDK

Matrix Client-Server r0 SDK for JavaScript. This SDK can be run in a browser or in Node.js.

Quickstart

In a browser

Download either the full or minified version from https://github.com/matrix-org/matrix-js-sdk/releases/latest and add that as a <script> to your page. There will be a global variable matrixcs attached to window through which you can access the SDK. See below for how to include libolm to enable end-to-end-encryption.

Please check the working browser example for more information.

In Node.js

Ensure you have the latest LTS version of Node.js installed.

Using yarn instead of npm is recommended. Please see the Yarn install guide if you do not have it already.

yarn add matrix-js-sdk

var sdk = require("matrix-js-sdk");
var client = sdk.createClient("https://matrix.org");
client.publicRooms(function(err, data) {
    console.log("Public Rooms: %s", JSON.stringify(data));
});

See below for how to include libolm to enable end-to-end-encryption. Please check the Node.js terminal app for a more complex example.

To start the client:

await client.startClient({initialSyncLimit: 10});

You can perform a call to /sync to get the current state of the client:

client.once('sync', function(state, prevState, res) {
    if(state === 'PREPARED') {
        console.log("prepared");
    } else {
        console.log(state);
        process.exit(1);
    }
});

To send a message:

var content = {
    "body": "message text",
    "msgtype": "m.text"
};
client.sendEvent("roomId", "m.room.message", content, "", (err, res) => {
    console.log(err);
});

To listen for message events:

client.on("Room.timeline", function(event, room, toStartOfTimeline) {
  if (event.getType() !== "m.room.message") {
    return; // only use messages
  }
  console.log(event.event.content.body);
});

By default, the matrix-js-sdk client uses the MemoryStore to store events as they are received. For example to iterate through the currently stored timeline for a room:

Object.keys(client.store.rooms).forEach((roomId) => {
  client.getRoom(roomId).timeline.forEach(t => {
      console.log(t.event);
  });
});

What does this SDK do?

This SDK provides a full object model around the Matrix Client-Server API and emits events for incoming data and state changes. Aside from wrapping the HTTP API, it:

  • Handles syncing (via /initialSync and /events)
  • Handles the generation of “friendly” room and member names.
  • Handles historical RoomMember information (e.g. display names).
  • Manages room member state across multiple events (e.g. it handles typing, power levels and membership changes).
  • Exposes high-level objects like Rooms, RoomState, RoomMembers and Users which can be listened to for things like name changes, new messages, membership changes, presence changes, and more.
  • Handle “local echo” of messages sent using the SDK. This means that messages that have just been sent will appear in the timeline as ‘sending’, until it completes. This is beneficial because it prevents there being a gap between hitting the send button and having the “remote echo” arrive.
  • Mark messages which failed to send as not sent.
  • Automatically retry requests to send messages due to network errors.
  • Automatically retry requests to send messages due to rate limiting errors.
  • Handle queueing of messages.
  • Handles pagination.
  • Handle assigning push actions for events.
  • Handles room initial sync on accepting invites.
  • Handles WebRTC calling.

Later versions of the SDK will:

  • Expose a RoomSummary which would be suitable for a recents page.
  • Provide different pluggable storage layers (e.g. local storage, database-backed)

 Usage

 Conventions

 Emitted events

The SDK will emit events using an EventEmitter. It also emits object models (e.g. Rooms, RoomMembers) when they are updated.

// Listen for low-level MatrixEvents
client.on("event", function(event) {
    console.log(event.getType());
});

// Listen for typing changes
client.on("RoomMember.typing", function(event, member) {
    if (member.typing) {
      console.log(member.name + " is typing...");
    }
    else {
      console.log(member.name + " stopped typing.");
    }
});

// start the client to setup the connection to the server
client.startClient();

Promises and Callbacks

Most of the methods in the SDK are asynchronous: they do not directly return a result, but instead return a Promise which will be fulfilled in the future.

The typical usage is something like:

matrixClient.someMethod(arg1, arg2).done(function(result) {
    ...
});

Alternatively, if you have a Node.js-style callback(err, result) function, you can pass the result of the promise into it with something like:

matrixClient.someMethod(arg1, arg2).nodeify(callback);

The main thing to note is that it is an error to discard the result of a promise-returning function, as that will cause exceptions to go unobserved. If you have nothing better to do with the result, just call .done() on it. See http://documentup.com/kriskowal/q/#the-end for more information.

Methods which return a promise show this in their documentation.

Many methods in the SDK support both Node.js-style callbacks and Promises, via an optional callback argument. The callback support is now deprecated: new methods do not include a callback argument, and in the future it may be removed from existing methods.

Examples

This section provides some useful code snippets which demonstrate the core functionality of the SDK. These examples assume the SDK is setup like this:

var sdk = require("matrix-js-sdk");
var myUserId = "@example:localhost";
var myAccessToken = "QGV4YW1wbGU6bG9jYWxob3N0.qPEvLuYfNBjxikiCjP";
var matrixClient = sdk.createClient({
    baseUrl: "http://localhost:8008",
    accessToken: myAccessToken,
    userId: myUserId
});

Automatically join rooms when invited

matrixClient.on("RoomMember.membership", function(event, member) {
    if (member.membership === "invite" && member.userId === myUserId) {
        matrixClient.joinRoom(member.roomId).done(function() {
           console.log("Auto-joined %s", member.roomId);
        });
    }
});

matrixClient.startClient();

Print out messages for all rooms

matrixClient.on("Room.timeline", function(event, room, toStartOfTimeline) {
    if (toStartOfTimeline) {
        return; // don't print paginated results
    }
    if (event.getType() !== "m.room.message") {
        return; // only print messages
    }
    console.log(
        // the room name will update with m.room.name events automatically
        "(%s) %s :: %s", room.name, event.getSender(), event.getContent().body
    );
});

matrixClient.startClient();

Output:

(My Room) @megan:localhost :: Hello world
(My Room) @megan:localhost :: how are you?
(My Room) @example:localhost :: I am good
(My Room) @example:localhost :: change the room name
(My New Room) @megan:localhost :: done

Print out membership lists whenever they are changed

matrixClient.on("RoomState.members", function(event, state, member) {
    var room = matrixClient.getRoom(state.roomId);
    if (!room) {
       return;
    }
    var memberList = state.getMembers();
    console.log(room.name);
    console.log(Array(room.name.length + 1).join("="));  // underline
    for (var i = 0; i < memberList.length; i++) {
       console.log(
       "(%s) %s",
           memberList[i].membership,
           memberList[i].name
       );
    }
});

matrixClient.startClient();

Output:

My Room
=======
(join) @example:localhost
(leave) @alice:localhost
(join) Bob
(invite) @charlie:localhost

API Reference

A hosted reference can be found at http://matrix-org.github.io/matrix-js-sdk/index.html

This SDK uses JSDoc3 style comments. You can manually build and host the API reference from the source files like this:

$ yarn gendoc
$ cd .jsdoc
$ python -m SimpleHTTPServer 8005

Then visit http://localhost:8005 to see the API docs.

End-to-end encryption support

The SDK supports end-to-end encryption via the Olm and Megolm protocols, using libolm. It is left up to the application to make libolm available, via the Olm global.

It is also necessry to call matrixClient.initCrypto() after creating a new MatrixClient (but before calling matrixClient.startClient()) to initialise the crypto layer.

If the Olm global is not available, the SDK will show a warning, as shown below; initCrypto() will also fail.

Unable to load crypto module: crypto will be disabled: Error: global.Olm is not defined

If the crypto layer is not (successfully) initialised, the SDK will continue to work for unencrypted rooms, but it will not support the E2E parts of the Matrix specification.

To provide the Olm library in a browser application:

To provide the Olm library in a node.js application:

  • yarn add https://packages.matrix.org/npm/olm/olm-3.0.0.tgz (replace the URL with the latest version you want to use from https://packages.matrix.org/npm/olm/)
  • global.Olm = require('olm'); before loading matrix-js-sdk.

If you want to package Olm as dependency for your node.js application, you can use yarn add https://packages.matrix.org/npm/olm/olm-3.0.0.tgz. If your application also works without e2e crypto enabled, add --optional to mark it as an optional dependency.

Contributing

This section is for people who want to modify the SDK. If you just want to use this SDK, skip this section.

First, you need to pull in the right build tools:

$ yarn install

Building

To build a browser version from scratch when developing::

$ yarn build

To constantly do builds when files are modified (using watchify)::

$ yarn watch

To run tests (Jasmine)::

$ yarn test

To run linting:

$ yarn lint

Fusebill AJAX Transparent Redirect

To facilitate PCI compliant credit card collections Fusebill provides a AJAX Transparent Redirect endpoint which you can use to securely capture customer’s credit cards. If you are adding the first payment method on a customer, it will be set to the default payment method automatically.

This API action is authenticated with a separate Public API Key. If you do not have that key, please contact Fusebill Support. The Public Key can only be used to authenticate the Transparent Redirect action.

Google reCAPTCHA required.

Fusebill leverages reCAPTCHA technology to ensure payment method data captured is provided by a human and to protect against bots and scripting.

We use Google reCAPTCHA V2 in order to accomplish this.
https://developers.google.com/recaptcha/intro
The basic workflow for how this is accomplished is as follows:

  • Using Fusebill’s public site key, the client is presented with a captcha widget.
  • The user then verifies that they are human, starting with a check box. The user may be presented with additional verification steps such as an image recognition task.
  • The captcha widget then verifies with Google that the user is human, and returns a response token.
  • That response token is then sent to Fusebill with the payment method data for our system to validate and verify.
Fusebill Environment
reCAPTCHA Public Site Key

Staging (stg-payments.subscriptionplatform.com)

6LcI_GwUAAAAAJZu0VvB68DdxNxb5ZcBIwAX7RVj

Sandbox and Production (payments.subscriptionplatform.com)

6LfVtGwUAAAAALHn9Ycaig9801f6lrPmouzuKF11

Create Credit Card Payment Method

Field Name
Details
Required
Type

CustomerID

This is the Fusebill customer ID of the customer you wish to add the card to

Yes

Number

PublicAPIKey

This is your public API key.
This is found in fusebill account under Settings > Integrations > Transparent Redirect.

Yes

String

CardNumber

This is the credit card number.

Yes

Number

FirstName

 

The first name of the cardholder.

Yes

String

LastName

The last name of the card holder.

Yes

String

ExpirationMonth

Expiration month on the credit card.

Yes

Number

ExpirationYear

Expiration on the credit card.

Yes

Number

CVV

The credit card verification number.

Yes

Number

recaptcha

Recaptcha token response.

Yes

String

riskToken

WePay Risk token

No+

String

clientIp

Client/Customer IP address

No+

String

email

Customer Email address

No+

String

address1

First line of payment method address.

No*

String

address2

Second line of payment method address.

No*

String

city

City of the payment method

No*

String

stateId

State ID of the Payment method.
These can be found by performing a GET to v1/countries

No*

Number

countryId

Country ID of the payment method.
These can be found by performing a GET to v1/countries

No*

Number

postalZip

PostalZip of the payment method

No*

String

paymentCollectOptions

Object that allows specifying an amount to collect when creating the card.

Only works through Json
{
"collectionAmount": 1.0
}

No

Object

+ Denotes a field required for Fusebill Payments API Risk Fields
* Denotes fields required for AVS and may be required by your account’s Gateway. These fields are also required if using Fusebill Payments accounts as AVS is mandatory.

Notes:- Address information can optionally be captured as well.

Sample Code

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<title>AJAX Transparent Redirect</title>
		http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
		
		
		
		
      var verifyCallback = function(response) {
        document.getElementById("mySubmit").disabled = false;
        $('input#recaptcha_token').val(response);
      };
      var expCallback = function () {
        document.getElementById("mySubmit").disabled = true;
        grecaptcha.reset();
      };
      var onloadCallback = function() {
        grecaptcha.render('exampleWithCallback', {
          'sitekey': '',
          'callback': verifyCallback,
          'expired-callback': expCallback
        });
      };
      
			function AJAXTransparentRedirect() {                                 
				var dataString = 'CustomerId='+ $('input#CustomerId').val() + 
						'&PublicApiKey=' + $('input#PublicApiKey').val() + 
						'&SuccessUri='+$('input#SuccessUri').val() +
						'&FailUri='+$('input#FailUri').val() + 
						'&CardNumber='+$('input#CardNumber').val() + 
						'&FirstName='+$('input#FirstName').val() + 
						'&LastName='+$('input#LastName').val() + 
						'&ExpirationMonth='+$('input#ExpirationMonth').val() + 
						'&ExpirationYear='+$('input#ExpirationYear').val() + 
						'&makeDefault='+$('input#MakeDefault').val() + 
						'&Cvv='+$('input#Cvv').val() +
						'&recaptcha=' + $('input#recaptcha_token').val();
				alert(dataString);

				//Set up the request
				var request = $.ajax({
					type: "POST",
					url: "https://stg-payments.subscriptionplatform.com/api/paymentsv2/",                   
					data: dataString 
				});

				//Set up the callback functions
				request.done(function (msg) {
					//$('#response').append("

success

"); alert("success"); //document.location.replace = ''; }); request.fail(function (jqXHR) { // $('#response').append("

failure

"); alert(parseAndBuildErrorMessage(jqXHR)); //document.location.replace = ''; expCallback(); }); } function htmlEscape(msg) { return document.createElement('span') .appendChild(document.createTextNode(msg)) .parentNode .innerHTML; } function buildErrorMessage (errors) { if (errors.length == 0) { return ""; } var message; if (errors.length > 1) { message = "
    "; for (var i = 0; i " + htmlEscape(errors[i].Value) + ""; } } message += "
"; } else { var internalErrors = errors[0].Value; internalErrors = internalErrors.split("\r\n"); if (internalErrors.length > 1) { message = "
    "; for (var i = 0; i " + htmlEscape(internalErrors[i]) + ""; } message += "
"; } } else { message = htmlEscape(errors[0].Value); } } return message; } function parseAndBuildErrorMessage (xhr) { if (xhr.status >= 500) return "An error occurred, please try again"; else return buildErrorMessage(xhr.responseJSON.Errors); } </head> <body> <form id="allfields"> <fieldset> <div> <label for="CustomerId">Customer Id</label> <input autofocus="autofocus" id="CustomerId" name="CustomerId" type="text" value="your customer id here" /> </div> <div> <label for="PublicApiKey">Public Api Key</label> <input id="PublicApiKey" name="PublicApiKey" type="text" value="your key here" /> </div> <div> <label for="CardNumber">Card number</label> <input id="CardNumber" name="CardNumber" type="text" value="4111111111111111" /> </div> <div> <label for="FirstName">First name</label> <input id="FirstName" name="FirstName" type="text" value="John" /> </div> <div> <label for="LastName">Last name</label> <input id="LastName" name="LastName" type="text" value="Doe" /> </div> <div> <label for="ExpirationMonth">Expiry month</label> <input id="ExpirationMonth" name="ExpirationMonth" type="text" value="12" /> </div> <div> <label for="ExpirationYear">Expiry year</label> <input id="ExpirationYear" name="ExpirationYear" type="text" value="20" /> </div> <div> <label for="Cvv">CVV</label> <input id="Cvv" name="Cvv" type="text" value="123" /> </div> <input id="MakeDefault" name="MakeDefault" type="hidden" value="true" /> <div class="g-recaptcha" id="exampleWithCallback"></div> <input id="recaptcha_token" name="recaptcha_token" type="hidden" /> <fieldset> </form> <input type="button" onCLick="AJAXTransparentRedirect();" value="Submit Card" id="mySubmit" disabled /> <div id="response"/> </body> </html> https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit

Sample Response

{
    "maskedCardNumber" : "************1111",
    "cardType" : "Visa",
    "expirationMonth" : 10,
    "expirationYear" : 23,
    "customerId" : 50975,
    "firstName" : "a",
    "lastName" : "a",
    "address1" : null,
    "address2" : null,
    "countryId" : null,
    "country" : "",
    "stateId" : null,
    "state" : "",
    "city" : null,
    "postalZip" : null,
    "makeDefault" : true,
    "id" : 5933,
    "uri" : null
}

Fusebill Payments

When using Fusebill Payments as your gateway processing account, some additional processing and data is required.

These are the ClientIP and a Risk token.

Additional information is available here.

Fusebill Test Gateways

Available here.

Using WebSockets in Javascript

WebSockets is a next-generation bidirectional communication technology for web applications which operates over a single socket and is exposed via a JavaScript interface in HTML 5 compliant browsers.

Source: [WebSockets – A Conceptual Deep Dive](https://ably.com/topic/websockets)

Once you get a Web Socket connection with the web server, you can send data from browser to server by calling a send() method, and receive data from server to browser by an onmessage event handler.

Following is the API which creates a new WebSocket object.

var Socket = new WebSocket(url, [protocal] );

Here first argument, url, specifies the URL to which to connect. The second attribute, protocol is optional, and if present, specifies a sub-protocol that the server must support for the connection to be successful.

A simple example

To open a websocket connection, we need to create new WebSocket using the special protocol ws in the url:

var Socket = new WebSocket("ws://howto.lintel.in/");

There’s also encrypted wss:// protocol. It’s like HTTPS for websockets.

Always prefer wss://

The wss:// protocol not only encrypted, but also more reliable.

That’s because ws:// data is not encrypted, visible for any intermediary. Old proxy servers do not know about WebSocket, they may see “strange” headers and abort the connection.

On the other hand, wss:// is WebSocket over TLS, (same as HTTPS is HTTP over TLS), the transport security layer encrypts the data at sender and decrypts at the receiver, so it passes encrypted through proxies. They can’t see what’s inside and let it through.

WebSocket Attributes

Following are the attribute of WebSocket object. Assuming we created Socket object as mentioned above:-

Sr.No. Attribute & Description
1 Socket.readyState

The readonly attribute readyState represents the state of the connection. It can have the following values:-

  • A value of 0 indicates that the connection has not yet been established.
  • 1 value indicates that the connection is established and communication is possible.
  • 2 value indicates that the connection is going through the closing handshake.
  • 3 value indicates that the connection has been closed or could not be opened.

2 Socket.bufferedAmount

The readonly attribute bufferedAmount represents the number of bytes of UTF-8 text that have been queued using send() method.

WebSocket Events

Following are the events associated with WebSocket object. Assuming we created Socket object as mentioned above:-

Event Event Handler Description
open Socket.onopen This event occurs when socket connection is established.
message Socket.onmessage This event occurs when client receives data from server.
error Socket.onerror This event occurs when there is any error in communication.
close Socket.onclose This event occurs when connection is closed.

WebSocket Methods

These are the methods associated with WebSocket object. Assuming we created Socket object as mentioned above:-

Sr.No. Method & Description
1 Socket.send()

The send(data) method transmits data using the connection.

2 Socket.close()

The close() method would be used to terminate any existing connection.

WebSocket Example

WebSocket is a standard bidirectional TCP socket between the client and the server. The socket starts out as a HTTP connection and then “Upgrades” to a TCP socket after a HTTP handshake. After the handshake, either side can send data.

Client Side HTML & JavaScript Code

At the time of writing this tutorial, there are only few web browsers supporting WebSocket() interface. You can try following example with latest version of Chrome, Mozilla, Opera and Safari.

<!DOCTYPE HTML>

<html>
   <head>
      
         function WebSocketTest() {
            
            if ("WebSocket" in window) {
               alert("WebSocket is supported by your Browser!");
               
               // Let us open a web socket
               var ws = new WebSocket("ws://localhost:1234/test");
				
               ws.onopen = function() {
                 
                  // Web Socket is connected, send data using send()
                  ws.send("Message to send");
                  alert("Message is sent...");
               };
				
               ws.onmessage = function (evt) { 
                  var received_msg = evt.data;
                  alert("Message is received...");
               };
				
               ws.onclose = function() { 
                  
                  // websocket is closed.
                  alert("Connection is closed..."); 
               };
            } 
            else {
              
               // The browser doesn't support WebSocket
               alert("WebSocket NOT supported by your Browser!");
            }
         }
      
   </head>
   
   <body>
      
       <a href="javascript:WebSocketTest()">Run WebSocket</a>
      
   </body>
</html>

Country Picker With Flag jQuery plugin

About single/multiple country picker jQuery plugin :-

This single/multiple country picker jQuery plugin allows you to easily display a list of countries with flag in your Bootstrap form.

Dependencies :-

Usage :-

Create your <select> with the .country_selector class and add option of required countries.

Improtant Notes:
For multiple country picker add multiple attribute in <select> tag.

<select class="country_selector">
   <option value="">Select a country...</option>
   <option value="AF">Afghanistan</option>
   <option value="AX">Åland Islands</option>
   <option value="AL">Albania</option>
   <option value="DZ">Algeria</option>
   <option value="AS">American Samoa</option>
   <option value="AD">Andorra</option>
   <option value="AO">Angola</option>
   <option value="AI">Anguilla</option>
   <option value="AQ">Antarctica</option>
   <option value="AG">Antigua and Barbuda</option>
   <option value="AR">Argentina</option>
   <option value="AM">Armenia</option>
   <option value="AW">Aruba</option>
   <option value="AU">Australia</option>
   <option value="AT">Austria</option>
   <option value="AZ">Azerbaijan</option>
   <option value="BS">Bahamas</option>
   <option value="BH">Bahrain</option>
   <option value="BD">Bangladesh</option>
   <option value="BB">Barbados</option>
   <option value="BY">Belarus</option>
   <option value="BE">Belgium</option>
   <option value="BZ">Belize</option>
   <option value="BJ">Benin</option>
   <option value="BM">Bermuda</option>
   <option value="BT">Bhutan</option>
   <option value="BO">Bolivia, Plurinational State of</option>
   <option value="BA">Bosnia and Herzegovina</option>
   <option value="BW">Botswana</option>
   <option value="BV">Bouvet Island</option>
   <option value="BR">Brazil</option>
   <option value="IO">British Indian Ocean Territory</option>
   <option value="BN">Brunei Darussalam</option>
   <option value="BG">Bulgaria</option>
   <option value="BF">Burkina Faso</option>
   <option value="BI">Burundi</option>
   <option value="KH">Cambodia</option>
   <option value="CM">Cameroon</option>
   <option value="CA">Canada</option>
   <option value="CV">Cape Verde</option>
   <option value="KY">Cayman Islands</option>
   <option value="CF">Central African Republic</option>
   <option value="TD">Chad</option>
   <option value="CL">Chile</option>
   <option value="CN">China</option>
   <option value="CX">Christmas Island</option>
   <option value="CC">Cocos (Keeling) Islands</option>
   <option value="CO">Colombia</option>
   <option value="KM">Comoros</option>
   <option value="CG">Congo</option>
   <option value="CD">Congo, the Democratic Republic of the</option>
   <option value="CK">Cook Islands</option>
   <option value="CR">Costa Rica</option>
   <option value="CI">Côte d\'Ivoire</option>
   <option value="HR">Croatia</option>
   <option value="CU">Cuba</option>
   <option value="CY">Cyprus</option>
   <option value="CZ">Czech Republic</option>
   <option value="DK">Denmark</option>
   <option value="DJ">Djibouti</option>
   <option value="DM">Dominica</option>
   <option value="DO">Dominican Republic</option>
   <option value="EC">Ecuador</option>
   <option value="EG">Egypt</option>
   <option value="SV">El Salvador</option>
   <option value="GQ">Equatorial Guinea</option>
   <option value="ER">Eritrea</option>
   <option value="EE">Estonia</option>
   <option value="ET">Ethiopia</option>
   <option value="FK">Falkland Islands (Malvinas)</option>
   <option value="FO">Faroe Islands</option>
   <option value="FJ">Fiji</option>
   <option value="FI">Finland</option>
   <option value="FR">France</option>
   <option value="GF">French Guiana</option>
   <option value="PF">French Polynesia</option>
   <option value="TF">French Southern Territories</option>
   <option value="GA">Gabon</option>
   <option value="GM">Gambia</option>
   <option value="GE">Georgia</option>
   <option value="DE">Germany</option>
   <option value="GH">Ghana</option>
   <option value="GI">Gibraltar</option>
   <option value="GR">Greece</option>
   <option value="GL">Greenland</option>
   <option value="GD">Grenada</option>
   <option value="GP">Guadeloupe</option>
   <option value="GU">Guam</option>
   <option value="GT">Guatemala</option>
   <option value="GG">Guernsey</option>
   <option value="GN">Guinea</option>
   <option value="GW">Guinea-Bissau</option>
   <option value="GY">Guyana</option>
   <option value="HT">Haiti</option>
   <option value="HM">Heard Island and McDonald Islands</option>
   <option value="VA">Holy See (Vatican City State)</option>
   <option value="HN">Honduras</option>
   <option value="HK">Hong Kong</option>
   <option value="HU">Hungary</option>
   <option value="IS">Iceland</option>
   <option value="IN">India</option>
   <option value="ID">Indonesia</option>
   <option value="IR">Iran, Islamic Republic of</option>
   <option value="IQ">Iraq</option>
   <option value="IE">Ireland</option>
   <option value="IM">Isle of Man</option>
   <option value="IL">Israel</option>
   <option value="IT">Italy</option>
   <option value="JM">Jamaica</option>
   <option value="JP">Japan</option>
   <option value="JE">Jersey</option>
   <option value="JO">Jordan</option>
   <option value="KZ">Kazakhstan</option>
   <option value="KE">Kenya</option>
   <option value="KI">Kiribati</option>
   <option value="KP">Korea, Democratic People\'s Republic of</option>
   <option value="KR">Korea, Republic of</option>
   <option value="KW">Kuwait</option>
   <option value="KG">Kyrgyzstan</option>
   <option value="LA">Lao People\'s Democratic Republic</option>
   <option value="LV">Latvia</option>
   <option value="LB">Lebanon</option>
   <option value="LS">Lesotho</option>
   <option value="LR">Liberia</option>
   <option value="LY">Libyan Arab Jamahiriya</option>
   <option value="LI">Liechtenstein</option>
   <option value="LT">Lithuania</option>
   <option value="LU">Luxembourg</option>
   <option value="MO">Macao</option>
   <option value="MK">Macedonia, the former Yugoslav Republic of</option>
   <option value="MG">Madagascar</option>
   <option value="MW">Malawi</option>
   <option value="MY">Malaysia</option>
   <option value="MV">Maldives</option>
   <option value="ML">Mali</option>
   <option value="MT">Malta</option>
   <option value="MH">Marshall Islands</option>
   <option value="MQ">Martinique</option>
   <option value="MR">Mauritania</option>
   <option value="MU">Mauritius</option>
   <option value="YT">Mayotte</option>
   <option value="MX">Mexico</option>
   <option value="FM">Micronesia, Federated States of</option>
   <option value="MD">Moldova, Republic of</option>
   <option value="MC">Monaco</option>
   <option value="MN">Mongolia</option>
   <option value="ME">Montenegro</option>
   <option value="MS">Montserrat</option>
   <option value="MA">Morocco</option>
   <option value="MZ">Mozambique</option>
   <option value="MM">Myanmar</option>
   <option value="NA">Namibia</option>
   <option value="NR">Nauru</option>
   <option value="NP">Nepal</option>
   <option value="NL">Netherlands</option>
   <option value="AN">Netherlands Antilles</option>
   <option value="NC">New Caledonia</option>
   <option value="NZ">New Zealand</option>
   <option value="NI">Nicaragua</option>
   <option value="NE">Niger</option>
   <option value="NG">Nigeria</option>
   <option value="NU">Niue</option>
   <option value="NF">Norfolk Island</option>
   <option value="MP">Northern Mariana Islands</option>
   <option value="NO">Norway</option>
   <option value="OM">Oman</option>
   <option value="PK">Pakistan</option>
   <option value="PW">Palau</option>
   <option value="PS">Palestinian Territory, Occupied</option>
   <option value="PA">Panama</option>
   <option value="PG">Papua New Guinea</option>
   <option value="PY">Paraguay</option>
   <option value="PE">Peru</option>
   <option value="PH">Philippines</option>
   <option value="PN">Pitcairn</option>
   <option value="PL">Poland</option>
   <option value="PT">Portugal</option>
   <option value="PR">Puerto Rico</option>
   <option value="QA">Qatar</option>
   <option value="RE">Réunion</option>
   <option value="RO">Romania</option>
   <option value="RU">Russian Federation</option>
   <option value="RW">Rwanda</option>
   <option value="BL">Saint Barthélemy</option>
   <option value="SH">Saint Helena, Ascension and Tristan da Cunha</option>
   <option value="KN">Saint Kitts and Nevis</option>
   <option value="LC">Saint Lucia</option>
   <option value="MF">Saint Martin (French part)</option>
   <option value="PM">Saint Pierre and Miquelon</option>
   <option value="VC">Saint Vincent and the Grenadines</option>
   <option value="WS">Samoa</option>
   <option value="SM">San Marino</option>
   <option value="ST">Sao Tome and Principe</option>
   <option value="SA">Saudi Arabia</option>
   <option value="SN">Senegal</option>
   <option value="RS">Serbia</option>
   <option value="SC">Seychelles</option>
   <option value="SL">Sierra Leone</option>
   <option value="SG">Singapore</option>
   <option value="SK">Slovakia</option>
   <option value="SI">Slovenia</option>
   <option value="SB">Solomon Islands</option>
   <option value="SO">Somalia</option>
   <option value="ZA">South Africa</option>
   <option value="GS">South Georgia and the South Sandwich Islands</option>
   <option value="ES">Spain</option>
   <option value="LK">Sri Lanka</option>
   <option value="SD">Sudan</option>
   <option value="SR">Suriname</option>
   <option value="SJ">Svalbard and Jan Mayen</option>
   <option value="SZ">Swaziland</option>
   <option value="SE">Sweden</option>
   <option value="CH">Switzerland</option>
   <option value="SY">Syrian Arab Republic</option>
   <option value="TW">Taiwan, Province of China</option>
   <option value="TJ">Tajikistan</option>
   <option value="TZ">Tanzania, United Republic of</option>
   <option value="TH">Thailand</option>
   <option value="TL">Timor-Leste</option>
   <option value="TG">Togo</option>
   <option value="TK">Tokelau</option>
   <option value="TO">Tonga</option>
   <option value="TT">Trinidad and Tobago</option>
   <option value="TN">Tunisia</option>
   <option value="TR">Turkey</option>
   <option value="TM">Turkmenistan</option>
   <option value="TC">Turks and Caicos Islands</option>
   <option value="TV">Tuvalu</option>
   <option value="UG">Uganda</option>
   <option value="UA">Ukraine</option>
   <option value="AE">United Arab Emirates</option>
   <option value="GB">United Kingdom</option>
   <option value="US">United States</option>
   <option value="UM">United States Minor Outlying Islands</option>
   <option value="UY">Uruguay</option>
   <option value="UZ">Uzbekistan</option>
   <option value="VU">Vanuatu</option>
   <option value="VE">Venezuela, Bolivarian Republic of</option>
   <option value="VN">Viet Nam</option>
   <option value="VG">Virgin Islands, British</option>
   <option value="VI">Virgin Islands, U.S.</option>
   <option value="WF">Wallis and Futuna</option>
   <option value="EH">Western Sahara</option>
   <option value="YE">Yemen</option>
   <option value="ZM">Zambia</option>
   <option value="ZW">Zimbabwe</option>
</select>

Add CSS class under <head> tag.

.country_selector {
   cursor: text;
}
.country_selector {
   width: 400px;
   float: none;
   margin: auto;
   display: inline-block;
   text-align: left;
}

.country_selector.single .selectize-input:after {
   display: none !important;
}

.country_selector .selectize-input .item .flag-icon, .country_selector .selectize-dropdown .option .flag-icon{
   margin-right: 10px;
}

.country_selector.single .selectize-input, .country_selector.single .selectize-input input {
   cursor: text !important;
}

.country_selector .selectize-dropdown .option {
   cursor: pointer !important;
}

Add JS function under <script> tag in bottom or add in your JS file.

$('.country_selector').selectize({
    render: {
        option: function(data, escape) {
            return '<div class="option"><span class="flag-icon flag-icon-' + String(escape(data.value)).toLowerCase() + '"></span>' + escape(data.text) + '</div>';
        },
        item: function(data, escape) {
            return '<div class="item"><span class="flag-icon flag-icon-' + String(escape(data.value)).toLowerCase() + '"></span>' + escape(data.text) + '</div>';
        }
    },
});

Configuration :-

Refer to this documentation for more configuration.

AWS Cognito Configurations

Introduction

Cognito is the AWS solution for managing user profiles, and Federated Identities help keep track of your users across multiple logins. Integrated into the AWS ecosystem, AWS Cognito opens up a world of possibility for advanced front end development as Cognito+IAM roles give you selective secure access to other AWS services.

Go to AWS Cognito on the AWS console to get started!

Initial Setup — Cognito

AWS Cognito

We will be setting up AWS Cognito, which is a custom login pool (such as login with email). Cognito IS NOT a login manager for any type of login (such as Facebook and Gmail), only for custom logins.

Let’s first make a user pool by clicking on “Manage your User Pools”. A user pool is a group of users that fulfill the same designation. The setup screen should look like this:

User Pool Name

We’re gonna walk through this process step by step, so enter the Pool name of “App_Users” and click “Step through settings”. The next step is “Attributes”, where we define the attributes that our “App_Users” will have.

User Attributes

We now, we only want to have an email, password and “agentName”. The email is our unique identifier for a user and the password is a mandatory field (which is why you don’t see it in the list of standard attributes). We want users to be able to have a codename to go by, so let’s set up “agentName” is a custom attribute. We are only using “agentName” to show how to add custom attributes. Scroll down and you will see the option to add custom attributes.

Custom Attributes

As of the date this tutorial was written, you cannot go back and change the custom attributes (even though AWS appears to be able to), so be sure to get this right the first time! If you need to change attributes, you will have to create a new user pool. Hopefully AWS fixes this issue soon. Anyways, moving on to account policies!

Account Policies

So we can see here that our passwords can be enforced to require certain characters. Obviously requiring a mix of various character types would be more secure, but users often don’t like that. For a middle ground, lets just require the password to be 8+ characters in length, and include at least 1 number. We also want users to be able to sign themselves up. The other parts are not so important, so let’s move onto the next step: verifications.

Account Verifications

This part is cool, we can easily integrate multi-factor authentication (MFA). This means users must sign up with an email as well as another form of authentication such as a phone number. A PIN would be sent to that phone number and the user would use it to verify their account. We won’t be using MFA in this tutorial, just email verification. Set MFA to “off” and check only “Email” as a verification method. We can leave the “AppUsers-SMS-Role” (IAM role) that has been filled in, as we won’t be using it but may use it in the future. Cognito uses that IAM role to be authorized to send SMS text messages used in MFA. Since we’re not using MFA, we can move on to: Message Customizations.

Custom Account Messages

This part is cool, we can easily integrate multi-factor authentication (MFA). This means users must sign up with an email as well as another form of authentication such as a phone number. A PIN would be sent to that phone number and the user would use it to verify their account. We won’t be using MFA in this tutorial, just email verification. Set MFA to “off” and check only “Email” as a verification method. We can leave the “AppUsers-SMS-Role” (IAM role) that has been filled in, as we won’t be using it but may use it in the future. Cognito uses that IAM role to be authorized to send SMS text messages used in MFA. Since we’re not using MFA, we can move on to: Message Customizations.

Custom Account Messages

When users receive their account verification emails, we can specify what goes into that email. Here we have made a custom email and programmatically placed in the verification PIN represented as {####}. Unfortunately we can’t pass in other variables such as a verification link. To accomplish this, we would have to use a combination of AWS Lambda and AWS SES.

SES (Simple Email Service)

Next click “Verify a New Address”, and enter the email you would like to verify.

Now login to your email and open the email from AWS. Click the link inside the email to verify, and you will be redirected to the AWS SES page again. You have successfully verified an email! That was easy.

Now that’s done, let’s return back to AWS Cognito and move on to: Tags.

User Pool Tags

It is not mandatory to add tags to a user pool, but it is definitely useful for managing many AWS services. Let’s just add a tag for ‘AppName’ and set it to a value of ‘MyApp’. We can now move on to: Devices.

Devices

We can opt to remember our user’s devices. I usually select “Always” because remembering user devices is both free and requires no coding on our part. The information is useful too, so why not? Next step: Apps.

Apps

We want certain apps to have access to our user pool. These apps are not present anywhere else on the AWS ecosystem, which means when we create an “app”, it is a Cognito-only identifier. Apps are useful because we can have multiple apps accessing the same user pool (imagine an Uber clone app, and a complimentary Driving Test Practice App). We will set the refresh token to 30 days, which means each login attempt will return a refresh token that we can use for authentication instead of logging in every time. We un-click “Generate Client Secret” because we intend to log into our user pool from the front end instead of back end (ergo, we cannot keep secrets on the front end because that is insecure). Click “Create App” and then “Next Step” to move on to: Triggers.

Triggers

We can trigger various actions in the user authentication and setup flow. Remember how we said we can create more complex account verification emails using AWS Lambda and AWS SES? This is where we would set that up. For the scope of this tutorial, we will not be using any AWS Lambda triggers. Let’s move on to the final step: Review.

Review

Here we review all the setup configurations we have made. If you are sure about this info, click “Create Pool” and our Cognito User Pool will be generated!

Take note of the Pool Id us-east-1_6i5p2Fwao in the Pool details tab.

Notice the Pool Id

And the App client id 5jr0qvudipsikhk2n1ltcq684b in the Apps tab. We will need both of these in our client side app.

Notice the App client id

Now that Cognito is set up, we can set up Federated Identities for multiple login providers. In this tutorial we do not cover the specifics of FB Login as it is not within in the scope of this tutorial series. However, integrating FB Login is super easy and we will show how it’s done in the below section.

Initial Setup — Federated Identities

AWS Cognito

Next we want to setup “Federated Identities”. If we have an app that allows multiple login providers (Amazon Cognito, Facebook, Gmail..etc) to the same user, we would use Federated Identities to centralize all these logins. In this tutorial, we will be using both our Amazon Cognito login, as well as a potential Facebook Login. Go to Federated Identities and begin the process to create a new identity pool. Give it an appropriate name.

Create a new identity pool

Now expand the “Authentication providers” section and you will see the below screen. Under Cognito, we are going to add the Cognito User Pool that we just created. Copy and paste the User Pool ID and App Client ID that we made note of earlier.

Authentication providers

And if we wanted Facebook login for the same user identity pool, we can go to the Facebook tab and simply enter our Facebook App ID. That’s all there is to it on the AWS console!

Facebook tab

Save the identity pool and you will be redirected to the below screen where IAM roles are created to represent the Federated Identity Pool. The unauthenticated IAM role is for non-logged in users, and the authenticated version is for logged in users. We can grant these IAM roles permission to access other AWS resources like S3 buckets and such. That is how we achieve greater security by integrating our app throughout the AWS ecosystem. Continue to finish creating this Identity Pool.

IAM roles

You should now see the below screen after successfully creating the identity pool. You now only need to make note of 1 thing which is the Identity Pool ID (i.e. us-east-1:65bd1e7d-546c-4f8c-b1bc-9e3e571cfaa7) which we will use later in our code. Great!

Sample code

Exit everything and go back to the AWS Cognito main screen. If we enter the Cognito section or the Federated Identities section, we see that we have the 2 necessary pools set up. AWS Cognito and AWS Federated Identities are ready to go!

AWS Cognito
AWS Federated Identities

That’s all for set up! With these 2 pools we can integrate the rest of our code into Amazon’s complete authentication service and achieve top tier user management.

How to upload a file in Zoho using python?

UploadFile API Method of Zoho CRM

Table of Contents

  • Purpose
  • Request URL
  • Request Parameters
  • Python Code to Upload a file to a record
  • Sample Response

Purpose

You can use this method to attach files to records.

Request URL

XML Format:
https://crm.zoho.com/crm/private/xml/Leads/uploadFile?authtoken=Auth Token&scope=crmapi&id=Record Id&content=File Input Stream

JSON Format:
https://crm.zoho.com/crm/private/json/Leads/uploadFile?authtoken=Auth Token&scope=crmapi&id=Record Id&content=File Input Stream

Request Parameters

Parameter Data Type Description
authtoken* String Encrypted alphanumeric string to authenticate your Zoho credentials.
scope* String Specify the value as crmapi
id* String Specify unique ID of the “record” or “note” to which the file has to be attached.
content FileInputStream Pass the File Input Stream of the file
attachmentUrl String Attach a URL to a record.

* – Mandatory parameter

Important Note:

  • The total file size should not exceed 20 MB.
  • Your program can request only up to 60 uploadFile calls per min. If API User requests more than 60 calls, system will block the API access for 5 min.
  • If the size exceeds 20 MB, you will receive the following error message: “File size should not exceed 20 MB“. This limit does not apply to URLs attached via attachmentUrl.
  • The attached file will be available under the Attachments section in the Record Details Page.
  • Files can be attached to records in all modules except Reports, Dashboards and Forecasts.
  • In the case of the parameter attachmentUrl, content is not required as the attachment is from a URL.
    Example for attachmentUrl: crm/private/xml/Leads/uploadFile?authtoken=*****&scope=crmapi&id=<entity_id>&attachmentUrl=<insert_ URL>

Python Code to Upload a file to a record

Here’s a simple script that you can use to upload a file in zoho using python.

Go to https://pypi.python.org/pypi/MultipartPostHandler2/0.1.5 and get the egg file and install it.

In the program, you need to specify values for the following:
  • Your Auth Token
  • The ID of the Record
  • The uploadFile Request URL in the format mentioned above
  • The File Path i.e the location of the File
import MultipartPostHandler, urllib2

ID ='put the accounts zoho id here '
authtoken = 'your zoho authtoken here'
fileName = "your file name here - i use the full path and filename"

opener = urllib2.build_opener(MultipartPostHandler.MultipartPostHandler)

params = {'authtoken':authtoken,'scope':'crmapi','newFormat':'1','id':ID, 'content':open(fileName,"rb")}

final_URL = "https://crm.zoho.com/crm/private/json/Accounts/uploadFile"

rslts = opener.open(final_URL, params)

print rslts.read()

Sample Response

{
   "response":{
      "result":{
         "recorddetail":{
            "FL":[
               {
                  "val":"Id",
                  "content":"2211247000000120001"
               },
               {
                  "val":"Created Time",
                  "content":"2016-11-19 14:54:07"
               },
               {
                  "val":"Modified Time",
                  "content":"2016-11-19 14:54:07"
               },
               {
                  "val":"Created By",
                  "content":"mayur"
               },
               {
                  "val":"Modified By",
                  "content":"mayur"
               }
            ]
         },
         "message":"File has been attached successfully"
      },
      "uri":"/crm/private/json/Accounts/uploadFile"
   }
}