I’m the CTO of ONEm Communications Ltd. We’ve built a developer framework and platform that allows developers to rapidly build fully functional omni -channel micro-apps. In this article, I’ll show you how to build an example micro-app from scratch using our simple Node.js SDK. The tutorial assumes a basic knowledge of Node.js. We’ll retrieve the movie details courtesy of the free api provided by please make sure to abide by their ). http://themoviedb.org ( terms We'll write a web widget that can be integrated into any website... And the same codebase will also support an SMS client out of the box... The ONEm platform lets you host your micro-app anywhere on the Internet. For local testing, We’ll use to provide a publicly accessible URL so that we have a bridge between our app running on localhost and the ONEm Framework. ngrok Pre-requisites 1. Sign up for a free api key at https://www.themoviedb.org/account/signup 2. Sign up for a free ONEm developer account at https://developer-portal.onem.zone/ 3. Install ngrok from https://ngrok.com/ Micro-app basics When users make requests from web a widget or via SMS, the ONEm Framework will invoke an HTTP callback to the micro-app’s web server. The micro-app should respond with HTTP status code 200 and include, in the response body, some JSON which tells the ONEm Framework how to render the response to the user. If you’re intrigued and want to know more, you can checkout the developer docs at . https://developer-docs.onem.zone Our Node.js SDK provides an abstraction of the JSON format so you don’t have to worry about the details. You have two options, you can use the SDK to produce JSON by passing parameters to the functions provided, or alternatively you can use a templating library and write your micro-app’s views in HTML :) In this tutorial, we’ll be using the second option and specifically as the templating language, you can use instead if you prefer. pug ejs Ok, enough chat, let’s get coding! Project Structure and Code The code used in this tutorial can be accessed via the git repository here Our project structure will look like this: / index.js package.json .env /app_api /routes index.js /views landing.pug movieView.pug /public /index.html Install and the project’s base dependencies: Express $ npm install express dotenv jwt-simple request-promise url-join We’ll also use the ONEm Framework’s Node.js SDK: $ npm install onemsdk Create an in the project root with the following content: index.js ( ).config() express = ( ) api = ( ) app = express() PORT = process.env.PORT || app. (express.json()) app. (express. (__dirname + )); app. ( , api) app.get( , { res.sendFile( , { root: __dirname }) }) app.get( , { res.sendFile( , { root: __dirname }) }) app.get( , { res.sendFile( , { root: __dirname }) }) app.listen(PORT, () =&gt; console.log(`Example micro-app listening on port ${PORT}`)) require 'dotenv' const require 'express' const require './app_api/routes' const const 3000 use use static '/public' use '/api' '/' function (req, res) '/public/index.html' '*' function (req, res) '/public/index.html' '/*' function (req, res) '/public/index.html' When users make requests from our micro-app, such as selecting a menu option or submitting a form, the ONEm Framework will issue a HTTP request to the micro-app’s callback path. In the we set as the ‘basepath’ for all requests coming from the ONEm Framework with this line: index.js /api app.use('/api', api) When the micro-app is launched for the first time by a user, the ONEm Framework will display the micro-app’s “landing page”. This is a bit like the of a typical web application. The landing page is invoked by the ONEm Framework issuing a request to the micro-app’s API base path, in our case index.html /api. So we’ll want our app to handle a basic call to and respond with some initial content that the user will see. GET /api For our example, we’ll create a static menu, so that our users can view three different movies: When the user clicks on a movie title, we’ll show the movie’s image and description. First off, let’s create the landing menu options by creating a in the folder: landing.pug /views Movie Menu a(href= ) Mad max a(href= ) Ad Astra a(href= ) Sonic the Hedgehog section header ul li '/movie/76341/' li '/movie/419704/' li '/movie/454626/' And let’s connect the base route in Express in : /routes/index.js jwt = ( ) express = ( ) request = ( ) urlJoin = ( ) { loadTemplate } = ( ).parser { Response } = ( ) api = express.Router() READ_ACCESS_TOKEN = process.env.READ_ACCESS_TOKEN (!READ_ACCESS_TOKEN) moviedbProps = { : , : } VIEWS_PATH = views = { : , : , } api.get( , (req, res) =&gt; { { rootTag = loadTemplate(views.VIEW_LANDING, {}) response = Response.fromTag(rootTag) res.json(response.toJSON()) } (e) { .log(e) res.status( ).json({ : , : }) } }) api.get( , (req, res) =&gt; { movieId = req.params.id { data = request(urlJoin(moviedbProps.baseUrl, ), { : , : { : + READ_ACCESS_TOKEN } }) (data.poster_path) { data.poster_path = urlJoin(moviedbProps.baseImagePath, data.poster_path) } rootTag = loadTemplate(views.VIEW_MOVIE, data) response = Response.fromTag(rootTag) res.json(response.toJSON()) } (e) { .log(e) res.status( ).json({ : , : }) } }) .exports = api const require 'jwt-simple' const require 'express' const require 'request-promise' const require 'url-join' const require 'onemsdk' const require 'onemsdk' const // get this by signing up for an account at https://www.themoviedb.org/ const if throw "themoviedb.org READ_ACCESS_TOKEN not found in environment variables" const baseUrl 'https://api.themoviedb.org' baseImagePath 'http://image.tmdb.org/t/p/w185/' const './app_api/views/' const VIEW_LANDING ` landing.pug` ${VIEWS_PATH} VIEW_MOVIE ` movieView.pug` ${VIEWS_PATH} '/' async try let let catch console 500 success false message 'server error' '/movie/:id' async let try let await `/3/movie/ ` ${movieId} json true headers 'Authorization' 'Bearer ' if let let catch console 500 success false message 'server error' module /* * Here we set the a path to the landing.pug file */ const views = { VIEW_LANDING: `${VIEWS_PATH}landing.pug`, VIEW_MOVIE: `${VIEWS_PATH}movieView.pug` } /* * The api's base path is called when users hit our app * for the first time. We'll use the onemsdk to parse the * pug file and generate the raw JSON response */ api.get('/', async (req, res) => { try { let rootTag = loadTemplate(views.VIEW_LANDING, {}) let response = Response.fromTag(rootTag) res.json(response.toJSON()) } catch (e) { console.log(e) res.status(500).json({ success: false, message: 'server error' }) } }) also contains a route for the movie view page, when the user clicks on a movie title, the ONEm Framework will issue an HTTP GET callback to the associated with that option, eg in we have the following line: /routes/index.js href landing.pug a(href='/movie/76341/') Mad max Later in this tutorial, we will tell the ONEm Framework to use the base path of , which will eventually translate into when the user selects to view Mad Max. /api HTTP GET /api/movie/76341 Ok, so a quick recap. We have created two views using pug. Our web server is ready to accept callbacks from and /api /api/movie/{:id} So what’s remaining now is to complete the setup of our micro-app. Create a file in the project root path: .env PORT=3000 READ_ACCESS_TOKEN=<themoviedb API Read Access Token (v4 auth) 2. We’ll use to give us a publicly accessible url to our Micro-app at . ngrok localhost:3000 ngrok http 3000 Copy the link provided by ngrok, it will be something like https://6f1ca0d4.ngrok.io 3. In the ONEm Developer Portal, select “Create App” and set the to your app appending /api to the base path, eg: callback path https:// 6f1ca0d4 .ngrok.io /api 4. In the ONEm Developer Portal, select your new app and then select “Web channel”. Copy/paste the javascript code shown in the tab, into the section of the of your Micro-app: body /public/index.html ... <body> <h1>Movie micro-app</h1> <script src="https://bot.onem.zone/bundle.js"></script> <script> ONEmStart({ app_id: "5eb948e62d60d1001f32fb83" }).render('body'); </script> </body> Tip: This code snippet can be included in any website, if you have access to another website’s index.html, then go ahead and try it. Running Fire up your micro-app: $ node index In your browser, visit (or where ever your app is configured to listen). localhost:3000 The ONEm Micro-app should be visible in bottom right-hand corner. Click the icon to open. You can also view the SMS client from the developer portal After registering your mobile number, you can test out the SMS interface by entering # followed by your micro-app name in the input box. test client. This is of course just an introduction, if this has intrigued you to learn more then you can access more details at https://developer-docs.onem.zone