dialogflow / dialogflow-fulfillment-nodejs

Dialogflow agent fulfillment library supporting v1&v2, 8 platforms, and text, card, image, suggestion, custom responses
Apache License 2.0
597 stars 282 forks source link

Dialogflow webhook duplicating intent call when calling a soap webservice, via promise #334

Open iaperez opened 3 years ago

iaperez commented 3 years ago

I'm building a Dialogflow Agent, that needs to call a soap webservice to create a case in a CRM. However, when trying to fulfill the intent, and when I call the await for the webservice promise, it seems to trigger a second call for the same intent, with the same context and the case ends up created twice. (i.e. two successful calls to the webservice, and duplicated cases)

It seems to be a bug while managing promises? My webhook looks something like this:

const CRMService = require('../services/crm/crm_soap');
    const { Suggestions} = require('actions-on-google');
    const { Suggestion } = require('dialogflow-fulfillment');

    module.exports = async function (agent) {
        agent.requestSource = agent.ACTIONS_ON_GOOGLE;
        let conv = agent.conv();

        let userContext = agent.context.get("usercontext");
        agent.context.set(userContext);

        if (userContext) {
            //doing something with the context...       
...

            let caseData = {
                userID: 'xxxxxxx',
                email: 'nee@nee.com',
                category: 'test'
            };

            try {
                let crmResponse;

                //this line triggers a second parallel call to the intent.
                crmResponse = await CRMService.createCaseWebCallback(caseData);
                campusCode = CRMService.getCampusCode(crmResponse)
                console.log('campusCode: ', campusCode)
            } catch (error) {
                console.log("id not found")
            }

           if (crmResponse['STATUS']==='1') {
                    conv.ask(`${name}: ` + ', case created.');

 ...

and the service function looks something like this:

   const soap = require('soap');
    const config = require('../../config');

    module.exports = {
        createCaseWebCallback: function (params, cb) {
            return new Promise ((resolve, reject) => {
                const args = params;
                const url_case = "http://xxx.ws?WSDL";
                soap.createClient(url_case, function (err, client) {
                    client.WM_createCase(args, function (err, result) {
                        return resolve(result["WM_createCaseResult"]);
                    });
                });
            });
        },

...