Skip to content

Commit

Permalink
adding linter and fixing a bunch of misc changed outlined in issue 24
Browse files Browse the repository at this point in the history
  • Loading branch information
petercort committed Dec 29, 2024
1 parent b2c840f commit 4be7ab3
Show file tree
Hide file tree
Showing 13 changed files with 973 additions and 111 deletions.
10 changes: 10 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import globals from "globals";
import pluginJs from "@eslint/js";


/** @type {import('eslint').Linter.Config[]} */
export default [
{files: ["**/*.js"], languageOptions: {sourceType: "commonjs"}},
{languageOptions: { globals: globals.node }},
pluginJs.configs.recommended,
];
882 changes: 877 additions & 5 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"scripts": {
"start": "NODE_ENV=production node src/app.js",
"register": "node src/commands.js",
"dev": "nodemon src/app.js"
"dev": "nodemon src/app.js",
"lint": "eslint src/**/*.js"
},
"author": "Peter Cort",
"license": "MIT",
Expand All @@ -26,6 +27,9 @@
"sqlite3": "^5.1.7"
},
"devDependencies": {
"@eslint/js": "^9.17.0",
"eslint": "^9.17.0",
"globals": "^15.14.0",
"nodemon": "^3.1.9"
}
}
16 changes: 13 additions & 3 deletions readme-template.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
readme:
title: "Event Buddy"
summary: "A discord plugin that manages event data!"
title: "FBF Discord Buddy"
summary: "A discord app that helps with random tasks in the FBF discord!"
benefits:
- Allows users to create and manage events
- "Helps with random tasks in the FBF discord!"
commands: |
| Command | Inputs | Description | Example | Output |
| ------- | ------ | ----------- | ------- | ------ |
| /connect_strava | None | User authorizes access to the Strava app to collect information about your bikes. Permissions: scope=read, activity:read_all, profile:read_all | /connect_strava | A link to connect to Strava |
| /sync_bikes | None | Syncs bike data from Strava. | /sync_bikes | Returns bike data in the format Name (Brand, Model, Mileage) |
| /get_all_bikes | None | Gets all your bike data from Strava | /get_all_bikes | Returns bike data in the format Name (Brand, Model) |
| /get_bike_by_name | name | Returns specific details about a bike | /get_bike_by_name name: Joe | Returns more bike data in the format name, brand, model, current mileage, and last waxed (date + mileage) |
| /i_waxed_my_chain | bike_name (req) date (optional) mileage (optional) | Updated the last_waxed field on the app. With no optional params passed it will update to the current date and mileage. | /i_waxed_my_chain bike_name: Joe date: 12/24/2024 mileage: 355 | If successful, returns the date and mileage in the system for a last wax, otherwise returns an error. |
| /get_last_ride | none | Returns the last ride you did according to Strava | /get_last_ride | Returns info on the last ride you did. |
owner_maintainers:
- '@petercort'
known_issues:
Expand Down
3 changes: 0 additions & 3 deletions src/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@ const path = require('node:path');

require('dotenv').config()
let discordToken;
let guildId;
let appId;
if (process.env.NODE_ENV === 'production') {
discordToken = fs.readFileSync("/mnt/secrets-store/discordToken", 'utf8');
guildId = fs.readFileSync("/mnt/secrets-store/guildId", 'utf8');
appId = fs.readFileSync("/mnt/secrets-store/appId", 'utf8');
} else {
discordToken = process.env.discordToken;
guildId = process.env.guildId;
appId = process.env.appId;
}

