Skip to content

Commit

Permalink
Merge branch 'developClientDiscord' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
MathieuSchl committed Sep 23, 2023
2 parents b05d5be + 5ebefba commit 8e07bb9
Show file tree
Hide file tree
Showing 11 changed files with 347 additions and 32 deletions.
42 changes: 38 additions & 4 deletions .github/workflows/client_discord-dockerPush.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,46 @@ jobs:
- name: Check out repository code
uses: actions/checkout@v3
- name: Install dependencies
working-directory: ./clientDiscord
run: |
cd clientDiscord/ && npm install
- name: Create summary
npm install
- name: Run tests and create summary
id: tests
continue-on-error: true
working-directory: ./clientDiscord
run: |
cd clientDiscord/ && export NODE_OPTIONS=--no-experimental-fetch && npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt
awk 'NR>5' /tmp/coverage0.txt > /tmp/coverage1.txt && sed '$ d' /tmp/coverage1.txt > $GITHUB_STEP_SUMMARY && echo -e "" >> $GITHUB_STEP_SUMMARY && cat /tmp/results.txt >> $GITHUB_STEP_SUMMARY
export NODE_OPTIONS=--no-experimental-fetch && npm test 2>> /tmp/results.txt >> /tmp/coverage0.txt
- name: Prepare data
id: data
run: |
awk 'NR>5' /tmp/coverage0.txt > /tmp/coverage1.txt
echo "embeds=[{\"type\":\"rich\",\"title\":\"$(grep -q "failed" /tmp/results.txt && echo "❌ Errors with the test [CLIENT_DISCORD]" || echo "✅ All test are checked [CLIENT_DISCORD]")\",\"description\":\"**Test client discord result:**\n$(tail -n 5 /tmp/results.txt | tr '\n' "&" | sed 's/&/\\n/g')\n**Coverage :**\",\"color\":$(grep -q "failed" /tmp/results.txt && echo 16525609 || echo 38912),\"fields\":[{\"name\":\"**Statements**\",\"value\":\"$(grep 'All files' /tmp/coverage0.txt | cut -d '|' -f 2 | tr -d ' ')%\",\"inline\":true},{\"name\":\"**Branches**\",\"value\":\"$(grep 'All files' /tmp/coverage0.txt | cut -d '|' -f 3 | tr -d ' ')%\",\"inline\":true},{\"name\":\"**Functions**\",\"value\":\"$(grep 'All files' /tmp/coverage0.txt | cut -d '|' -f 4 | tr -d ' ')%\",\"inline\":true},{\"name\":\"**Lines**\",\"value\":\"$(grep 'All files' /tmp/coverage0.txt | cut -d '|' -f 5 | tr -d ' ')%\",\"inline\":true}]}]" >> "$GITHUB_OUTPUT"
- name: ERROR Send coverage to discord
uses: Ilshidur/action-discord@master
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
DISCORD_USERNAME: GitHub
DISCORD_AVATAR: https://cdn.discordapp.com/avatars/1138225091528904714/df91181b3f1cf0ef1592fbe18e0962d7.webp?size=100
DISCORD_EMBEDS: ${{ steps.data.outputs.embeds }}

- name: Echo errors
if: steps.tests.outcome == 'failure'
run: |
sed '$ d' /tmp/coverage1.txt > $GITHUB_STEP_SUMMARY
echo -e "\n" >> $GITHUB_STEP_SUMMARY
cat /tmp/results.txt >> $GITHUB_STEP_SUMMARY
echo -e "\n" >> $GITHUB_STEP_SUMMARY
echo "❌ Errors with the test" >> $GITHUB_STEP_SUMMARY
exit 1
- name: Echo success
if: steps.tests.outcome == 'success'
run: |
echo -e "\n" >> $GITHUB_STEP_SUMMARY
sed '$ d' /tmp/coverage1.txt > $GITHUB_STEP_SUMMARY
cat /tmp/results.txt >> $GITHUB_STEP_SUMMARY
echo -e "\n" >> $GITHUB_STEP_SUMMARY
echo "✅ All test are checked" >> $GITHUB_STEP_SUMMARY
Build_Push:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion clientDiscord/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: "3"
services:
karassistant-client-discord:
#build: .
image: codyisthesenate/karassistant-client-discord:1.0.1
image: codyisthesenate/karassistant-client-discord:1.1.1
restart: always
container_name: karassistant-client-discord
volumes:
Expand Down
54 changes: 52 additions & 2 deletions clientDiscord/events/ready.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,59 @@
const { Events } = require("discord.js");
let timeout = 1000;

