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

@gupshup-io/gupshup-onedirect

v1.1.4

Published

One Direct Module

Downloads

15

Readme

Overview

This library can be added in the bot project and can be used to send the analytics to the One Direct platform or send the analytics data to different applications (ex: Convomate).

  1. Send Analytics to the One Direct platform.
  2. Send Analytics Data to Applications such as Convomate,etc. using Queuing Mechanism.

Installation

npm install @gupshup-io/gupshup-onedirect

1. Send Analytics to One Direct Platform

In order to connect to OneDirect analytics we need following details -

  1. One Direct Brand Auth Token : Token is required to push the analytics
  2. One Direct Brand Mobile Number : The mobile number which the brand is associated with
  3. One Direct Brand Host Name : Host name of the brand which is registered in One Direct
  4. Bot Id : Unique Id for the bot through which the current message is sent
  5. Bot Name : Name of the corresponding bot.
  6. Channel Name : Channel through which message is being sent.

These above details need to passed in the constructor call shown as below:

Initialization

const oneDirectSDK = require("@gupshup-io/gupshup-onedirect").oneDirectSDK;
const whatsAppChannel = new oneDirectSDK(
                    {
                        oneDirectBrandAuthToken: ``,           # Unique API Key of the customer
                        oneDirectBrandAccountMobileNumber: ``, # Associated Mobile number
                                                                 of the oneDirect Account
                        oneDirectBrandAccountHostName: ``      # Host name of the customer
                    }, 
                    {
                        botName: ``,                           # Bot Name to be used for conversation
                        botId: ``,                             # Corresponding bot Id
                        channelName: ``                        # Channel through which message is being sent.
                    });

Flow

The library should be used in order to identify the flow of events by the user. From where the user started the journey and which route the user has taken, so its necessary to tag every Message/Node/State in the bot flow. And that tag should be passed as a parameter to the library. Also, we need to make sure that parent Message/Node/State is also known and passed to the library.

Methods

  • captureEvent : This method takes in the node details, message to be passed and channel id for both inbound and outbound requests and further executes the requests. The following are the parameters that need to be passed :

    • incomingMsg (String) : Message received from the user
    • outgoingMsg (String) : Message responded by the bot
    • channelId (Number): Unique Id for the channel in which the current message is exchanged
    • inboundNodeData (JSON Object) : Incoming Message JSON Object with nodeId, nodeName, parentId, flowName and flowId as keys.
       inboundNodeData = {
         "nodeId": "",   # Id for the node inside the flow which the message is generated by
         "nodeName": "", # Name of the corresponding node
         "parentId": "", # Id for the node after which the current Node is executed.
         "flowName": "", # Name of the flow to which the message is related to
         "flowId": "",   # Id of the corresponding flow
     }
      
       Flow will be the higher level entity and node will be entity within flow
       For example - `Menu` will be flow (Higher level) and `display_menu` will be a node
       Similarly `view_products` will be flow and `display_toothpaste`, `display_toothbrush`, `display_item3` will all be nodes.
       NodeId if not present, can be used same as nodeName, similarly if flowId can be used as same as flowName
       Parent ID is basically from which node is reply coming from.
    • outboundNodeData (JSON Object): Outgoing Message JSON Object with nodeId, nodeName, parentId, flowName and flowId as keys.
      nodeinfo = {
        "nodeId": "",       # Id for the node inside the flow which the message is generated by
        "nodeName": "",     # Name of the corresponding node
        "parentId": "",     # Id for the node after which the current Node is executed.
        "flowName": "",     # Name of the flow to which the message is related to
        "flowId": "",       # Id of the corresponding flow
        "sessionId": "",    # Unique session Id in which the current message is sent(Required only when either Method type is outbound)
    }
    • retryCount (Number): Maximum number of tries to send the request if it fails . Default value is 0.
    • methodType (String): The type of request that should be called. Available methodTypes are : 1. inbound 2. outbound 3. exchange (Inbound followed by outbound). Default value is exchange.

Example

#For Whatsapp channel
const oneDirectSDK = require("@gupshup-io/gupshup-onedirect").oneDirectSDK;

const whatsAppChannel = new oneDirectSDK({
    oneDirectBrandAuthToken: `xxxxxxxxx`,                        
    oneDirectBrandAccountMobileNumber: `+91xxxxxxx`,              
    oneDirectBrandAccountHostName: `xxxxx.xxxxxx.xxx`                   
}, {
    botName: `One Direct Module Test Bot`,
    botId: `678`,
    channelName: "WHATSAPP"
});

## Note : In case of outbound request, the sessionId needs to be passed in outboundNodeData as shown in example. 

## Inbound request

inboundMsgData = {incomingMsg: "Hi..!!",channelId: 29712813}
inboundNodeData =
    {
        nodeId: `inboundNode`,
        nodeName: `inboundNode`,
        parentId: null,
        flowName: `testflowIn`,
        flowId: `testflowIn`
    }
var inboundResponse = whatsAppChannel.captureEvent(inboundMsgData,inboundNodeData,null,5,"inbound")

## Outbound Request

