Skip to content

Commit

Permalink
Merge pull request #39 from Contraversum/ci/cd
Browse files Browse the repository at this point in the history
Add CI/CD
  • Loading branch information
GregTCLTK committed Sep 16, 2023
2 parents 06d7a0d + cd942db commit e6b265f
Show file tree
Hide file tree
Showing 9 changed files with 4,693 additions and 70 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/build.yaml
@@ -0,0 +1,27 @@
name: Build

on: push

jobs:
build:
name: Build Bot
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [20.x]

steps:
- name: Pull Project
uses: actions/checkout@v3.5.2

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3.6.0
with:
node-version: ${{ matrix.node-version }}

- name: Preparing Project
run: npm i

- name: Building ContraBot
run: tsc
39 changes: 39 additions & 0 deletions .github/workflows/publish.yaml
@@ -0,0 +1,39 @@
name: Publish

on: release

jobs:
build:
name: Publish Bot
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [20.x]

steps:
- name: Pull Project
uses: actions/checkout@v3.5.2

- name: Login to GitHub Container Registry
uses: docker/login-action@v2.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}

- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: "ghcr.io/contraversum/contrabot:latest"

- name: Deploy
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
script: cd memoriter/ && docker compose up -d --pull always contra-bot
3 changes: 1 addition & 2 deletions .gitignore
@@ -1,3 +1,2 @@
node_modules
config.json
sheetConfig.json
.env
6 changes: 6 additions & 0 deletions Dockerfile
@@ -0,0 +1,6 @@
FROM node:20
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD [ "npx", "ts-node", "index.ts" ]
5 changes: 2 additions & 3 deletions deploy-commands.ts
@@ -1,5 +1,4 @@
import { REST, Routes } from 'discord.js';
import { clientId, guildId, token } from './config.json';
import fs from 'fs';
import path from 'path';

Expand All @@ -24,7 +23,7 @@ for (const folder of commandFolders) {
}

// Construct and prepare an instance of the REST module
const rest = new REST().setToken(token);
const rest = new REST().setToken(process.env.TOKEN!);

// and deploy your commands!
(async () => {
Expand All @@ -33,7 +32,7 @@ const rest = new REST().setToken(token);

// The put method is used to fully refresh all commands in the guild with the current set
const data: any = await rest.put(
Routes.applicationGuildCommands(clientId, guildId),
Routes.applicationGuildCommands(process.env.CLIENT_ID!, process.env.GUILD_ID!),
{ body: commands },
);

Expand Down
107 changes: 53 additions & 54 deletions index.ts
@@ -1,31 +1,31 @@
import 'dotenv/config'
import { Client, Collection, Events, GatewayIntentBits } from 'discord.js';
import { token } from './config.json';
import { sendQuestion } from './commands/test/test-command';
import { sendSurveyQuestions, Feedbackquestions } from './commands/test/startSurvey';
import * as fs from 'fs';
import path from 'path'
import { MongoClient } from "mongodb";
import { google } from 'googleapis';

export const db = new MongoClient("mongodb://127.0.0.1:27017/");
export const db = new MongoClient(process.env.MONGO_URL!);

interface ClientWithCommands extends Client {
commands: Collection<string, any>
}
const client = new Client({
intents: [
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.DirectMessages
]
GatewayIntentBits.GuildMessages,
GatewayIntentBits.DirectMessages
]
}) as ClientWithCommands;


client.on(Events.ClientReady, async (c) => {
console.log(`Ready! Logged in as ${c.user.tag}`);
await db.connect();
});

client.login(token); // Log in to the bot
client.login(process.env.TOKEN); // Log in to the bot

client.commands = new Collection();
const foldersPath = path.join(__dirname, 'commands');
Expand Down Expand Up @@ -73,51 +73,51 @@ client.on(Events.InteractionCreate, async (interaction) => {
});
}
}
return;
}