function randomIntFromInterval(min, max) {
// min and max included
return Math.floor(Math.random() * (max - min + 1) + min);
}

async function activity(client) {
const randomActivity = randomIntFromInterval(0, 25);
switch (randomActivity) {
case 0:
client.user.setActivity("My name is Karoline");
timeout = randomIntFromInterval(60, 120) * 1000;
break;

case 1:
client.user.setActivity("My name is Glados");
timeout = randomIntFromInterval(60, 120) * 1000;
break;

case 2:
client.user.setActivity("My name is Connor");
timeout = randomIntFromInterval(60, 120) * 1000;
break;

case 3:
client.user.setActivity("My name is Marcus");
timeout = randomIntFromInterval(60, 120) * 1000;
break;

case 4:
client.user.setActivity("My name is Car (Tut tut)");
timeout = randomIntFromInterval(60, 120) * 1000;
break;

default:
client.user.setActivity("My name is Kara");
timeout = randomIntFromInterval(300, 3600) * 1000;
break;
}
return;
}

module.exports.run = async (client) => {
client.on(Events.ClientReady, () => {
client.on(Events.ClientReady, async () => {
console.log(`Logged in as ${client.user.tag} !\n`);

client.user.setActivity("My name is Kara");
await activity(client);
while (true) {
await new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, timeout);
});
await activity(client);
}
});
};
15 changes: 15 additions & 0 deletions clientDiscord/events/userUpdate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const { Events } = require("discord.js");
const updateUser = require("../utils/updateUser").updateUser;

module.exports.run = async (client) => {
client.on(Events.UserUpdate, (oldUser, newUser) => {
const userName = newUser.username;
const userId = newUser.id;
const oldAvatar = oldUser.avatar;
const newAvatar = newUser.avatar;
if (oldAvatar !== newAvatar) {
const avatarUrl = newAvatar ? `https://cdn.discordapp.com/avatars/${userId}/${newAvatar}.webp` : null;
updateUser({ userName: userName, userId: userId, data: { discordAvatarUrl: avatarUrl } });
}
});
};
7 changes: 6 additions & 1 deletion clientDiscord/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ async function start() {

const TOKEN = process.env.DISCORD_TOKEN;
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.DirectMessages],
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildPresences,
GatewayIntentBits.DirectMessages,
],
partials: [
Partials.Channel, // Required to receive DMs
],
Expand Down
2 changes: 1 addition & 1 deletion clientDiscord/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "clientdiscord",
"version": "1.0.1",
"version": "1.1.1",
"description": "A discord bot for KarAssistant",
"main": "index.js",
"scripts": {
Expand Down
13 changes: 13 additions & 0 deletions clientDiscord/utils/RSA.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const NodeRSA = require("node-rsa");

module.exports.encryptData = encryptData;
async function encryptData({ data, publicKey }) {
try {
const keyPublic = new NodeRSA(publicKey);
data.date = new Date().toUTCString();
const passPhraseEncrypted = keyPublic.encrypt(JSON.stringify(data), "base64");
return passPhraseEncrypted;
} catch {
return null;
}
}
39 changes: 37 additions & 2 deletions clientDiscord/utils/getPassPhrase.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,35 @@ async function createNewClient({ authautifierTag }) {
});
}

async function encryptPassPhrase({ clientToken, publicKey }) {
module.exports.updateUser = updateUser;
async function updateUser({ data, clientToken }) {
return await new Promise((resolve, reject) => {
api({
method: "PUT",
headers: { "Content-Type": "application/json", karaeatcookies: clientToken },
params: {
data,
},
data,
url: process.env.BACK_URL + "/api/user",
})
.then(function (response) {
if (response.status !== 200) throw "Create new client status : " + response.status;

return resolve(true);
})
.catch(function (error) {
if (error.code === "ECONNREFUSED") resolve({ err: "Access to the Kara server cannot be established" });
if (error.response && error.response.status === 403) resolve({ err: "Access to the Kara server is forbidden" });
else {
console.log(error);
resolve({ err: error.code });
}
});
});
}

async function encryptData({ clientToken, publicKey }) {
try {
const keyPublic = new NodeRSA(publicKey);
const passPhrase = clientToken + ";" + new Date().toISOString();
Expand Down Expand Up @@ -66,12 +94,19 @@ module.exports.getPassPhrase = async ({ userId, userName, avatarUrl }) => {
publicKey: newClient.publicKey,
};
fs.writeFileSync(__dirname + "/../data/clients/" + userId + ".json", JSON.stringify(userData));

resolve(newClient);
}
});
if (err) return { err };

