waBotApiScripts top-level property

List<WaBotApiScript> waBotApiScripts
getter/setter pair

Implementation

List<WaBotApiScript> waBotApiScripts = [
  WaBotApiScript(
    file_name: ".gitignore",
    script: r"""
*
!.gitignore
""",
  ),
  WaBotApiScript(
    file_name: "package.json",
    script: json.encode(
      {
        "name": "whatsapp-bot-api",
        "version": "0.0.0",
        "description": "",
        "bin": "server.js",
        "main": "server.js",
        "scripts": {
          "test": "echo \"Error: no test specified\" && exit 1",
        },
        "keywords": [],
        "author": "https://github.com/azkadev",
        "license": "ISC",
        "dependencies": {
          "fastify": "^4.17.0",
          "glob": "^10.2.7",
          "node-fetch": "^2.6.0",
          "whatsapp_client": "^0.0.24",
        }
      },
    ),
  ),
  WaBotApiScript(
    file_name: "server.js",
    script: r"""
var { default: fastify } = require("fastify");
var { WhatsappClient, UpdateWa } = require("whatsapp_client");

var path = require('node:path');
var uri = require('node:url');
var fs = require("node:fs");
var { default: fetch } = require("node-fetch");
var { glob } = require("glob");


async function main() {
    var args = new Args();
    console.log("init wa");

    var app_name = args.after("--app_name") ?? "Whatsapp CLIENT FREE";
    var database_directory = args.after("--database_directory") ?? "./db_wa/";
    var host = args.after("--host") ?? "0.0.0.0";
    var port = args.after("--port") ?? 9990;

    if (!fs.existsSync(database_directory)) {
        fs.mkdirSync(database_directory);
    }


    var wa = new WhatsappClient({
        clientOption: {
            "app_name": app_name,
            "database_directory": path.join(database_directory, "client_0"),
            "database_key": "",
            "is_mobile_api": false,
            "print_qr_in_terminal": true,
        },
    });

    var app = fastify({
        "logger": false,
    });
    app.all("/", async function (req, res) {
        return res.send({
            "@type": "ok"
        });
    });

    app.all("/api", async function (req, res) {
        if (req.method.toLocaleLowerCase() != "post") {
            return res.status(400).send({
                "@type": "error"
            });
        }

        var query = req.query;
        var jsonData = {};

        try {
            jsonData = req.body;
        } catch (e) {
        }

        if (!jsonData) {
            return res.status(400).send({
                "@type": "error",
                "message": "data_must_be_json",
            });
        }

        try {

            var result_data = await handleUpdate({
                body: jsonData,
                query: query,
                wa: wa,
                database_directory: database_directory,
            });
            if (result_data) {
                if (result_data["@type"] == "error") {
                    return res.status(400).send(result_data);
                }
                return res.status(200).send(result_data);
            }
        } catch (e) {

            console.log(e);
            return res.status(500).send({
                "@type": "error",
                "message": "server_error_script"
            });
        }


        return res.status(404).send({
            "@type": "error",
            "message": "method_not_found"
        });


    });


    app.listen({
        "host": host,
        "port": port,
    });



    wa.on("update", async function (updateWa) {
        if (!updateWa.update_wa) {
            return;
        }
        if (!updateWa.update_wa.update) {
            return;
        }
        var update = updateWa.update_wa.update;
        if (!update) {
            return;
        }
        if (typeof update["@type"] != "string") {
            var events = update;
            if (events['creds.update']) {
            }
            if (events['connection.update']) {
                var update = events['connection.update'];
                var { connection, lastDisconnect, qr } = update;
                if (connection == "connecting") {

                    if (typeof updateWa.update_wa.waClient.count != "number") {
                        updateWa.update_wa.waClient.count = 0;
                    }
                    updateWa.update_wa.waClient.count += 1;

                    // console.log(JSON.stringify(updateWa.update_wa.waClient.msg_retry_count, null, 2));
                    return;
                }
            }

            // console.log(JSON.stringify(update, null, 2));
            return;
        }

        try {

            var waClientData = JSON.parse(fs.readFileSync(path.join(database_directory, `${path.basename(updateWa.update_wa.client_option.database_directory)}_client.json`), {
                "encoding": "utf8"
            }));
            if (waClientData["url"]) {
                await fetch(waClientData["url"], {
                    "method": "post",
                    "headers": {

                    },
                    "body": JSON.stringify(update),
                });
            } else if (updateWa.update_wa.client_option.url_webhook) {
                await fetch(updateWa.update_wa.client_option.url_webhook, {
                    "method": "post",
                    "headers": {

                    },
                    "body": JSON.stringify(update),
                });
            }
        } catch (e) {
            console.log(e);
        }



    });

    var files = await glob("*_client.json", {
        "cwd": database_directory,
        "nodir": true,
        "realpath": true,
    });
    for (var index = 0; index < files.length; index++) {
        var file_path = files[index];
        try {
            var res = JSON.parse(fs.readFileSync(path.join(database_directory, file_path), {
                "encoding": "utf8"
            }));

            await wa.initNewClient({
                clientOption: {
                    database_directory: path.join(database_directory, `${res["id"]}`),
                    database_key: res["key"],
                    "app_name": wa.whatsapp_client.client_option.app_name,
                    "print_qr_in_terminal": true,
                    "is_mobile_api": false,
                    "url_webhook": res["url"],
                }
            });
        } catch (e) {

        }
    }
}

async function handleUpdate({
    body = {
        "@type": ""
    },
    query = {

    },
    wa = new WhatsappClient(),
    database_directory = "",

}) {


    var method = body["@type"];
    var token = String(body["@token"]);
    var tokens = token.split(":");
    var waClientData = wa.getClient({
        id: function () {
            try {
                return tokens[0];
            } catch (e) {
                return "";

            }
        }(),
        key: function () {
            try {
                return tokens[1];
            } catch (e) {
                return "";

            }
        }(),
        is_from_client: false,
    });
    var waClient = waClientData["waClient"];

    if (RegExp("^(createClient)$", "i").test(method)) {
        if (typeof body["id"] != "string") {
            return {
                "@type": "error",
                "message": "id_must_format_string",
                "description": "Id must be string"
            };
        }
        if (!String(body["id"])) {
            return {
                "@type": "error",
                "message": "id_must_be_not_empty",
                "description": "Id must be not empty"
            };
        }
        if (!RegExp("^([a-z0-9_]+)$", "i").test(body["id"])) {
            return {
                "@type": "error",
                "message": "id_must_format_bad",
                "description": "Id Format must be [ a-z 0-9 _ ]"
            };
        }
        if (typeof body["url"] != "string") {
            return {
                "@type": "error",
                "message": "url_must_format_string",
                "description": "Url must be string"
            };
        }
        if (!String(body["url"])) {
            return {
                "@type": "error",
                "message": "url_must_be_not_empty",
                "description": "Url must be not empty"
            };
        }
        var id = String(body["id"]);
        var path_folder = path.join(database_directory, `${id}`);
        if (fs.existsSync(path_folder)) {
            return {
                "@type": "error",
                "description": "Please Create Other ID",
                "message": "client_exist",
            };
        }
        if (!fs.existsSync(database_directory)) {
            fs.mkdirSync(database_directory);
        }
        var url = String(body["url"]);
        var key = generateUuid();
        var new_token = `${id}:${key}`;
        var url_webhook = updateUrlQuery({
            url: url,
            query: {
                "token": new_token,
            },
        });
        var jsonData = {
            "@type": "clientData",
            "token": new_token,
            "url": url_webhook,
        };
        var jsonDataClient = {
            "id": id,
            "key": key,
            "token": new_token,
            "is_mobile_api": (body["is_mobile_api"] == true),
            "url": url_webhook,
        };
        fs.writeFileSync(path.join(database_directory, `${id}_client.json`), JSON.stringify(jsonDataClient, null, 2));
        wa.initNewClient({
            clientOption: {
                "app_name": wa.whatsapp_client.client_option.app_name,
                "database_directory": path_folder,
                "database_key": key,
                "print_qr_in_terminal": true,
                "is_mobile_api": (body["is_mobile_api"] == true),
                "url_webhook": url_webhook,
            }
        });
        return jsonData;
    }

    if (!token) {
        return {
            "@type": "error",
            "message": "token_must_be_not_empty"
        };
    }

    if (waClientData["@type"] == "error") {
        return waClientData;
    }
    if (RegExp("^(stopClient)$", "i").test(method)) {

        waClient.end();
        return {
            "@type": "ok",

        };
    }

    if (RegExp("^(getWebhook)$", "i").test(method)) {
        var waClientData = JSON.parse(fs.readFileSync(path.join(database_directory, `${path.basename(tokens[0])}_client.json`), {
            "encoding": "utf8",
        }));
        return {
            "@type": "waClientData",
            ...waClientData,
        };
    }

    if (RegExp("^(setWebhook)$", "i").test(method)) {
        if (typeof body["url"] != "string") {
            return {
                "@type": "error",
                "message": "url_must_format_string",
                "description": "Url must be string"
            };
        }

        if (!String(body["url"])) {
            return {
                "@type": "error",
                "message": "url_must_be_not_empty",
                "description": "Url must be not empty"
            };
        }

        var waClientData = JSON.parse(fs.readFileSync(path.join(database_directory, `${path.basename(tokens[0])}_client.json`), {
            "encoding": "utf8",
        }));
        waClientData["url"] = body["url"];
        fs.writeFileSync(path.join(database_directory, `${path.basename(tokens[0])}_client.json`), JSON.stringify(waClientData, null, 2));
        return {
            "@type": "ok",
        };
    }

    return await wa.invoke({
        method: method,
        parameters: body,
        waClient: waClient,
    });

}

function updateUrlQuery({
    url = "",
    query = {

    }
}) {
    var url_api = new URL(url);
    var search_params = new URLSearchParams(url_api.search);
    for (var key in query) {
        if (Object.hasOwnProperty.call(query, key)) {
            var element = query[key];
            search_params.set(key, element);
        }
    }
    url_api.search = search_params.toString()
    return decodeURIComponent(url_api.toString());

}

function generateUuid() {
    var hex = "0123456789abcdefghijklmnopqrstuvwxyz_-";
    var model = "AAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    var str = "";
    var bools = [
        true,
        false,
    ];
    for (var i = 0; i < model.length; i++) {
        var rnd = Math.floor(Math.random() * hex.length);
        var result = model[i] == "x" ? hex[rnd] : model[i];
        if (bools[Math.floor(Math.random() * bools.length)]) {
            str += result.toUpperCase();
        } else {
            str += result;
        }

    }
    return str;
}



class Args {
    constructor(args) {
        var result_args = [...process.argv];
        result_args.shift();
        result_args.shift();
        if (args) {
            result_args = args;
        }
        this.args = result_args;
    }

    after(key) {
        if (typeof key == "string") {
            for (var index = 0; index < this.args.length; index++) {
                var element = this.args[index];
                if (element == key) {
                    try {
                        return this.args[index + 1];
                    } catch (e) {
                        return null;
                    }
                }
            }
            return null;
        } else if (typeof key == "object") {
            return null;
        } else {
            return null;
        }
    }


    constains(key) {
        if (typeof key == "string") {
            return this.args.includes(key);
        } else if (typeof key == "object") {
            for (var index = 0; index < key.length; index++) {
                var element = key[index];

                if (this.args.includes(element)) {
                    return true;
                }

            }
            return false;
        } else {
            return false;
        }
    }

}
main();
""",
  ),
];