Browse Source

strapi

master
jefry 4 years ago
parent
commit
e5b9508379
11 changed files with 776 additions and 261 deletions
  1. +0
    -5
      api/message/models/message.settings.json
  2. +8
    -0
      api/session-data/config/routes.json
  3. +62
    -3
      api/session-data/controllers/session-data.js
  4. +13
    -0
      config/config.js
  5. +16
    -8
      config/functions/cron.js
  6. +8
    -7
      config/server.js
  7. +13
    -0
      ecosystem.config.js
  8. +4
    -0
      index.js
  9. +218
    -0
      model/messageModel.js
  10. +3
    -1
      package.json
  11. +431
    -237
      yarn.lock

+ 0
- 5
api/message/models/message.settings.json View File

@@ -25,11 +25,6 @@
"type": "json",
"required": false
},
"uuid": {
"type": "uid",
"targetField": "send_to",
"required": false
},
"attachment": {
"collection": "file",
"via": "related",


+ 8
- 0
api/session-data/config/routes.json View File

@@ -47,6 +47,14 @@
"config": {
"policies": []
}
},
{
"method": "POST",
"path": "/initiate",
"handler": "session-data.initiate",
"config": {
"policies": []
}
}
]
}

+ 62
- 3
api/session-data/controllers/session-data.js View File

@@ -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)
* 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();
}
});
},
};

+ 13
- 0
config/config.js View File

@@ -0,0 +1,13 @@
module.exports = {
//
graphql: {
endpoint: '/graphql',
shadowCRUD: true,
playgroundAlways: true,
depthLimit: 7,
amountLimit: 100,
apolloServer: {
tracing: false,
},
},
};

+ 16
- 8
config/functions/cron.js View File

@@ -1,4 +1,4 @@
'use strict';
"use strict";

/**
* Cron config that gives you an opportunity
@@ -11,11 +11,19 @@
*/

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" }
);
});
},
};

+ 8
- 7
config/server.js View File

@@ -1,9 +1,10 @@
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 },
});

+ 13
- 0
ecosystem.config.js View File

@@ -0,0 +1,13 @@
module.exports = {
apps : [{
name: "strapi",
script: "index.js",
exec_mode: "fork",
env: {
"NODE_ENV": "development",
},
env_production : {
"NODE_ENV": "production"
}
}]
};

+ 4
- 0
index.js View File

@@ -0,0 +1,4 @@
const strapi = require("strapi");

console.log("test starting script");
strapi(/* {...} */).start();

+ 218
- 0
model/messageModel.js View File

@@ -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,
};

+ 3
- 1
package.json View File

@@ -13,6 +13,7 @@
"dependencies": {
"knex": "<0.20.0",
"mysql": "latest",
"qrcode-terminal": "^0.12.0",
"strapi": "3.4.1",
"strapi-admin": "3.4.1",
"strapi-connector-bookshelf": "3.4.1",
@@ -22,7 +23,8 @@
"strapi-plugin-graphql": "3.4.1",
"strapi-plugin-upload": "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": {
"name": "A Strapi developer"


+ 431
- 237
yarn.lock
File diff suppressed because it is too large
View File


Loading…
Cancel
Save