npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ut-ussd

v7.3.2

Published

UT USSD module

Downloads

127

Readme

ut-ussd - USSD menu engine

Configuration options

{
  utUssd: {
    ussd: {
      exposeState: 'true|false', // this will expose runtime
      // state if set to true, defaults: false
      // refresh: gets refreshed on every cycle;
      // static(default): sets only once and will expire
      // in predefined period of time (timeOut);
      expireRule:  'refresh|static',
      timeOut: 1000, // expiration period definition
      shortCodes: { // short codes
        "*877#": "menu/entrance"
      },
      maintenanceModeState: "menu/maintenance", // maintenance mode state
      wrongInputState: "error/wrongInput", // wrong input state
      resumeState: "menu/resume", // resume state
      strings: [ // USSD strings
        "*877*1*1#",
        "*877*1*2#",
        "*877*2*1#",
        "*877*2*2#",
        "*877*2*3#",
        "*877*3*1#",
        "*877*3*2#",
        "*877*4#"
      ],
      defaultPhone: "1234", // default phone number for the simulator
      defaultShortCode: "*131#", // default short code for the simulator
      charsCount: true, // if characters count should be visible in the simulator
      // To display a slogan with the respective text above the phone number input
      // (no slogan will be displayed by default)
      slogan: 'Test'
    }
  }
}

Views

USSD menu is defined in template files named view.xml, each one being in a separate folder. Folders are usually structured to mirror the USSD menu structure.

For example:

ussd
├── components
|   ├── back.xml
|   ├── backToHome.xml
|   └── footer.xml
└── menu
    ├── home
    |   └── view.xml
    ├── login
    |   └── view.xml
    └── error
    |   ├── runtimeError
    |   |   └── view.xml
    |   └── wrongInput
    |       └── view.xml
    └── account
        ├── balanceEnquiry
        |   └── view.xml
        └── miniStatement
            └── view.xml

The template files are JavaScript template literals, passed to ut-function.template engine. Each view file can contain some specific markup as in the below examples:

  1. Links - links are defined with the tag <a id="" href="">, where the attribute id represents the USSD input, and href represents the next menu to show when this input is received.

    Menu
    <a id="1" href="menu/account">1. Account information</a>
  2. Expressions - the standard syntax ${} applicable to JS template literals can be used to define expressions, either simple ones like:

    ${params.system.prevState}

    or more complex like iterating over array:

    ${
      params.miniStatement.map(
        rec => `${rec.amount} on ${rec.postDate}`
      ).join(`<br/>`)
    }

    or for conditional rendering:

    ${
      params.view === 'pin' ? 'Please enter your PIN' :
      params.view === 'wrongPin' ? `Wrong PIN.<br/>Please try again' :
        'Unexpected Error'
    }
  3. Translations - the USSD template engine includes the function T, which can be used to translate text:

    ${T`Please enter your PIN`}

    The syntax is based on JS tagged templates.

  4. Includes - repeated fragments can be included in multiple views using the syntax:

    Some menu
    
    ${include('../../components/back.xml')}

The essential API objects available in the views ${} expressions are:

  • All node.js global objects
  • T - the function used for translation
  • include - the function used to include fragments
  • params - object, containing the template parameters

The essential tags available in the views are:

  • <a id="" href="">link</a> - for defining links to other menus
  • <br/> - for line breaks

Controllers

Each menu can have an optional controller.js file, which handles actions related to the menu. This file resides in the same folder as the menu's respective view.js. There are two optional actions, that can be defined:

  1. send: This is executed before rendering the current menu. It can call other services to fetch data to be displayed in the menu.
  2. receive: This is executed after receiving the response for a particular menu.

Controllers can be defined as object:

module.exports = {
    async send(params) {
        // some processing
        return params;
    },
    async receive(params) {
        // some processing
        return params;
    }
};

Controllers can be also be defined as a function, returning an object. This is useful when external API must be called using the familiar destructuring syntax: import:{}.

Note that import is the only available property at the moment.

module.exports = ({
    import: {
        subjectObjectPredicate
    }
}) => ({
    async send(params) {
        try {
            const result = await subjectObjectPredicate({});
            // some processing
            return params;
        } catch (error) {
            params.error = error;
            this.redirect('menu/error/runtimeError');
            return params;
        }
    }
});

The official API objects available in the controllers are:

  • import: {subjectObjectPredicate} - proxy for obtaining external API
  • this.redirect(view) - for selecting the next view