Expand Down
2 changes: 1 addition & 1 deletion src/commands/events/update_event.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ module.exports = {

try {
// equivalent to: INSERT INTO events (name, description, username) values (?, ?, ?);
const event = await EventsTable.update({
await EventsTable.update({
description: eventDescription,
location: eventLocation,
link: eventLink,
Expand Down
48 changes: 28 additions & 20 deletions src/commands/strava/get_all_bikes.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
const { SlashCommandBuilder } = require('discord.js');
const { BikesTable } = require('../../dbObjects.js');
const { BikesTable, UsersTable } = require('../../dbObjects.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('get_all_bikes')
.setDescription('Get all your bikes!'),
async execute(interaction) {
const userId = interaction.user.id;

try {
// Query the BikesTable to get all bikes for the user
const bikes = await BikesTable.findAll({ where: { userId } });

if (bikes.length === 0) {
return await interaction.reply('No bikes found.');
}
const bikeList = bikes.map(bike => `${bike.name} (${bike.brand} ${bike.model})`).join('\n');
return await interaction.reply(`Your bikes:\n${bikeList}`);
} catch (error) {
console.error('Error fetching bikes:', error);
return await interaction.reply('There was an error fetching your bikes.');
}
data: new SlashCommandBuilder()
.setName('get_all_bikes')
.setDescription('Get all your bikes!'),
async execute(interaction) {
const userId = interaction.user.id;
// look up if the user is in the database
try {
const user = await UsersTable.findOne({ where: { userId } });
if (!user) {
return await interaction.reply({content: 'Please connect your Strava using the /connect_strava command.', ephemeral: true });
}
} catch (error) {
console.error('Error fetching user:', error);
return await interaction.reply({content: 'There was an error querying data, please check back in a bit.', ephemeral: true });
}
try {
// Query the BikesTable to get all bikes for the user
const bikes = await BikesTable.findAll({ where: { userId } });
if (bikes.length === 0) {
return await interaction.reply({content: 'No bikes found! Add a bike by going to https://www.strava.com/settings/gear and adding a bike. Then run /sync_bikes to sync your bikes.', ephemeral: true });
}
const bikeList = bikes.map(bike => `${bike.name}: ${bike.brand} ${bike.model}. ${Math.round(bike.distance * 0.000621371)} miles. Last waxed on ${bike.lastWaxedDate} at ${Math.round(bike.lastWaxedDistance * 0.000621371)} miles.`).join('\n');
return await interaction.reply({content: `Your bikes:\n${bikeList}`, ephemeral: true });
} catch (error) {
console.error('Error fetching bikes:', error);
return await interaction.reply({content: 'There was an error fetching your bikes.', ephemeral: true });
}
},
};
22 changes: 15 additions & 7 deletions src/commands/strava/get_bike_by_name.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { SlashCommandBuilder } = require('discord.js');
const { BikesTable } = require('../../dbObjects.js');
const { BikesTable, UsersTable } = require('../../dbObjects.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('get_bike_by_name')
Expand All @@ -10,21 +10,29 @@ module.exports = {
.setRequired(true)),
async execute(interaction) {
const userId = interaction.user.id;
// look up if the user is in the database
try {
const user = await UsersTable.findOne({ where: { userId } });
if (!user) {
return await interaction.reply({content: 'Please connect your Strava using the /connect_strava command.', ephemeral: true });
}
} catch (error) {
console.error('Error fetching user:', error);
return await interaction.reply({content: 'There was an error querying data, please check back in a bit.', ephemeral: true });
}
const bikeName = interaction.options.getString('name')
try {
// Query the BikesTable to get the bike by name for the user
const bike = await BikesTable.findOne({ where: { userId, name: bikeName } });

if (!bike) {
return await interaction.reply('No bike found with that name.');
return await interaction.reply({content: 'No bike found with that name.', ephemeral: true });
}
const miles = Math.round(bike.lastWaxedDistance * 0.000621371); // equivilant meters to miles
const bikeInfo = `Bike information:\nName: ${bike.name}\nBrand: ${bike.brand}\nModel: ${bike.model}.\nCurrent Mileage: ${Math.round(bike.distance * 0.000621371)}\nThis chain was last waxed on ${bike.lastWaxedDate} at ${miles} miles.`;

return await interaction.reply(bikeInfo);
const bikeInfo = `${bike.name}: ${bike.brand} ${bike.model}. ${Math.round(bike.distance * 0.000621371)} miles. Last waxed on ${bike.lastWaxedDate} at ${Math.round(bike.lastWaxedDistance * 0.000621371)} miles.`;
return await interaction.reply({content: bikeInfo, ephemeral: true });
} catch (error) {
console.error('Error fetching bike:', error);
return await interaction.reply('There was an error fetching your bike.');
return await interaction.reply({content: 'There was an error fetching your bike.', ephemeral: true });
}
}
};
16 changes: 13 additions & 3 deletions src/commands/strava/i_waxed_my_chain.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { SlashCommandBuilder } = require('@discordjs/builders');
const { BikesTable } = require('../../dbObjects.js');
const { BikesTable, UsersTable } = require('../../dbObjects.js');

module.exports = {
data: new SlashCommandBuilder()
Expand All @@ -19,6 +19,16 @@ module.exports = {
.setRequired(false)),
async execute(interaction) {
const userId = interaction.user.id;
// look up if the user is in the database
try {
const user = await UsersTable.findOne({ where: { userId } });
if (!user) {
return await interaction.reply({content: 'Please connect your Strava using the /connect_strava command.', ephemeral: true });
}
} catch (error) {
console.error('Error fetching user:', error);
return await interaction.reply({content: 'There was an error querying data, please check back in a bit.', ephemeral: true });
}
const bikeName = interaction.options.getString('bike_name');
// if date is null use today
let date = interaction.options.getString('date')
Expand All @@ -38,12 +48,12 @@ module.exports = {
}

try {
const output = await BikesTable.update(
await BikesTable.update(
{ lastWaxedDate: date, lastWaxedDistance: mileage},
{ where: { userId: userId, bikeId: bike.bikeId } }
);
const distanceMiles = Math.round(mileage * 0.000621371192);
await interaction.reply({ content: `Successfully updated the last waxed date for bike ID ${bike.bikeId} to ${date}, at ${distanceMiles} miles.`});
await interaction.reply({ content: `Successfully updated the last waxed date for ${bike.name} to ${date}, at ${distanceMiles} miles.`, ephemeral: true });
} catch (error) {
console.error('Error updating waxed chain date:', error);
await interaction.reply({ content: 'There was an error updating the waxed chain date.', ephemeral: true });
Expand Down
11 changes: 7 additions & 4 deletions src/commands/strava/sync_bikes.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ module.exports = {
async execute(interaction) {
const userId = interaction.user.id;
const user = await UsersTable.findOne({ where: { userId } });
if (!user) {
return await interaction.reply({content: 'Please connect your Strava using the /connect_strava command.', ephemeral: true });
}
const strava_access_token = await getStravaAuthentication(user.dataValues);
if (!strava_access_token) {
return interaction.reply({ content: 'You need to connect your Strava account first.', ephemeral: true });
Expand All @@ -25,7 +28,7 @@ module.exports = {
const bikes = response.data.bikes;

if (bikes.length === 0) {
return await interaction.reply('No bikes found on Strava.');
return await interaction.reply({content: 'No bikes found on Strava.', ephemeral: true });
}
// Take the bike ID and call the gear/{id} endpoint to get the bike's name, brand, and model

Expand All @@ -49,14 +52,14 @@ module.exports = {
updatedBikes.push(updatedData[0].dataValues);
} catch (error) {
console.error('Error fetching bike data:', error);
return await interaction.reply('There was an error fetching your bike data.');
return await interaction.reply({content: 'There was an error fetching your bike data.', ephemeral: true });
}
}
const bikeList = updatedBikes.map(bike => `${bike.name} (${bike.brand} ${bike.model} ${Math.round(bike.distance * 0.000621371)})`).join('\n');
return await interaction.reply(`Your bikes have been synced:\n${bikeList}`);
return await interaction.reply({content: `Your bikes have been synced:\n${bikeList}`, ephemeral: true });
} catch (error) {
console.error('Error fetching or syncing bikes:', error);
return await interaction.reply('There was an error syncing your bikes.');
return await interaction.reply({content: 'There was an error syncing your bikes.', ephemeral: true });
}
},
};
1 change: 0 additions & 1 deletion src/hold.txt

This file was deleted.

9 changes: 4 additions & 5 deletions src/shared_library/strava_authentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,15 @@ async function firstTimeAuth(userId, code){
}
}
async function getStravaAuthentication(userData) {
const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds

if (userData.expiresAt <= currentTime) {
const currentTime = Math.floor(Date.now() / 1000); // Current time in seconds because Strava uses seconds for token expiry
if (userData.strava_expires_at <= currentTime) {
// Token is expired, refresh it
console.log('Token is expired, refreshing...');
const refreshTokenResponse = await axios.post('https://www.strava.com/oauth/token', {
client_id: stravaClientId,
client_secret: stravaClientSecret,
grant_type: 'refresh_token',
refresh_token: userData.refreshToken,
refresh_token: userData.strava_refresh_token,
});

const newAccessToken = refreshTokenResponse.data.access_token;
Expand All @@ -60,7 +59,7 @@ async function getStravaAuthentication(userData) {
}, {
where: { userId: userData.userId }
});

console.log('Token refreshed successfully!');
return newAccessToken;
} else {
console.log('Token is still valid...');
Expand Down
58 changes: 0 additions & 58 deletions src/utils.js

This file was deleted.

0 comments on commit 4be7ab3

Please sign in to comment.