outboundMsgData = {outgoingMsg: "What would you like to buy.?"}
outboundNodeData =
    {
        nodeId: `outboundNode`,
        nodeName: `outboundNode`,
        parentId: `inboundNode`,
        flowName: `testflowOut`,
        flowId: `testflowOut`,
        sessionId: 1234567          #Valid Session Id is required
    }
var outboundResponse = whatsAppChannel.captureEvent(outboundMsgData,null,outboundNodeData,5,"outbound")

## Both Inbound and Outbound

msgData = {incomingMsg: "Hi..!!", outgoingMsg: "What would you like to buy.?", channelId: 29712813}
inboundNodeData =
    {
        nodeId: `inboundNode`,
        nodeName: `inboundNode`,
        parentId: null,
        flowName: `testflowIn`,
        flowId: `testflowIn`
    }
outboundNodeData =
    {
        nodeId: `outboundNode`,
        nodeName: `outboundNode`,
        parentId: `inboundNode`,
        flowName: `testflowIn`,
        flowId: `testflowIn`,
    }
whatsAppChannel.captureEvent(msgData,inboundNodeData,outboundNodeData,5,"exchange");

2. Send Data to any other app using Queue

In order to send data to any other app using queue, we would need the following values-

  1. Bot Id : Unique Id for the bot through which the current message is sent
  2. Bot Name : Name of the corresponding bot.
  3. Channel Name : Channel through which message is being sent.
  4. RabbitMQ URL : Rabbit MQ Connection URL over which data is sent
  5. Exchange Name : Exchange name across which data is sent
  6. Routing Key : Routing Key acts as an address that exchange uses to decide where the data is sent

These above details need to passed in the constructor call shown as below:

Initialization

const SendDataByQueue = require("@gupshup-io/gupshup-onedirect").sendDataByQueue;
const sendDataByQueue = new SendDataByQueue(
                    {
                        channelName: ``                        # Channel through which message is being sent.
                    },
                    {
                        rabbitmqURL : `` ,                     # RabbitMQ Connection URL
                        exchange: ``,                          # Exchange Name
                        routingKey : ``,                       # Routing Key for the exchange
                    });

Methods

  • captureEvent : This method takes in the node details, message to be passed and channel id for both inbound and outbound requests and further executes the requests. The following are the parameters that need to be passed :

    • incomingMsg (String) : Message received from the user
    • outgoingMsg (String) : Message responded by the bot
    • channelId (Number): Unique Id for the channel in which the current message is exchanged
    • inboundNodeData (JSON Object) : Incoming Message JSON Object with nodeId, nodeName, parentId, flowName and flowId as keys.
       inboundNodeData = {
         "nodeId": "",   # Id for the node inside the flow which the message is generated by
         "nodeName": "", # Name of the corresponding node
         "parentId": "", # Id for the node after which the current Node is executed.
         "flowName": "", # Name of the flow to which the message is related to
         "flowId": "",   # Id of the corresponding flow
     }
      
       Flow will be the higher level entity and node will be entity within flow
       For example - `Menu` will be flow (Higher level) and `display_menu` will be a node
       Similarly `view_products` will be flow and `display_toothpaste`, `display_toothbrush`, `display_item3` will all be nodes.
       NodeId if not present, can be used same as nodeName, similarly if flowId can be used as same as flowName
       Parent ID is basically from which node is reply coming from.
    • outboundNodeData (JSON Object): Outgoing Message JSON Object with nodeId, nodeName, parentId, flowName and flowId as keys.
      nodeinfo = {
        "nodeId": "",       # Id for the node inside the flow which the message is generated by
        "nodeName": "",     # Name of the corresponding node
        "parentId": "",     # Id for the node after which the current Node is executed.
        "flowName": "",     # Name of the flow to which the message is related to
        "flowId": "",       # Id of the corresponding flow
    }
    • methodType (String): The type of request that should be called. Available methodTypes are :

                1. inbound
                2. outbound
                3. exchange (Inbound followed by outbound).
                Default value is exchange.
  • captureEventV2 : This method is used for sending multiple outgoing messages from bot to user. The following are the parameters that need to be passed :

    • inboundNodeData (JSON Object) : Incoming Message JSON Object with nodeId, nodeName, parentId, flowName and flowId as keys.
       inboundNodeData = {
         "incomingMsg": "",   # Message received from the user
         "channelId": "",     # Unique Id for the channel in which the current message is exchanged
         "nodeInfo" : {
             "nodeId": "",        # Id for the node inside the flow which the message is generated by
             "nodeName": "",      # Name of the corresponding node
             "parentId": "",      # Id for the node after which the current Node is executed.
             "flowName": "",      # Name of the flow to which the message is related to
             "flowId": "",        # Id of the corresponding flow
         }
     }
      
       Flow will be the higher level entity and node will be entity within flow
       For example - `Menu` will be flow (Higher level) and `display_menu` will be a node
       Similarly `view_products` will be flow and `display_toothpaste`, `display_toothbrush`, `display_item3` will all be nodes.
       NodeId if not present, can be used same as nodeName, similarly if flowId can be used as same as flowName
       Parent ID is basically from which node is reply coming from.
    • outboundNodeData (JSON Object): Array of Outgoing Message JSON Object with outgoingMsg, nodeId, nodeName, parentId, flowName and flowId as items in the JSON Object.
      outboundNodeData = [{
        "outgoingMsg": ""   # Message responded by the bot
        "nodeInfo": {
            "nodeId": "",       # Id for the node inside the flow which the message is generated by
            "nodeName": "",     # Name of the corresponding node
            "parentId": "",     # Id for the node after which the current Node is executed.
            "flowName": "",     # Name of the flow to which the message is related to
            "flowId": "",       # Id of the corresponding flow
        }
    }, ... ]
    • methodType (String): The type of request that should be called. Available methodTypes are :
      1. inbound
      2. outbound
      3. exchange (Inbound followed by outbound). Default value is exchange.

