External Script calling external API - Timed out

Hello,

I have looked at a couple different example of how to call an external API using genieacs, I have even tried the one listed in the docs to get the lat/long of the ISS but all my checks keep coming back with time out.

For reference here is what the script should return when you give it an IP,

curl --location --request GET 'http://rancid.abccomm.com/tools/lte/api.php?ip=104.36.101.255'

Response:
{“ip_addr”:“104.36.foo.bar”,“IMSI”:“302425111112882”,“custom_ICCID”:“474544”,“PlatID”:null,“code”:“OK”}

Here is my code:

const getIMSI = ext("ipam_imsi","getIMSI", CPE_IP);

/opt/genieacs/ext/ipam_imsi.js

genieacs@acs:~$ cat /opt/genieacs/ext/ipam_imsi.js
var http = require("http");

function getIMSIfunc() {
  let IP = arguments[0];
  var options = {
    'method': 'GET',
    'hostname': 'rancid.abccomm.com',
    'path': '/tools/lte/api.php?ip=' + IP,
    'headers': {
    },
    'maxRedirects': 20
  };
var req = http.request(options, function (res) {
var chunks = [];

res.on("data", function (chunk) {
  chunks.push(chunk);
});

res.on("end", function (chunk) {
  var body = Buffer.concat(chunks);
  console.log(body.toString());
      var result = JSON.parse(body.toString());
      return result;
});
req.end();
res.on("error", function (error) {
  console.error(error);
 });
});
}
exports.getIMSI = getIMSIfunc;

I get this in my cwmp-access.log

Channel has faulted; channel="test" retries=0 faultCode="timeout" faultMessage="Extension timed out"

You are missing the callback. Try this:

var http = require("http");

function getIMSIfunc(args, callback) {
    let IP = args;
    var options = {
        'hostname': 'rancid.abccomm.com',
        'path': '/tools/lte/api.php?ip=' + IP,
        'headers': {
        },
        'maxRedirects': 20
    };
    var req = http.get(options, function (res) {
        var chunks = [];

        if (res.statusCode === 404) {
            return callback(null, null);
        }

        res.on("data", function (chunk) {
            chunks.push(chunk);
        });

        res.on("end", function (chunk) {
            var body = Buffer.concat(chunks);
            console.log(body.toString());
            var result = JSON.parse(body.toString());

            callback(null, result);
        });
    });


    req.on("error", function (err) {
        callback(err);
    });

}
exports.getIMSI = getIMSIfunc;

Thank you! I could’ve swore I tried the callback but maybe was using callback(result, null) instead. Either way it works now, thank you!

Hi @akcoder
I am also having a similar problem with my POST request to an external system.

/opt/genieacs/ext/addnewdev.js

"use strict";
var http = require("http");
var result = null;

function addDevSync(oui,modelname,serial,callback) {
    
    var options = {
      'method': 'POST',
      'hostname': '10.72.0.189',
      'port': 9111,
      'path': '/api/device/sync-and-merge',
      'headers': {
        'Content-Type': 'application/json'
      },
      'maxRedirects': 20
    };

    var req = http.request(options, function (res) {
      var chunks = [];

     if (res.statusCode !== 200)
        return callback(
          new Error(`Request failed (status code: ${res.statusCode})`)
        );

      res.on("data", function (chunk) {
        chunks.push(chunk);
      });

      res.on("end", function (chunk) {
        var body = Buffer.concat(chunks);
        console.log(body.toString());
        result = JSON.parse(body.toString());
        callback(null, result);
      });

      res.on("error", function (error) {
        callback(err);
      });
    });

    var postData = JSON.stringify({
      "serial": serial,
      "oui": oui,
      "modelName": modelname
    });

    req.write(postData);

    req.end();
}

exports.addDevSync = addDevSync;

Here is the provision script

let serial = declare("InternetGatewayDevice.DeviceInfo.SerialNumber", {value: 1});
let oui = declare("InternetGatewayDevice.DeviceInfo.ManufacturerOUI", {value: 1});
let modelname = declare("InternetGatewayDevice.DeviceInfo.ModelName", {value: 1});
log("Device ID is: "+oui.value[0] +"-"+modelname.value[0]+"-"+serial.value[0]);
ext("addnewdev", "addDevSync", oui.value[0], modelname.value[0], serial.value[0]);

When receiving an event from device, the provision script run, but it returned Timed out error

2023-01-07T04:52:24.339Z [INFO] ::ffff:10.72.203.192 xxxxxx-xxx-xxxxxx: Inform; cpeRequestId="16002" informEvent="0 BOOTSTRAP,1 BOOT" informRetryCount=0
2023-01-07T04:52:44.964Z [INFO] ::ffff:10.72.203.192 xxxxxx-xxx-xxxxxx: Script: Device ID is: xxxxxx-xxx-xxxxxx
2023-01-07T04:52:47.966Z [WARN] ::ffff:10.72.203.192 xxxxxx-xxx-xxxxxx: Channel has faulted; channel="bootstrap" retries=0 faultCode="timeout" faultMessage="Extension timed out"
2023-01-07T04:52:47.982Z [INFO] ::ffff:10.72.203.192 xxxxxx-xxx-xxxxxx: New device registered

Would you help to correct my extension script?
Thank you so much!

Did you find any solution? I’m having the same issue sometimes even external script ended successfully. I tried to increase EXT_TIMEOUT but still I get timeout error.