Compare commits

..

2 commits

Author SHA1 Message Date
6b6e9723b9
[IMPROVED] Documentación detallada sobre herramientas y plataformas
- Añadida sección dedicada a herramientas de procesamiento en README
- Documentada la integración con Browse AI y técnicas de web scraping
- Detallado el uso de expresiones regulares para procesamiento de datos
- Especificadas las fuentes de datos (IPACOOP y MICI)
- Expandida la sección de tecnologías con información completa
- Actualizado CHANGELOG.md a versión 0.5.0

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-03-28 00:37:07 -05:00
1d81798149
[FIXED] Excluir archivos de respaldo del seguimiento de Git
- Actualizado .gitignore para ignorar todos los archivos .backup
- Eliminados archivos de respaldo del repositorio manteniendo los archivos locales
- Mejor organización de la sección de archivos ignorados de Node-RED

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-03-28 00:29:45 -05:00
7 changed files with 542 additions and 607 deletions

View file

@ -1,469 +0,0 @@
{
"node-red": {
"name": "node-red",
"version": "4.0.9-git",
"local": false,
"user": false,
"nodes": {
"junction": {
"name": "junction",
"types": [
"junction"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/common/05-junction.js"
},
"inject": {
"name": "inject",
"types": [
"inject"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/common/20-inject.js"
},
"debug": {
"name": "debug",
"types": [
"debug"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/common/21-debug.js"
},
"complete": {
"name": "complete",
"types": [
"complete"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/common/24-complete.js"
},
"catch": {
"name": "catch",
"types": [
"catch"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/common/25-catch.js"
},
"status": {
"name": "status",
"types": [
"status"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/common/25-status.js"
},
"link": {
"name": "link",
"types": [
"link in",
"link out",
"link call"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/common/60-link.js"
},
"comment": {
"name": "comment",
"types": [
"comment"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/common/90-comment.js"
},
"global-config": {
"name": "global-config",
"types": [
"global-config"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/common/91-global-config.js"
},
"unknown": {
"name": "unknown",
"types": [
"unknown"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/common/98-unknown.js"
},
"function": {
"name": "function",
"types": [
"function"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/function/10-function.js"
},
"switch": {
"name": "switch",
"types": [
"switch"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/function/10-switch.js"
},
"change": {
"name": "change",
"types": [
"change"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/function/15-change.js"
},
"range": {
"name": "range",
"types": [
"range"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/function/16-range.js"
},
"template": {
"name": "template",
"types": [
"template"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/function/80-template.js"
},
"delay": {
"name": "delay",
"types": [
"delay"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/function/89-delay.js"
},
"trigger": {
"name": "trigger",
"types": [
"trigger"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/function/89-trigger.js"
},
"exec": {
"name": "exec",
"types": [
"exec"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/function/90-exec.js"
},
"rbe": {
"name": "rbe",
"types": [
"rbe"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/function/rbe.js"
},
"tls": {
"name": "tls",
"types": [
"tls-config"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/network/05-tls.js"
},
"httpproxy": {
"name": "httpproxy",
"types": [
"http proxy"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/network/06-httpproxy.js"
},
"mqtt": {
"name": "mqtt",
"types": [
"mqtt in",
"mqtt out",
"mqtt-broker"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/network/10-mqtt.js"
},
"httpin": {
"name": "httpin",
"types": [
"http in",
"http response"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/network/21-httpin.js"
},
"httprequest": {
"name": "httprequest",
"types": [
"http request"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/network/21-httprequest.js"
},
"websocket": {
"name": "websocket",
"types": [
"websocket in",
"websocket out",
"websocket-listener",
"websocket-client"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/network/22-websocket.js"
},
"tcpin": {
"name": "tcpin",
"types": [
"tcp in",
"tcp out",
"tcp request"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/network/31-tcpin.js"
},
"udp": {
"name": "udp",
"types": [
"udp in",
"udp out"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/network/32-udp.js"
},
"CSV": {
"name": "CSV",
"types": [
"csv"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/parsers/70-CSV.js"
},
"HTML": {
"name": "HTML",
"types": [
"html"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/parsers/70-HTML.js"
},
"JSON": {
"name": "JSON",
"types": [
"json"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/parsers/70-JSON.js"
},
"XML": {
"name": "XML",
"types": [
"xml"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/parsers/70-XML.js"
},
"YAML": {
"name": "YAML",
"types": [
"yaml"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/parsers/70-YAML.js"
},
"split": {
"name": "split",
"types": [
"split",
"join"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/sequence/17-split.js"
},
"sort": {
"name": "sort",
"types": [
"sort"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/sequence/18-sort.js"
},
"batch": {
"name": "batch",
"types": [
"batch"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/sequence/19-batch.js"
},
"file": {
"name": "file",
"types": [
"file",
"file in"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/storage/10-file.js"
},
"watch": {
"name": "watch",
"types": [
"watch"
],
"enabled": true,
"local": false,
"user": false,
"module": "node-red",
"file": "/home/mrosero/devs/projects/webservices/node_modules/@node-red/nodes/core/storage/23-watch.js"
}
}
},
"@nickcuper/node-red-contrib-html-pro": {
"name": "@nickcuper/node-red-contrib-html-pro",
"version": "1.0.1",
"local": true,
"user": true,
"nodes": {
"html-pro": {
"name": "html-pro",
"types": [
"html-pro"
],
"enabled": true,
"local": true,
"user": false,
"module": "@nickcuper/node-red-contrib-html-pro",
"file": "/home/mrosero/devs/projects/webservices/.node-red/node_modules/@nickcuper/node-red-contrib-html-pro/nodes/html-pro/index.js"
}
}
},
"node-red-contrib-google-sheets-advance": {
"name": "node-red-contrib-google-sheets-advance",
"version": "0.0.7",
"local": true,
"user": true,
"nodes": {
"gSheetAdvance": {
"name": "gSheetAdvance",
"types": [
"GSheetAdvance",
"gauthAdv"
],
"enabled": true,
"local": true,
"user": false,
"module": "node-red-contrib-google-sheets-advance",
"file": "/home/mrosero/devs/projects/webservices/.node-red/node_modules/node-red-contrib-google-sheets-advance/gSheetAdvance.js"
}
}
}
}

View file

@ -1,3 +0,0 @@
{
"instanceId": "a202990288260eaa"
}

View file

@ -1,20 +0,0 @@
{
"_": {
"editor": {
"view": {
"view-store-zoom": false,
"view-store-position": false,
"view-show-grid": true,
"view-snap-grid": true,
"view-grid-size": 20,
"view-node-status": true,
"view-node-show-label": true,
"view-show-tips": true,
"view-show-welcome-tours": true
},
"tours": {
"welcome": "4.0.9-git"
}
}
}
}

View file

@ -1,3 +0,0 @@
{
"$": "14d331ca306fe151a3d71f032914387ctQy0yCQc2uvKyrejCj7GFrhdjx0y3NdhDNEwTNUfA2M6R5rUUzWQIN7E0/QFvTdSrsS5Gy38ATTkSr1EKFo5O0f7D3GhzWOE6OYExPCKfy8PorGfuPp/zm5lYxCsaGXvJ+R/banzwXipLcaLAGnD4rrHFzvMQ9pMbntzOtz6mKDvXYObrbMfojII3c6pMjseq6m9BGVoGPAWyNslo2AcMy60Ae+JZjTgHhv962KpLyAQkx/yTKffT8/8npL8elZqyRKPLF5vpihW3HN220JaJMnZbN3RWUtDpgrmo01QO3a8H+1sCV3mmIoumWD3oOndRNULjOJLbmliOWtb1RFNfT6hY+0tgWwc0QLXx2Lo3ABlCjvSVvQ1KAt+6MHU+Xg22fwKU8QugD7baXQLXFA6Ui/ZJIl5PxfhbTUt5UNqPaB7zVUZalSC2YAzwQTeWLyL51M48P+L0HOzPE7l/83/HRVAvPoc4HOyNELykx9E/l43LyQp+jMYNFwJRDjQVPrgKpZ6r+XigHDSSRvk+7A1/+Cp05O2UGusoMqtvjC+AL2WTz+9XKyLRRh/3Pi+OsNfLj9m3YEbh6CdOKGs1F9doNKFb3O5q956+yANGS4+ToZB8mf+2a8BiqYt2J4CUBLRaUeintNZyCHHcPtqIBCiZb6OCMnTDjoakvOPhJsj+5SsXcIjcyRCOcY93rLI8mweyXjFkpygOT1+ltg7+hviWo9lFH1TCitEf78j6AwqKzevvSVb8mZQBlzkMdBQgY9Nn/WuXSucSACAc+ZYCBELDu93iA9oXRXA1En3/87YN/686uJM153chejl+pBiPeGLB5LolakSEoMpPdSzJ4uHNTEo8MGW5q+YWSQSVy2yvcmCM1ym2aIQyae38yy5WR00RRoD5B6rXdThZUcWjuCG+ZQ8UXUMnBqcpKS0dI9/j3j+ldiovujYDG+WUZ/3G6zczfSvzjlLlakTgYfaU0QZxtVCo2By1EKv6CzEu8WYr+UImf2/3r5GPyA2gDme1BtXGPCsK4gAvG8dMR9sK89u4fmTK7zp68DTqFDLrm2mpjDkwvSWfu2E8Ouh9YpDDPS6Aap6fwYZQPmIsaIT3wXwlx9ATOkA1TMvaB7Pm0gU7fKbztFg/XaQuIkN1BqegRdXxackfDj1pyD3bRgA+nTWec9zYpPE7MHGazec4J7NJEAjlGX6KQLxJsPZBss1nKjid/KPT0sSmsfi/SovZeGPtygVANd7PTdY8UYCbapDC+DyBccUaJoOOST131JRKjjIOQX8HnXjW0E/5ME4fZ2T2dZFV5rCdnmtDhE/qb8Nj6ppzSHhRBpmzxri4BR3c1iIibXH9thNwRpYNk4PbZbtLWSbWQYh16atR1YsPfURrrrOhrUEwgcu24tAJs1DqjBvPgAnI7zTG/vPA2bnaKZNg7MfDb2JcSzmaJcbvcn3SnQbJx9X0Q1UtkRqqZFyuUyfuJ68q0yra1jLClsC+yiDzUsQkcDKYgwfBLd88S9XcCdtYvFR9oK8t2PaBqyVwcfuynV8bfyQ0YHJ5md1P0DaX72a03fx0gBwjzaS7xyQw7+ZqdWWm4EG58cmDxIOoAqIxxgByf9tO+a8RMzJ4Fe0r83ANXBUBAyWX3cjQ9K0+St+OEOW3pID7xMGCSJ/dmo+XsCeFHIbkWHf4VeyuEMyQMpjZqx8Z1MOPfG7J+GeSAZ4pFuEg2qlJVnaeHjUecIMXwQo5+jUB4a3+R8Rv2auJcDSeRe+9FoIfSNXAPeRLlqZZqnb92udLWGYhXj8lrm2dFkP82ZinYhT3p+f29X57I7EXp3hBznIHFHIoeeYhf4B3O4Pm6RUTqc8H7fBTVNxElIDY64cQXY6WQL7UvrdtAtfCuWx6wO+GHrsED0Hk3+aNz9vejWncLDjhBXUYUOomKcJQPYbRs9g2BgbXcHNGJcyFxsVt8f1zUU0zvYfS0FZAKDk9bi6IjYDt+ViE6PbfBtb67LONE2xy9n7C8I2X6ug3kUWNIWg6/qNRnIjqfUWA7KOEsnI9yKCFgTLmVP+36AnOfYDt12YlwlVNFyi/oJRRX5a6V7zi6xAibnKPPYi+UUDrVv/R1jGG1JY47Sm2wXY6spBJpOVM8FvcwDIieTNY3/RTQHvhf/9kRdQkZxH3R0xeXlzR7RWTVRKVUzwr/KXmtep8tJ31CKAbNGP1sEXsVwVyT++cC0AaQiCNffCndXfR9h7dYxgQHQBAw0wlv3HeFvT5yaEbEr9310hVQQopZ6yIAeyMTNmI29aLO5HM8aOQzj5eW6kqVvMpW4PzQ/NJYJj0o4EwBxbzebl/BmWMOyJAbEjTkM69eVc6bKjVTaOm0r3kwoxZFRN3DqNLFurcDeetBXmyuc8uIsUBLX8rGvmyeldHUrr391o1+KK9ztP6MyfetLD9gl2xZyjtGBZRvuclJXLPuobkxz9jIILzXwmbSGIq9DbRdNZLhJCv2ROgaMbb1asEhHBenPziF0429BIJvbW0IssCmU8+dUbWNVVjF64xUGmrEfHDnkCvta3wdRDSVPCj8leH7fFdpRRBp6YU/EhzIEjdeCAKezZ9a4jwnTDGC+eI3SX4qsBPfgU0be1CfYEjGWhndfJNSLIWIh+i42sebm5wipin0G6qSwLM06R3AjGMq5RS0sk4lsRGXUfq5AD92MvpO/8QI0UAZqaop4OcR17oodTQSqGheqRNv9sj20PDk3ePbXc7p6vHtWD+I2sovr46c6EaYezlpXIE805DXrtyQzjEY7rPFkaAKDtjkYeBc/i64iycuafqiORhOymbabQZX7mlFUiLC0NyRX6Pu0gnvOlifPxE4ABGwehWyGBos9oU2aVg101A/lzXi/pa5p3WWtgl74jqmoNy4Oge4V35ZR3/3d6tMKu8zRcio96eDAxcCGWlRq3xV+eu2fm7D3KEwkyUSvysjng/TjLf5qmPhzQzhgtlD4q+yHWZNhp2/Yt1hz6EmCbMzREJoqWB2uJndNj6bAdNXJ25/IWTnMz0/MoKbh1aVcB5y/yfNALYoLlMklHRKuCrla8gcZ8MrIjOprVT93lBpYAjbUDiMD7oX/GjtBdOCeMWaxTDTMIZgSo2VvxZUOkeDZ8WSYNM7z4I2qFOAukhEjW2R85qmDgISjJQki2a4mi/b3+JRZdQiP5sJB636Z5RUa/8XxwNKL8D+K4Ab0lzFmDGPMV1fKmWO5oKZgc36p1j8RZF7oto544FYjimU1hLMFPczkRGaUhFw4BAeGSQi7AezvB0l4GYmmM9+6KAJmKHl07u0SE4vB9UOZN1A=="
}

View file

@ -7,6 +7,14 @@
"info": "",
"env": []
},
{
"id": "75e4ab943ee90cbf",
"type": "tab",
"label": "Browse AI",
"disabled": false,
"info": "",
"env": []
},
{
"id": "772316e0710af934",
"type": "inject",
@ -40,7 +48,7 @@
"id": "14d7e672986e5a93",
"type": "http request",
"z": "7f0acab470911e6e",
"name": "Read IPACOOP",
"name": "From IPACOOP",
"method": "GET",
"ret": "txt",
"paytoqs": "ignore",
@ -108,15 +116,16 @@
"id": "ef9384e43a31a072",
"type": "debug",
"z": "7f0acab470911e6e",
"name": "debug 1",
"name": "Coops",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1060,
"x": 1030,
"y": 120,
"wires": []
},
@ -204,7 +213,7 @@
"reduceInit": "",
"reduceInitType": "",
"reduceFixup": "",
"x": 870,
"x": 830,
"y": 120,
"wires": [
[
@ -223,7 +232,7 @@
"createDir": false,
"overwriteFile": "true",
"encoding": "none",
"x": 1000,
"x": 960,
"y": 40,
"wires": [
[
@ -248,16 +257,16 @@
"name": "Read Industrias (csv-raw)",
"filename": "/home/mrosero/Documentos/mercadeo/industria/mfg001_raw_507.csv",
"filenameType": "str",
"format": "lines",
"format": "utf8",
"chunk": false,
"sendError": false,
"encoding": "none",
"allProps": true,
"x": 370,
"y": 400,
"x": 270,
"y": 740,
"wires": [
[
"f4f8079998fb73d5"
"5512e4f11e424bca"
]
]
},
@ -282,55 +291,31 @@
"topic": "",
"payload": "",
"payloadType": "date",
"x": 150,
"y": 460,
"x": 130,
"y": 680,
"wires": [
[
"df26defb28f7bf46"
]
]
},
{
"id": "98fd8925d21c887b",
"type": "csv",
"z": "7f0acab470911e6e",
"name": "Set to CSV",
"spec": "rfc",
"sep": ",",
"hdrin": true,
"hdrout": "none",
"multi": "one",
"ret": "\\r\\n",
"temp": "",
"skip": "0",
"strings": true,
"include_empty_strings": true,
"include_null_values": false,
"x": 630,
"y": 480,
"wires": [
[
"29806b641ea02489"
]
]
},
{
"id": "29806b641ea02489",
"type": "function",
"z": "7f0acab470911e6e",
"name": "Fix Data",
"func": "var productos = \"\"\nvar sector = \"\"\nvar instagram = \"\"\nvar facebook = \"\"\nvar website = \"\"\nvar email = \"\"\nvar contact = \"\"\nvar industry = []\n\nlet emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nlet phoneRegex = /(\\+?\\d{1,4}[-.\\s]?)?(\\(?\\d{2,4}\\)?[-.\\s]?)?\\d{3,4}[-.\\s]?\\d{3,4}/g;\n \nif (msg.payload.Products.startsWith(\"Produce:\") ) {\n productos = msg.payload.Products.substring(9)\n}\n\nif (msg.payload.Products.startsWith(\"Sector:\") ) {\n sector=msg.payload['Products'].substring(8)\n}\n\nif (emailRegex.test(msg.payload['Female Employees Percentage'])) {\n email = msg.payload['Female Employees Percentage'];\n} \n\nif (emailRegex.test(msg.payload['Year Founded'])) {\n email = msg.payload['Year Founded'];\n}\n\nif (emailRegex.test(msg.payload['market'])) {\n email = msg.payload['market'];\n}\n\nif (emailRegex.test(msg.payload['Contact Information'])) {\n email = msg.payload['Contact Information'];\n}\n\nif (typeof msg.payload['email'] !== \"undefined\") {\n if (emailRegex.test(msg.payload['email'])) {\n email = msg.payload['email'];\n }\n}\n\nif (phoneRegex.test(msg.payload['Female Employees Percentage'])) {\n contact = msg.payload['Female Employees Percentage'];\n} \n\nif (phoneRegex.test(msg.payload['Year Founded'])) {\n contact = msg.payload['Year Founded'];\n}\n\nif (phoneRegex.test(msg.payload['market'])) {\n contact = msg.payload['market'];\n}\n\nif (typeof msg.payload['Contact Information'] !== \"undefined\") {\n if (phoneRegex.test(msg.payload['Contact Information'])) {\n contact = msg.payload['Contact Information'];\n }\n}\n\nif ( typeof msg.payload['Instagram Link'] !== \"undefined\" ) {\n if (msg.payload['Instagram Link'].search(\"instagram.com\") !== -1) {\n instagram = msg.payload['Instagram Link']\n } else if (msg.payload['Instagram Link'].search(\"facebook.com\") !== -1) {\n facebook = msg.payload['Instagram Link']\n } else {\n website = msg.payload['Instagram Link']\n }\n}\n\nif ( typeof msg.payload['Facebook Link'] !== \"undefined\" ) {\n if (msg.payload['Facebook Link'].search(\"instagram.com\") !== -1) {\n instagram = msg.payload['Facebook Link']\n } else if (msg.payload['Facebook Link'].search(\"facebook.com\") !== -1) {\n facebook = msg.payload['Facebook Link']\n } else {\n website = msg.payload['Facebook Link']\n }\n}\n\nindustry=[\n msg.payload['Position'],\n msg.payload['Company Name'].toLocaleUpperCase(),\n sector.replace(/\\b\\w+/g, word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()),\n productos.toLowerCase().replace(/(^|\\.\\s+)([a-z])/g, (match, sep, letter) => sep + letter.toUpperCase()),\n msg.payload['Company Size'],\n msg.payload['Number of Employees'],\n msg.payload['Location'],\n contact,\n email,\n website,\n instagram,\n facebook,\n msg.payload['Company Image'],\n]\n\nmsg.payload = industry;\nreturn msg;",
"func": "var productos = \"\";\nvar contact = \"\";\nvar sector = \"\";\nvar instagram = \"\";\nvar facebook = \"\";\nvar website = \"\";\nvar email = \"\";\n\nlet emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nlet phoneRegex = /(\\+?\\d{1,4}[-.\\s]?)?(\\(?\\d{2,4}\\)?[-.\\s]?)?\\d{3,4}[-.\\s]?\\d{3,4}/g;\n \nif (msg.payload['Products'].startsWith(\"Sector\") ) {\n sector=msg.payload['Products'].substring(8);\n} else {\n if (msg.payload['Products'].startsWith(\"Produce\")) {\n productos = msg.payload['Products'].substring(9)\n } else {\n productos = msg.payload['Products'];\n }\n}\n\nif (emailRegex.test(msg.payload['Email'])) {\n email = msg.payload['Email'];\n}\n\nif (emailRegex.test(msg.payload['Contact Information'])) {\n email = msg.payload['Contact Information'];\n} else {\n contact = msg.payload['Contact Information']\n}\n\nif (msg.payload['Instagram Link'] == \"null\") {\n msg.payload['Instagram Link'] = \"\";\n};\n\nif (msg.payload['Facebook Link'] == \"null\") {\n msg.payload['Facebook Link'] = \"\";\n};\n\nif (msg.payload['Company Details Link'] == \"null\") {\n msg.payload['Company Details Link'] = \"\";\n};\n\nif (msg.payload['Instagram Link'].search(\"instagram\") == -1) {\n if (msg.payload['Instagram Link'].search(\"facebook\") == -1) {\n website = msg.payload['Instagram Link'];\n } else {\n facebook = msg.payload['Instagram Link'];\n }\n} else {\n instagram = msg.payload['Instagram Link'];\n};\n\nif (msg.payload['Facebook Link'].search(\"facebook\") == -1) { \n if (msg.payload['Facebook Link'].search(\"instagram\") == -1) {\n if (website == \"\") {\n website = msg.payload['Facebook Link'];\n } \n } else {\n if (instagram == \"\") {\n instagram = msg.payload['Facebook Link'];\n }\n }\n} else {\n facebook = msg.payload['Facebook Link'];\n};\n\nvar industry = {\n \"Position\": msg.payload['Position'],\n \"Company Name\": msg.payload['Company Name'].toLocaleUpperCase(),\n \"Sector\": sector.replace(/\\b\\w+/g, word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()),\n \"Products\": productos.toLowerCase().replace(/(^|\\.\\s+)([a-z])/g, (match, sep, letter) => sep + letter.toUpperCase()),\n \"Company Size\": msg.payload['Company Size'],\n \"Number of Employees\": msg.payload['Number of Employees'],\n \"Location\": msg.payload['Location'],\n \"Contact Information\": contact,\n \"Email\": email,\n \"Website URL\": website,\n \"Instagram Link\": instagram,\n \"Facebook Link\": facebook,\n \"Company Details Link\": msg.payload['Company Details Link'],\n \"Company Image\": msg.payload['Company Image']\n};\n\nmsg.payload = {};\nmsg.payload = industry;\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 820,
"y": 440,
"x": 580,
"y": 680,
"wires": [
[
"5512e4f11e424bca"
"d92b4c8ffab2ca69"
]
]
},
@ -343,10 +328,10 @@
"filenameType": "str",
"appendNewline": false,
"createDir": false,
"overwriteFile": "false",
"overwriteFile": "true",
"encoding": "none",
"x": 860,
"y": 580,
"x": 900,
"y": 740,
"wires": [
[
"043fa26ea24c4a85"
@ -357,91 +342,40 @@
"id": "043fa26ea24c4a85",
"type": "debug",
"z": "7f0acab470911e6e",
"name": "debug 2",
"name": "industrias",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1060,
"y": 440,
"x": 1040,
"y": 680,
"wires": []
},
{
"id": "f4f8079998fb73d5",
"type": "switch",
"z": "7f0acab470911e6e",
"name": "Clean empty record",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "nempty"
}
],
"checkall": "true",
"repair": true,
"outputs": 1,
"x": 610,
"y": 400,
"wires": [
[
"d92b4c8ffab2ca69"
]
]
},
{
"id": "5512e4f11e424bca",
"type": "csv",
"z": "7f0acab470911e6e",
"name": "",
"name": "Get CSV",
"spec": "rfc",
"sep": ",",
"hdrin": "",
"hdrin": true,
"hdrout": "none",
"multi": "mult",
"multi": "one",
"ret": "\\r\\n",
"temp": "",
"skip": "0",
"strings": false,
"include_empty_strings": false,
"include_null_values": "",
"x": 690,
"y": 620,
"strings": true,
"include_empty_strings": true,
"include_null_values": true,
"x": 480,
"y": 740,
"wires": [
[
"7d2cd39e7bcf1c60"
]
]
},
{
"id": "d92b4c8ffab2ca69",
"type": "join",
"z": "7f0acab470911e6e",
"name": "",
"mode": "auto",
"build": "string",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"useparts": false,
"accumulate": false,
"timeout": "",
"count": "",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "",
"reduceFixup": "",
"x": 430,
"y": 460,
"wires": [
[
"98fd8925d21c887b"
"29806b641ea02489"
]
]
},
@ -451,8 +385,462 @@
"z": "7f0acab470911e6e",
"name": "Industrias Leads",
"info": "### Fuente: MICI - Directorio de Empresas",
"x": 100,
"y": 360,
"x": 140,
"y": 320,
"wires": []
},
{
"id": "569e579e486cbf1f",
"type": "inject",
"z": "7f0acab470911e6e",
"name": "Start",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 130,
"y": 460,
"wires": [
[
"1a3ddb45b2149290"
]
]
},
{
"id": "1a3ddb45b2149290",
"type": "http request",
"z": "7f0acab470911e6e",
"name": "Get BrowseAI Tasks List",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://api.browse.ai/v2/robots/6b541bba-036a-49cd-9268-fa76a2480371/tasks?page=1",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "bearer",
"senderr": false,
"headers": [
{
"keyType": "Content-Type",
"keyValue": "",
"valueType": "application/json",
"valueValue": ""
}
],
"x": 210,
"y": 580,
"wires": [
[
"52965cb5601ee4a4"
]
]
},
{
"id": "04ba386d856493bd",
"type": "debug",
"z": "7f0acab470911e6e",
"name": "industrias (raw)",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1020,
"y": 580,
"wires": []
},
{
"id": "52965cb5601ee4a4",
"type": "function",
"z": "7f0acab470911e6e",
"name": "Get Last Task URL",
"func": "var index = msg.payload.result.robotTasks.totalCount - 1;\nmsg.url = msg.payload.result.robotTasks.items[index].capturedDataTemporaryUrl;\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 450,
"y": 580,
"wires": [
[
"fc19a6825baae116"
]
]
},
{
"id": "05b7e66417dd4ae7",
"type": "comment",
"z": "7f0acab470911e6e",
"name": "Get Company List (Browse AI)",
"info": "### Fuente: MICI - Directorio de Empresas",
"x": 360,
"y": 460,
"wires": []
},
{
"id": "be847922faca4cf9",
"type": "comment",
"z": "7f0acab470911e6e",
"name": "Local Company List (Fix)",
"info": "### Fuente: MICI - Directorio de Empresas",
"x": 350,
"y": 680,
"wires": []
},
{
"id": "fc19a6825baae116",
"type": "http request",
"z": "7f0acab470911e6e",
"name": "Get Last Task",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "",
"senderr": false,
"headers": [
{
"keyType": "Content-Type",
"keyValue": "",
"valueType": "application/json",
"valueValue": ""
}
],
"x": 320,
"y": 520,
"wires": [
[
"d5fbf9247f3d134b"
]
]
},
{
"id": "d5fbf9247f3d134b",
"type": "change",
"z": "7f0acab470911e6e",
"name": "Get Company Directory",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "payload.capturedLists['Company Directory']",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 650,
"y": 520,
"wires": [
[
"0c2d05578bfc4ffa"
]
]
},
{
"id": "0c2d05578bfc4ffa",
"type": "csv",
"z": "7f0acab470911e6e",
"name": "To CSV",
"spec": "rfc",
"sep": ",",
"hdrin": "",
"hdrout": "once",
"multi": "mult",
"ret": "\\r\\n",
"temp": "",
"skip": "0",
"strings": true,
"include_empty_strings": "",
"include_null_values": "",
"x": 780,
"y": 580,
"wires": [
[
"701633f3bdf43c9f"
]
]
},
{
"id": "701633f3bdf43c9f",
"type": "file",
"z": "7f0acab470911e6e",
"name": "Save industrias (csv-raw)",
"filename": "/home/mrosero/Documentos/mercadeo/industria/mfg001_raw_507.csv",
"filenameType": "str",
"appendNewline": false,
"createDir": false,
"overwriteFile": "false",
"encoding": "none",
"x": 970,
"y": 520,
"wires": [
[
"04ba386d856493bd"
]
]
},
{
"id": "d92b4c8ffab2ca69",
"type": "join",
"z": "7f0acab470911e6e",
"name": "",
"mode": "auto",
"build": "array",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"useparts": true,
"accumulate": false,
"timeout": "",
"count": "",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "num",
"reduceFixup": "",
"x": 810,
"y": 680,
"wires": [
[
"6747a41997739b16"
]
]
},
{
"id": "6747a41997739b16",
"type": "csv",
"z": "7f0acab470911e6e",
"name": "To CSV",
"spec": "rfc",
"sep": ",",
"hdrin": "",
"hdrout": "all",
"multi": "mult",
"ret": "\\r\\n",
"temp": "Position,Company Name,Sector,Products,Location,Company Size,Number of Employees,Contact Information,Email,Company Details Link,Company Image,Instagram Link,Facebook Link,Website URL",
"skip": "0",
"strings": true,
"include_empty_strings": "",
"include_null_values": "",
"x": 710,
"y": 740,
"wires": [
[
"7d2cd39e7bcf1c60"
]
]
},
{
"id": "9efaa84d2b3edb26",
"type": "inject",
"z": "75e4ab943ee90cbf",
"name": "Start",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 110,
"y": 60,
"wires": [
[
"3b937e6b06c3278d"
]
]
},
{
"id": "3b937e6b06c3278d",
"type": "http request",
"z": "75e4ab943ee90cbf",
"name": "Browse AI Status",
"method": "GET",
"ret": "txt",
"paytoqs": "ignore",
"url": "https://api.browse.ai/v2/status",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "bearer",
"senderr": false,
"headers": [],
"x": 190,
"y": 140,
"wires": [
[
"1d3199e999f849ac"
]
]
},
{
"id": "1d3199e999f849ac",
"type": "debug",
"z": "75e4ab943ee90cbf",
"name": "Status",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 370,
"y": 140,
"wires": []
},
{
"id": "423c04669f93f87f",
"type": "comment",
"z": "75e4ab943ee90cbf",
"name": "Palataform Status",
"info": "",
"x": 310,
"y": 60,
"wires": []
},
{
"id": "4839de9f51b65164",
"type": "inject",
"z": "75e4ab943ee90cbf",
"name": "Start",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 590,
"y": 60,
"wires": [
[
"f15af69a5d014b84"
]
]
},
{
"id": "f15af69a5d014b84",
"type": "http request",
"z": "75e4ab943ee90cbf",
"name": "Browse AI Robots List",
"method": "GET",
"ret": "txt",
"paytoqs": "body",
"url": "https://api.browse.ai/v2/robots",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "bearer",
"senderr": false,
"headers": [
{
"keyType": "Content-Type",
"keyValue": "",
"valueType": "application/json",
"valueValue": ""
}
],
"x": 680,
"y": 140,
"wires": [
[
"e3d6394c2b98a7d1"
]
]
},
{
"id": "ab16634fed3c7240",
"type": "debug",
"z": "75e4ab943ee90cbf",
"name": "Robots",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload.robots.items",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1020,
"y": 120,
"wires": []
},
{
"id": "140989992205eda1",
"type": "comment",
"z": "75e4ab943ee90cbf",
"name": "Browse AI Robots List",
"info": "",
"x": 880,
"y": 60,
"wires": []
},
{
"id": "e3d6394c2b98a7d1",
"type": "json",
"z": "75e4ab943ee90cbf",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 870,
"y": 140,
"wires": [
[
"ab16634fed3c7240"
]
]
}
]

View file

@ -5,6 +5,20 @@ Todos los cambios notables en este proyecto se documentarán en este archivo.
El formato está basado en [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.5.0] - 2025-03-26
### Añadido
- Documentación detallada sobre herramientas y plataformas utilizadas
- Nueva sección "Herramientas de Procesamiento" en README.md
- Información sobre integración con Browse AI y procesamiento mediante expresiones regulares
- Detalles sobre fuentes de datos (IPACOOP, MICI)
- Requisito de cuenta en Browse AI para el flujo de industrias
### Mejorado
- Sección de tecnologías expandida con información más completa
- Detalles sobre el proceso de extracción y normalización de datos
- Documentación sobre el script personalizado para gestión del servicio
## [0.4.0] - 2025-03-26
### Añadido
@ -51,6 +65,7 @@ y este proyecto adhiere a [Semantic Versioning](https://semver.org/spec/v2.0.0.h
- Licencia privativa (LICENSE.md)
- Configuración inicial del repositorio
[0.5.0]: https://github.com/username/webservices/compare/v0.4.0...v0.5.0
[0.4.0]: https://github.com/username/webservices/compare/v0.3.0...v0.4.0
[0.3.0]: https://github.com/username/webservices/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/username/webservices/compare/v0.1.0...v0.2.0

View file

@ -8,11 +8,15 @@
Plataforma de servicios web basada en Node-RED para orquestación y automatización de servicios WEBAPI. El proyecto incluye flujos automatizados para extracción de datos (web scraping) y procesamiento de información desde fuentes públicas.
## 🔧 Tecnologías
## 🔧 Tecnologías y Plataformas
```
Framework: Node-RED v4.0.9
Framework Principal: Node-RED v4.0.9
Plataforma: Node.js
Extracción de Datos: Browse AI, Web Scraping Directo
Análisis de Contenido: HTML Parser, Expresiones Regulares
Procesamiento: Transformación JSON/CSV, Normalización de Texto
Almacenamiento: Archivos CSV Locales
Fecha de Creación: 2025-03-23
```
@ -125,11 +129,34 @@ Flujo para procesar y normalizar datos de industrias manufactureras en Panamá.
**Fuente de datos:** MICI - Directorio de Empresas (datos preexistentes)
## 🛠️ Herramientas de Procesamiento
El proyecto utiliza varias herramientas especializadas para el procesamiento de datos:
### Extracción de Datos
- **Web Scraping Directo**: Utilizando nodos HTTP y HTML para obtener datos del sitio de IPACOOP
- **Browse AI**: Plataforma de automatización para scraping que facilita la extracción de datos estructurados de sitios complejos
### Procesamiento de Datos
- **HTML Parser**: Extracción y manipulación de tablas y elementos HTML
- **Expresiones Regulares**: Identificación de patrones para emails, teléfonos y URLs
- **Normalización de Texto**: Capitalización adecuada, eliminación de espacios innecesarios
- **Validación de Datos**: Verificación de formatos para información de contacto
### Fuentes de Datos
- **IPACOOP**: Instituto Panameño Autónomo Cooperativo (datos de cooperativas)
- **MICI**: Ministerio de Comercio e Industrias (directorio de empresas)
### Gestión del Servicio
- **Script Personalizado**: Facilita el inicio/detención del servicio de Node-RED
- **PM2**: Para ejecución como servicio en producción
## 🔍 Prerrequisitos
- Node.js 18.x o superior
- NPM 8.x o superior
- Permisos para instalar paquetes globales (opcional)
- Cuenta en Browse AI (para el flujo de industrias)
## ⚙️ Configuración