Example

## Inbound

inboundMsgData = {incomingMsg: "Hi..!!",channelId: 29712813}
inboundNodeData =
    {
        nodeId: `inboundNode`,
        nodeName: `inboundNode`,
        parentId: null,
        flowName: `testflowIn`,
        flowId: `testflowIn`
    }
whatsAppChannel.captureEvent(inboundMsgData,inboundNodeData,null,"inbound");

## Outbound

outboundMsgData = {outgoingMsg: "What would you like to buy.?"}
outboundNodeData =
    {
        nodeId: `outboundNode`,
        nodeName: `outboundNode`,
        parentId: `inboundNode`,
        flowName: `testflowOut`,
        flowId: `testflowOut`,
    }
whatsAppChannel.captureEvent(outboundMsgData,null,outboundNodeData,"outbound");

## Both Inbound and Outbound

msgData = {incomingMsg: "Hi..!!", outgoingMsg: "What would you like to buy.?", channelId: 29712813}
inboundNodeData =
    {
        nodeId: `inboundNode`,
        nodeName: `inboundNode`,
        parentId: null,
        flowName: `testflowIn`,
        flowId: `testflowIn`
    }
outboundNodeData =
    {
        nodeId: `outboundNode`,
        nodeName: `outboundNode`,
        parentId: `inboundNode`,
        flowName: `testflowIn`,
        flowId: `testflowIn`,
    }

whatsAppChannel.captureEvent(msgData,inboundNodeData,outboundNodeData,"exchange");


## Multiple outgoing messages for both inbound and outbound ## 
let inboundNodeData = {
    incomingMsg: "test incoming",
    channelId: "29712813"
    nodeInfo : {
        nodeId: `inboundNode`,
        nodeName: `inboundNode`,
        parentId: null,
        flowName: `testflowIn`,
        flowId: `testflowIn`
    }
}

let outboundNodeData = [
{
    outgoingMsg : "outgoing message 1"
    nodeInfo : {
        nodeId: `outboundNode1`,
        nodeName: `outboundNode1`,
        parentId: `inboundNode`,
        flowName: `testflowIn`,
        flowId: `testflowIn`,
    } 
},
{
    outgoingMsg : "outgoing message 2"
    nodeInfo : {
        nodeId: `outboundNode2`,
        nodeName: `outboundNode2`,
        parentId: `outboundNode1`,
        flowName: `testflowIn2`,
        flowId: `testflowIn2`,
    }
}
]

outbound messages will have their parent ID as their previous node

whatsAppChannel.captureEventV2(inboundNodeData,outboundNodeData,"exchange");

Data is sent in the form of an Object with keys inboundData and outboundData.

To listen to messages which are sent through rabbitmq, we would require an active consumer. Before publishing any messages, the consumer should be actively listening to incoming requests.

Note: 1. The sessionId and the one Direct Brand Account MobileNumber aren't present in the sent outbound and inbound data respectively. After consuming the data from the queue: * Add brand account to inbound Data * Add sessionId to outbound Data 2. The exchange across which data is shared should be durable

#Consumer

async function consumeMessage(consumer)
{
    const connection = await amqp.connect(rabbitmqURL);
    const channel = await connection.createChannel();
    await channel.assertExchange(exchange,'direct',{
        durable:false
    })
    
    const q = await channel.assertQueue('',{
        durable:false,autoDelete:true
    })

    channel.bindQueue(q.queue,exchange,consumer)

    console.log("[x]Awaiting messages in Consumer");
    channel.consume(q.queue,(msg)=>
    {
        var data = JSON.parse(msg.content)
        // console.log(data["inboundData"]);        Inbound Data
        // console.log(data["outboundData"]);       Outbound Data

        // var inboundDataObj = JSON.parse(data["inboundData"]);
        // inboundDataObj.brandAccount = oneDirectBrandAccountMobileNumber;   Adding brand account to inbound data

        // var outboundDataObj = JSON.parse(data["outboundData"]);
        // outboundDataObj.sessionId = sessionId;                             Adding session Id to outbound data

        console.log(data);
        setTimeout(()=>
        {
            connection.close();
            process.exit(0);
        },500); 

        channel.ack(msg);   
    },{ noAck : false });
}

consumeMessage(consumer)