@@ -25,11 +25,6 @@ | |||||
"type": "json", | "type": "json", | ||||
"required": false | "required": false | ||||
}, | }, | ||||
"uuid": { | |||||
"type": "uid", | |||||
"targetField": "send_to", | |||||
"required": false | |||||
}, | |||||
"attachment": { | "attachment": { | ||||
"collection": "file", | "collection": "file", | ||||
"via": "related", | "via": "related", | ||||
@@ -47,6 +47,14 @@ | |||||
"config": { | "config": { | ||||
"policies": [] | "policies": [] | ||||
} | } | ||||
}, | |||||
{ | |||||
"method": "POST", | |||||
"path": "/initiate", | |||||
"handler": "session-data.initiate", | |||||
"config": { | |||||
"policies": [] | |||||
} | |||||
} | } | ||||
] | ] | ||||
} | } |
@@ -1,8 +1,67 @@ | |||||
'use strict'; | |||||
const messageModel = require("../../../model/messageModel"); | |||||
const { parseMultipartData, sanitizeEntity } = require("strapi-utils"); | |||||
const { Client } = require("whatsapp-web.js"); | |||||
/** | /** | ||||
* Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/controllers.html#core-controllers) | * Read the documentation (https://strapi.io/documentation/developer-docs/latest/concepts/controllers.html#core-controllers) | ||||
* to customize this controller | * to customize this controller | ||||
*/ | */ | ||||
module.exports = {}; | |||||
module.exports = { | |||||
initiate: async (ctx) => { | |||||
ctx.respond = false; | |||||
const { req, res } = ctx; | |||||
res.setHeader("Content-Type", "text/html; charset=UTF-8"); | |||||
res.setHeader("Transfer-Encoding", "chunked"); | |||||
res.writeHead(200); | |||||
messageModel.createNewClient(async function (data) { | |||||
// console.log(data); | |||||
var json = JSON.parse(data); | |||||
if (json["STATUS"] == 1 && json["TYPE"] == "READY") { | |||||
// console.log(json["DATA"]); | |||||
let checkExist = await strapi | |||||
.query("session-data") | |||||
.findOne({ phonenumber: json["DATA"].wid.user }); | |||||
if (checkExist) { | |||||
// messageModel.loadClient(async function(data){ | |||||
// let state = JSON.parse(data); | |||||
// if (state["STATUS"] == 1 && state["TYPE"] == "READY"){ | |||||
// let loaded = new Client(); | |||||
// loaded = state["DATA"]; | |||||
// await loaded.destroy(); | |||||
// } | |||||
// }); | |||||
let id = checkExist.id; | |||||
await strapi.services["session-data"].update({ id }, { | |||||
name:json["DATA"].pushname, | |||||
device_manufacturer:json["DATA"].phone.device_manufacturer, | |||||
device_model:json["DATA"].phone.device_model, | |||||
platform:json["DATA"].platform, | |||||
os_version:json["DATA"].phone.os_version, | |||||
phonenumber:json["DATA"].wid.user, | |||||
session_data:json["DATA"].sessionData, | |||||
}); | |||||
} | |||||
else { | |||||
await strapi.services["session-data"].create({ | |||||
name:json["DATA"].pushname, | |||||
device_manufacturer:json["DATA"].phone.device_manufacturer, | |||||
device_model:json["DATA"].phone.device_model, | |||||
platform:json["DATA"].platform, | |||||
os_version:json["DATA"].phone.os_version, | |||||
phonenumber:json["DATA"].wid.user, | |||||
session_data:json["DATA"].sessionData, | |||||
}); | |||||
// console.log(entry); | |||||
} | |||||
} | |||||
res.write(data); | |||||
if ( | |||||
json["STATUS"] == 0 || | |||||
(json["STATUS"] == 1 && json["TYPE"] == "READY") | |||||
) { | |||||
return res.end(); | |||||
} | |||||
}); | |||||
}, | |||||
}; |
@@ -0,0 +1,13 @@ | |||||
module.exports = { | |||||
// | |||||
graphql: { | |||||
endpoint: '/graphql', | |||||
shadowCRUD: true, | |||||
playgroundAlways: true, | |||||
depthLimit: 7, | |||||
amountLimit: 100, | |||||
apolloServer: { | |||||
tracing: false, | |||||
}, | |||||
}, | |||||
}; |
@@ -1,4 +1,4 @@ | |||||
'use strict'; | |||||
"use strict"; | |||||
/** | /** | ||||
* Cron config that gives you an opportunity | * Cron config that gives you an opportunity | ||||
@@ -11,11 +11,19 @@ | |||||
*/ | */ | ||||
module.exports = { | module.exports = { | ||||
/** | |||||
* Simple example. | |||||
* Every monday at 1am. | |||||
*/ | |||||
// '0 1 * * 1': () => { | |||||
// | |||||
// } | |||||
"*/3 * * * * *": async () => { | |||||
const draftArticleToPublish = await strapi.api.message.services.message.find( | |||||
{ | |||||
_sort: "send_from:desc", | |||||
state: "QUEUE", | |||||
} | |||||
); | |||||
draftArticleToPublish.forEach(async (message) => { | |||||
await strapi.api.message.services.message.update( | |||||
{ id: message.id }, | |||||
{ state: "SENT" } | |||||
); | |||||
}); | |||||
}, | |||||
}; | }; |
@@ -1,9 +1,10 @@ | |||||
module.exports = ({ env }) => ({ | module.exports = ({ env }) => ({ | ||||
host: env('HOST', '0.0.0.0'), | |||||
port: env.int('PORT', 1337), | |||||
admin: { | |||||
auth: { | |||||
secret: env('ADMIN_JWT_SECRET', 'f4b5b7ba9c157b7f1f921ee91be34b8a'), | |||||
}, | |||||
}, | |||||
host: env("HOST", "0.0.0.0"), | |||||
port: env.int("PORT", 1337), | |||||
admin: { | |||||
auth: { | |||||
secret: env("ADMIN_JWT_SECRET", "f4b5b7ba9c157b7f1f921ee91be34b8a"), | |||||
}, | |||||
}, | |||||
cron: { enabled: true }, | |||||
}); | }); |
@@ -0,0 +1,13 @@ | |||||
module.exports = { | |||||
apps : [{ | |||||
name: "strapi", | |||||
script: "index.js", | |||||
exec_mode: "fork", | |||||
env: { | |||||
"NODE_ENV": "development", | |||||
}, | |||||
env_production : { | |||||
"NODE_ENV": "production" | |||||
} | |||||
}] | |||||
}; |
@@ -0,0 +1,4 @@ | |||||
const strapi = require("strapi"); | |||||
console.log("test starting script"); | |||||
strapi(/* {...} */).start(); |
@@ -0,0 +1,218 @@ | |||||
const qrcode = require("qrcode-terminal"); | |||||
const fs = require("fs"); | |||||
// const path = require("path"); | |||||
const { Client } = require("whatsapp-web.js"); | |||||
// const SESSION_FOLDER = path.join(__dirname, "../data/"); | |||||
// const SESSION_FILE_PATH = path.join(__dirname, "../data/session.json"); | |||||
// const sessions = require("../api/session_data"); | |||||
const { parseMultipartData, sanitizeEntity } = require("strapi-utils"); | |||||
var client; | |||||
//Login Session when there is Session File | |||||
function callbacks(client, callback,type="create") { | |||||
let sessionData; | |||||
client.on("auth_failure", (session) => { | |||||
console.log("auth_failure"); | |||||
// clearFileSession(phoneNumber); | |||||
return callback( | |||||
JSON.stringify({ | |||||
STATUS: 0, | |||||
TYPE: "AUTH_FAILURE", | |||||
DATA: "SESSION HAS BEEN ENDED , PLEASE CREATE A NEW ONE !", | |||||
}) | |||||
); | |||||
}); | |||||
client.on("disconnected", async function (session) { | |||||
console.log("disconnected from loading"); | |||||
if (session == "UNPAIRED") { | |||||
try { | |||||
if (client && client.info) { | |||||
getID = await strapi | |||||
.query("session-data") | |||||
.findOne({ phonenumber: client.info.wid.user }); | |||||
if (getID) { | |||||
let id = getID["id"]; | |||||
await strapi.query("session-data").delete({ id }); | |||||
} | |||||
} | |||||
} catch (e) {} | |||||
} | |||||
}); | |||||
client.on("ready", () => { | |||||
var clientInfo = client.info; | |||||
clientInfo["sessionData"] = sessionData; | |||||
return callback( | |||||
JSON.stringify({ | |||||
STATUS: 1, | |||||
TYPE: "READY", | |||||
DATA: (type=="create")?clientInfo:client, | |||||
}) | |||||
); | |||||
}); | |||||
client.on("message", async (msg) => { | |||||
console.log("MESSAGE RECEIVED", msg.body); | |||||
}); | |||||
client.on("qr", (qr) => { | |||||
return callback( | |||||
JSON.stringify({ STATUS: 1, TYPE: "QR_AUTH", DATA: qr }) | |||||
); | |||||
}); | |||||
client.on("change_state", (state) => { | |||||
console.log(`state => ${state}`); | |||||
}); | |||||
client.on("authenticated", (session) => { | |||||
try { | |||||
sessionData = session; | |||||
// fs.writeFileSync(SESSION_FILE_PATH, JSON.stringify(session)); | |||||
} catch (e) { | |||||
return callback( | |||||
JSON.stringify({ | |||||
STATUS: 0, | |||||
TYPE: "AUTHENTICATED_ERROR", | |||||
DATA: e.message, | |||||
}) | |||||
); | |||||
} | |||||
}); | |||||
} | |||||
var loadClient = async function (clientSessionData, callback) { | |||||
try { | |||||
// if(!client){ | |||||
// console.log(client.info); | |||||
// return callback({"STATUS" : 1 , "TYPE" : "READY" , "DATA" : client.info}) | |||||
// } | |||||
// let sessionPath = path.join(SESSION_FOLDER, `${phoneNumber}.json`); | |||||
// if (fs.existsSync(sessionPath)) { | |||||
// sessionData = require(sessionPath); | |||||
client = new Client({ | |||||
puppeteer: { | |||||
args: ["--no-sandbox", "--disable-setuid-sandbox"], | |||||
}, | |||||
session: clientSessionData, | |||||
restartOnAuthFail: true, | |||||
}); | |||||
callbacks(client, callback,"load"); | |||||
console.log("initialize"); | |||||
client.initialize(); | |||||
} catch (e) { | |||||
return callback({ | |||||
STATUS: 0, | |||||
TYPE: "ERROR", | |||||
DATA: e.message, | |||||
}); | |||||
} | |||||
}; | |||||
var createNewClient = async function (callback) { | |||||
try { | |||||
client = new Client({ | |||||
puppeteer: { | |||||
args: ["--no-sandbox", "--disable-setuid-sandbox"], | |||||
}, | |||||
}); | |||||
callbacks(client, callback); | |||||
client.initialize(); | |||||
//var clientInfo = await getClientInfo(); | |||||
//return clientInfo; | |||||
} catch (e) { | |||||
return callback({ STATUS: 0, TYPE: "READY", DATA: e.message }); | |||||
} | |||||
}; | |||||
var sendMessage = async function (phone_number, textMessage) { | |||||
try { | |||||
if (!client.info) { | |||||
throw { message: "Client Is Not Ready !" }; | |||||
} | |||||
var phoneNumber = reformatMobilePhone(phone_number); | |||||
// var state = await client.isRegisteredUser(phoneNumber); | |||||
// console.log(state); | |||||
await client.sendMessage(phoneNumber, textMessage); | |||||
return { STATUS: 1, DATA: "Messages Succesfully send !" }; | |||||
} catch (e) { | |||||
return { STATUS: 0, DATA: e.message }; | |||||
} | |||||
}; | |||||
var getClientInfo = function () { | |||||
try { | |||||
var a; | |||||
while (!a) { | |||||
a = client.info; | |||||
} | |||||
return { STATUS: 1, DATA: a }; | |||||
} catch (e) { | |||||
return { STATUS: 0, DATA: e.message }; | |||||
} | |||||
}; | |||||
var getClientState = async function () { | |||||
try { | |||||
if (!client.info) { | |||||
throw { message: "Client Is Not Ready !" }; | |||||
} | |||||
let state = await client.getState(); | |||||
return { STATUS: 1, DATA: state }; | |||||
} catch (e) { | |||||
return { STATUS: 0, DATA: e.message }; | |||||
} | |||||
}; | |||||
var destroySession = async function (phoneNumber) { | |||||
try { | |||||
if (client && client.info) { | |||||
await client.logout(); | |||||
await client.destroy(); | |||||
clearFileSession(phoneNumber); | |||||
return { STATUS: 1, DATA: "Session cleared" }; | |||||
} else throw { message: "Client Is Not Ready !" }; | |||||
} catch (e) { | |||||
return { STATUS: 0, DATA: e.message }; | |||||
} | |||||
}; | |||||
function reformatMobilePhone(phoneNumber) { | |||||
var newPhoneNumber; | |||||
if (phoneNumber[0].toString() == "0") { | |||||
newPhoneNumber = "62" + phoneNumber.substring(1) + "@c.us"; | |||||
} else if (phoneNumber[0] == "+") { | |||||
newPhoneNumber = phoneNumber.substring(1) + "@c.us"; | |||||
} else { | |||||
newPhoneNumber = phoneNumber + "@c.us"; | |||||
} | |||||
return newPhoneNumber; | |||||
} | |||||
function clearFileSession(phoneNumber) { | |||||
try { | |||||
let sessionPath = path.join(SESSION_FOLDER, `${phoneNumber}.json`); | |||||
if (fs.existsSync(sessionPath)) { | |||||
console.log(`clearing session ${phoneNumber}`); | |||||
fs.unlinkSync(sessionPath); | |||||
} | |||||
} catch (e) { | |||||
throw e; | |||||
} | |||||
} | |||||
module.exports = { | |||||
sendMessage: sendMessage, | |||||
createNewClient: createNewClient, | |||||
loadClient: loadClient, | |||||
getClientInfo: getClientInfo, | |||||
destroySession: destroySession, | |||||
getClientState: getClientState, | |||||
getClientState: getClientState, | |||||
}; |
@@ -13,6 +13,7 @@ | |||||
"dependencies": { | "dependencies": { | ||||
"knex": "<0.20.0", | "knex": "<0.20.0", | ||||
"mysql": "latest", | "mysql": "latest", | ||||
"qrcode-terminal": "^0.12.0", | |||||
"strapi": "3.4.1", | "strapi": "3.4.1", | ||||
"strapi-admin": "3.4.1", | "strapi-admin": "3.4.1", | ||||
"strapi-connector-bookshelf": "3.4.1", | "strapi-connector-bookshelf": "3.4.1", | ||||
@@ -22,7 +23,8 @@ | |||||
"strapi-plugin-graphql": "3.4.1", | "strapi-plugin-graphql": "3.4.1", | ||||
"strapi-plugin-upload": "3.4.1", | "strapi-plugin-upload": "3.4.1", | ||||
"strapi-plugin-users-permissions": "3.4.1", | "strapi-plugin-users-permissions": "3.4.1", | ||||
"strapi-utils": "3.4.1" | |||||
"strapi-utils": "3.4.1", | |||||
"whatsapp-web.js": "^1.12.0" | |||||
}, | }, | ||||
"author": { | "author": { | ||||
"name": "A Strapi developer" | "name": "A Strapi developer" | ||||