const passPhraseEncrypted = await encryptPassPhrase({ clientToken, publicKey });
const passPhraseEncrypted = await encryptData({ clientToken, publicKey });
if (!userExist)
updateUser({
data: { discordAvatarUrl: avatarUrl },
clientToken: clientToken,
passPhrase: passPhraseEncrypted,
});

return { clientToken, passPhrase: passPhraseEncrypted };
};
49 changes: 28 additions & 21 deletions clientDiscord/utils/heyKara.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,17 @@ const api = axios.create({
serialize: stringify, // or (params) => Qs.stringify(params, {arrayFormat: 'brackets'})
},
});
const getPassPhrase = require("./getPassPhrase").getPassPhrase;
const prepareRequest = require("./prepareRequest").prepareRequest;
const decryptResult = require("./prepareRequest").decryptResult;

module.exports.makeRequest = makeRequest;
async function makeRequest({ query, clientToken, passPhrase }) {
async function makeRequest({ query, clientToken, data }) {
return await new Promise((resolve, reject) => {
api({
method: "GET",
headers: { "Content-Type": "application/json" },
headers: { "Content-Type": "application/json", karaeatcookies: clientToken },
params: {
query,
clientToken,
passPhrase,
data,
},
url: process.env.BACK_URL + "/api/heyKara",
})
Expand All @@ -27,30 +26,38 @@ async function makeRequest({ query, clientToken, passPhrase }) {
return resolve(response.data);
})
.catch(function (error) {
if (error.code === "ECONNREFUSED") resolve({ err: "Access to the Kara server cannot be established" });
if (error.response && error.response.status === 403) resolve({ err: "Access to the Kara server is forbidden" });
if (error.code === "ECONNREFUSED")
resolve({ err: "Access to the Kara server cannot be established", status: 420 });
if (error.response && error.response.status === 403)
resolve({ err: "Access to the Kara server is forbidden", status: error.response.status });
else if (error.response && error.response.status === 404)
return resolve({ err: "User does not exist", status: error.response.status });
if (error.response && error.response.status === 500)
resolve({ err: "Kara as an internal error", status: error.response.status });
else {
console.log(error);
resolve({ err: error.code });
resolve({ err: error.code, status: error.response ? error.response.status : 420 });
}
});
});
}

module.exports.heyKara = heyKara;
async function heyKara({ userName, userId, messageContent, avatarUrl }) {
const { err, clientToken, passPhrase } = await getPassPhrase({ userId, userName, avatarUrl });
async function heyKara({ userName, userId, messageContent, avatarUrl, retry = 0 }) {
const { err, clientToken, data, publicKey } = await prepareRequest({ userId, userName, avatarUrl, messageContent });
if (err) return err;
const data = passPhrase
? await makeRequest({ query: messageContent, clientToken, passPhrase })
: { clientExist: false };
if (data.errRequest) return data.errRequest;
const resultPhrase = data.result;
const dataRequest = data ? await makeRequest({ query: messageContent, clientToken, data }) : { clientExist: false };
if (dataRequest.err && retry != 0) return dataRequest.err;

if (!data.clientExist) {
fs.unlinkSync(__dirname + "/../data/clients/" + userId + ".json");
return heyKara({ userName, userId, messageContent, avatarUrl });
if (!dataRequest || dataRequest.err) {
if (dataRequest && dataRequest.status === 404) fs.unlinkSync(__dirname + "/../data/clients/" + userId + ".json");
retry++;
return heyKara({ userName, userId, messageContent, avatarUrl, retry });
}

return resultPhrase;
const resultDecrypted = data
? await decryptResult({ data: dataRequest, publicKey })
: { result: "Error with the request" };

const phraseResult = resultDecrypted.result;
return phraseResult;
}
Loading

0 comments on commit 8e07bb9

Please sign in to comment.