// check if the interaction is a button interaction
else if (interaction.isButton()) {
if (interaction.isButton()) {
const buttonId = interaction.customId;

if (buttonId === 'start_survey') {
await interaction.deferUpdate();
sendSurveyQuestions(interaction);

// Update context for this user in the database to indicate feedback process has started
await db.db('contrabot').collection("users").updateOne(
{ userId: interaction.user.id },
{
$set: {
{ userId: interaction.user.id },
{
$set: {
feedbackInProgress: true,
currentFeedbackQuestionIndex: 0
}
},
},
{ upsert: true }
);
}
else {
// Fetch user's context from the database
const userContext = await db.db('contrabot').collection("users").findOne({ userId: interaction.user.id });

let userResponses = userContext?.userVector || [];

// Update the userResponses based on button clicked
if (buttonId === 'agree') userResponses.push(1);
else if (buttonId === 'disagree') userResponses.push(-1);
else if (buttonId === 'neutral') userResponses.push(0);

// Update the userResponses for this user in the database
await db.db('contrabot').collection("users").updateOne(
{ userId: interaction.user.id },
{
$set: {
userVector: userResponses
} else {
// Fetch user's context from the database
const userContext = await db.db('contrabot').collection("users").findOne({ userId: interaction.user.id });

const userResponses = userContext?.userVector || [];

// Update the userResponses based on button clicked
if (buttonId === 'agree') userResponses.push(1);
else if (buttonId === 'disagree') userResponses.push(-1);
else if (buttonId === 'neutral') userResponses.push(0);

// Update the userResponses for this user in the database
await db.db('contrabot').collection("users").updateOne(
{ userId: interaction.user.id },
{
$set: {
userVector: userResponses
}
}
}
);
);

await interaction.deferUpdate();
sendQuestion(interaction);
await interaction.deferUpdate();
sendQuestion(interaction);
}
}
});
Expand All @@ -127,13 +127,12 @@ const SHEET_ID = '1pKsioVutiEPkNwTUrW1v_Y8bFe5eQobCGpK9KVpsOo8';
const START_COLUMN = 'A';
const END_COLUMN = 'P';
const COLUMNS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); // to allow easy access to column names
const sheetConfig = JSON.parse(fs.readFileSync('./sheetConfig.json', 'utf-8'));

const jwtClient = new google.auth.JWT(
sheetConfig.client_email,
undefined,
sheetConfig.private_key,
['https://www.googleapis.com/auth/spreadsheets']
process.env.CLIENT_EMAIL,
undefined,
process.env.PRIVATE_KEY,
[ 'https://www.googleapis.com/auth/spreadsheets' ]
);

const sheets = google.sheets({ version: 'v4', auth: jwtClient });
Expand All @@ -147,17 +146,17 @@ client.on(Events.MessageCreate, async (message) => {

if (userContext?.feedbackInProgress) {
let currentFeedbackQuestionIndex = userContext?.currentFeedbackQuestionIndex || 0;

// Calculate the column where the answer should be placed.
const columnForAnswer = COLUMNS[currentFeedbackQuestionIndex + 1]; // +1 to skip the first column which might have the userID
const columnForAnswer = COLUMNS[ currentFeedbackQuestionIndex + 1 ]; // +1 to skip the first column which might have the userID

// Find the row number for the current user (assuming the user's ID is in the first column)
const response = await sheets.spreadsheets.values.get({
spreadsheetId: SHEET_ID,
range: `${START_COLUMN}:${START_COLUMN}` // search in the first column only
});
const rows = response.data.values || [];
let rowIndex = rows.findIndex(row => row[0] === message.author.id.toString()) + 1; // +1 because index is 0-based and rows in Google Sheets are 1-based.
let rowIndex = rows.findIndex((row: any) => row[ 0 ] === message.author.id.toString()) + 1; // +1 because index is 0-based and rows in Google Sheets are 1-based.

// If the user is not found, create a new row for them
if (rowIndex === 0) {
Expand All @@ -168,7 +167,7 @@ client.on(Events.MessageCreate, async (message) => {
insertDataOption: 'INSERT_ROWS',
resource: {
values: [
[message.author.id] // userID in the first column
[ message.author.id ] // userID in the first column
]
}
} as any);
Expand All @@ -182,29 +181,29 @@ client.on(Events.MessageCreate, async (message) => {
valueInputOption: 'RAW',
resource: {
values: [
[message.content]
[ message.content ]
]
}
} as any);

currentFeedbackQuestionIndex++;

if (currentFeedbackQuestionIndex < Feedbackquestions.length) {
message.author.send(Feedbackquestions[currentFeedbackQuestionIndex]);
message.author.send(Feedbackquestions[ currentFeedbackQuestionIndex ]);

await db.db('contrabot').collection("users").updateOne(
{ userId: message.author.id },
{
$set: {
{ userId: message.author.id },
{
$set: {
currentFeedbackQuestionIndex: currentFeedbackQuestionIndex
}
}
);
} else {
await db.db('contrabot').collection("users").updateOne(
{ userId: message.author.id },
{
$set: {
{ userId: message.author.id },
{
$set: {
feedbackInProgress: false
}
}
Expand Down

0 comments on commit e6b265f

Please sign in to comment.