Skip to content

Commit 5966a7c

Browse files
committed
Merge branch 'development'
2 parents 21b7de4 + 6011b6f commit 5966a7c

File tree

8 files changed

+1310
-1056
lines changed

8 files changed

+1310
-1056
lines changed

.gitignore

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
!.gitignore
2+
!.keep
3+
!.gitkeep
4+
15
# Logs
26
logs
37
*.log
@@ -120,4 +124,9 @@ dist
120124
# database files
121125
*.db
122126
*.env
123-
.env
127+
128+
# -----
129+
130+
.idea
131+
.vscode
132+
.code

README.md

+52-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,58 @@
11
# eggcart
2-
Grocery List Telegram Bot
2+
## Grocery List Telegram Bot
33

4-
<img src=https://github.com/Radical-Egg/eggcart/blob/master/assets/eggcart_profile.png height=600 width=800>
4+
<img alt="AppLogo" src="assets/eggcart_profile.png" width="256">
55

6-
How to create your own bot:
6+
## Description
7+
EggCart is a Telegram Bot designed to manage your grocery list efficiently. Built with Node.js, SQLite, and Telegraf, it offers a simple and interactive way to add, remove, and manage items on your grocery list through Telegram.
78

8-
1. git clone https://github.com/Radical-Egg/eggcart.git
9-
2. create a file .env and store the API keys and your telegram user ID - updated approvedShoppers function on line 114 (EggCart.js) with your process.env.user variable
10-
3. npm install
9+
## Features
10+
- Add items to your grocery list with a simple Telegram command.
11+
- Remove items from the list as you purchase them.
12+
- View the entire list at any time.
13+
- Clear the list with one command.
1114

15+
## Screenshot
1216

13-
<img src=https://github.com/Radical-Egg/eggcart/blob/master/assets/egg_cart_screenshot.png height=800>
17+
<img alt="AppScreenshot" src="assets/egg_cart_screenshot.png" width="312">
18+
19+
## Installation
20+
To get EggCart up and running, follow these steps:
21+
22+
1. Clone the repository
23+
24+
```bash
25+
git clone https://github.com/ljgonzalez1/eggcart.git eggcart
26+
```
27+
28+
2. Install the dependencies:
29+
```bash
30+
cd eggcart
31+
yarn install
32+
```
33+
34+
3. Create a `.env` file in the root directory and add your Telegram Bot API key and other required environment variables.
35+
36+
3.1 updated approvedShoppers function on line 114 (EggCart.js) with your process.env.user variable
37+
38+
4. Start the bot:
39+
```bash
40+
yarn start
41+
```
42+
43+
## Usage
44+
Once the bot is running, you can interact with it on Telegram using the following commands:
45+
- `/add [item1, item2, ...]` - Add items to your grocery list.
46+
- `/remove [item1, item2, ...]` - Remove items from your grocery list.
47+
- `/list` - Display the current grocery list.
48+
- `/clear` - Clear the grocery list.
49+
50+
## Contributing
51+
Contributions to EggCart are welcome! Please read our [Contributing Guidelines](CONTRIBUTING.md) for more information on how to report issues, suggest features, or submit pull requests.
52+
53+
## Credits
54+
- Original Author: Radical_Egg
55+
- Primary Contributor and Maintainer: ljgonzalez1
56+
57+
## License
58+
EggCart is released under the [ISC License](LICENSE). See the LICENSE file for more details.

db/.keep

Whitespace-only changes.

modules/Database.js

+44-28
Original file line numberDiff line numberDiff line change
@@ -38,25 +38,38 @@ class Supermarket extends Database {
3838
this.table = 'eggo_list'
3939
}
4040
create(data) {
41-
this.db.serialize(() => {
42-
this.createTable(this.table, this.grocery_list_attrs)
43-
this.handleCreate(data)
44-
})
41+
return new Promise((resolve, reject) => {
42+
this.db.serialize(() => {
43+
this.createTable(this.table, this.grocery_list_attrs);
44+
45+
// Ahora handleCreate debería ser modificado para manejar promesas
46+
this.handleCreate(data).then(result => {
47+
resolve(true); // Si la creación fue exitosa
48+
}).catch(err => {
49+
console.error(err);
50+
resolve(false); // Si hubo un error
51+
});
52+
});
53+
});
4554
}
55+
4656
handleCreate(data) {
47-
let sqlCommand = `INSERT OR IGNORE INTO ${this.table} VALUES (?)`
48-
49-
let insert = this.db.prepare(sqlCommand)
50-
51-
try {
52-
insert.run(data['item'])
53-
console.log("Entry has been created or already exists for " + data['item'])
54-
} catch (error) {
55-
console.log(error.message)
56-
console.log(`Cannot insert this user because it already exists
57-
\n if your need to update values - use update function `)
58-
return false
59-
}
57+
return new Promise((resolve, reject) => {
58+
let sqlCommand = `INSERT OR IGNORE INTO ${this.table} VALUES (?)`;
59+
let insert = this.db.prepare(sqlCommand);
60+
61+
insert.run(data['item'], function(err) {
62+
if (err) {
63+
console.log(err.message);
64+
console.log(`Cannot insert this item because it already exists
65+
\n if your need to update values - use update function `);
66+
reject(err); // Rechazar la promesa con el error
67+
} else {
68+
console.log("Entry has been created or already exists for " + data['item']);
69+
resolve(); // Resolver la promesa exitosamente
70+
}
71+
});
72+
});
6073
}
6174

6275
// can access this in the main by doing
@@ -73,7 +86,7 @@ class Supermarket extends Database {
7386
})
7487
})
7588
}
76-
// TODO - updating is working but we need to log our updates to somewhere
89+
7790
handleUpdate = (item, new_item) => {
7891
this.retreive(item.item).then((item) => {
7992
let sqlCommand = `UPDATE ${this.table} SET item = ? WHERE item = ?`
@@ -118,16 +131,19 @@ class Supermarket extends Database {
118131
}
119132
getTable() {
120133
return new Promise((resolve, reject) => {
121-
var shopping_list = []
122-
this.db.each(`SELECT item FROM ${this.table}`,
123-
(err,row) => {
124-
if (err) {reject(console.log("we got a prob"))}
125-
shopping_list.push(row.item)
126-
},
127-
(err, list) => {
128-
resolve(shopping_list)
129-
})
130-
})
134+
let shopping_list = [];
135+
this.db.each(`SELECT item FROM ${this.table}`, (err, row) => {
136+
if (err) {
137+
console.log("we got a prob", err);
138+
reject(err);
139+
return;
140+
}
141+
shopping_list.push(row.item);
142+
}, () => {
143+
resolve(shopping_list);
144+
}
145+
);
146+
});
131147
}
132148
}
133149

modules/Eggcart.js

+67-96
Original file line numberDiff line numberDiff line change
@@ -12,124 +12,95 @@ class EggCart {
1212
this.bot = new Telegraf(process.env.API_TOKEN)
1313
}
1414
addItem() {
15-
this.bot.command('add', (ctx) => {
16-
let isApproved = this.approvedShoppers(ctx.from.id)
17-
18-
if (isApproved) {
19-
let ilist = ctx.update.message.text
20-
let remove_add = ilist.substr(ilist.indexOf(" ") + 1)
21-
22-
let item_list = remove_add.split(",")
23-
24-
let response = 'Okay! \n'
25-
for(let i = 0; i < item_list.length; i++) {
26-
let item = {"item": item_list[i].trim()}
27-
if (this.store.create(item) !== false) {
28-
response += `${item_list[i]},`
15+
this.bot.command('add', async (ctx) => {
16+
let iList = ctx.update.message.text;
17+
let remove_add = iList.slice(iList.indexOf(" ") + 1);
18+
let item_list = remove_add.split(",");
19+
let response = 'Okay! \n';
20+
21+
for (let i = 0; i < item_list.length; i++) {
22+
let item = {"item": item_list[i].trim()};
23+
try {
24+
let success = await this.store.create(item);
25+
if (success) {
26+
response += `${item_list[i].trim()}, `;
2927
}
28+
} catch (error) {
29+
console.error(error);
3030
}
31-
// remove last comma
32-
response = response.substr(0, response.length - 1)
33-
response += ' are on the shopping list!'
34-
ctx.reply(response)
35-
} else {
36-
ctx.reply("Sorry you cannot shop here")
37-
console.log(ctx.from)
3831
}
39-
})
32+
response = response.slice(0, response.length - 2); // Eliminar la última coma y espacio
33+
response += ' are on the shopping list!';
34+
ctx.reply(response);
35+
});
4036
}
37+
4138
deleteItem() {
42-
this.bot.command('remove', (ctx) => {
43-
let isApproved = this.approvedShoppers(ctx.from.id)
44-
45-
if (isApproved) {
46-
let ilist = ctx.update.message.text
47-
let remove_add = ilist.substr(ilist.indexOf(" ") + 1)
48-
49-
let item_list = remove_add.split(",")
50-
51-
let response = 'Okay! \n'
52-
53-
for(let i = 0; i < item_list.length; i++) {
54-
this.store.delete(item_list[i].trim())
55-
response += `${item_list[i]},`
39+
this.bot.command('remove', async (ctx) => {
40+
let iList = ctx.update.message.text;
41+
let remove_add = iList.slice(iList.indexOf(" ") + 1);
42+
let item_list = remove_add.split(",");
43+
let response = 'Okay! \n';
44+
45+
for (let i = 0; i < item_list.length; i++) {
46+
try {
47+
await this.store.delete(item_list[i].trim());
48+
response += `${item_list[i].trim()}, `;
49+
} catch (error) {
50+
console.error(error);
5651
}
57-
response = response.substr(0, response.length - 1)
58-
response += ' is no longer on the shopping list!\n'
59-
60-
ctx.reply(response)
61-
} else {
62-
ctx.reply("Sorry you can't shop here :c")
6352
}
64-
65-
})
53+
response = response.slice(0, response.length - 2);
54+
response += ' is no longer on the shopping list!\n';
55+
ctx.reply(response);
56+
});
6657
}
58+
6759
getList() {
6860
this.bot.command('list', (ctx) => {
69-
let isApproved = this.approvedShoppers(ctx.from.id)
70-
71-
if (isApproved) {
72-
let list = this.store.getTable().then((items) => {
73-
let response = 'Grocery List\n'
74-
let itemCount = 0
75-
let i = 1
76-
items.forEach((item) => {
77-
response += `${i}. ${item}\n`
78-
i++
79-
itemCount++
80-
})
81-
if (itemCount === 0) {
82-
ctx.reply("Nothing to shop for :o - try adding eggs")
83-
} else {
84-
ctx.reply(response)
85-
}
61+
let list = this.store.getTable().then((items) => {
62+
let response = 'Grocery List\n'
63+
let itemCount = 0
64+
let i = 1
65+
items.forEach((item) => {
66+
response += `${i}. ${item}\n`
67+
i++
68+
itemCount++
8669
})
87-
} else {
88-
ctx.reply("Sorry you can't shop here :c")
89-
}
70+
if (itemCount === 0) {
71+
ctx.reply("Nothing to shop for :o - try adding eggs")
72+
} else {
73+
ctx.reply(response)
74+
}
75+
})
9076
})
9177
}
9278
clearList() {
93-
this.bot.command('clear', (ctx) => {
94-
let isApproved = this.approvedShoppers(ctx.from.id)
95-
96-
if(isApproved) {
97-
let list = this.store.getTable().then((items) => {
98-
items.forEach((item) => {
99-
this.store.delete(item)
100-
})
101-
})
102-
} else {
103-
ctx.reply("Sorry you can't shop here :c")
79+
this.bot.command('clear', async (ctx) => {
80+
try {
81+
let items = await this.store.getTable();
82+
for (const item of items) {
83+
await this.store.delete(item);
84+
}
85+
ctx.reply("The shopping list has been cleared!");
86+
} catch (error) {
87+
console.error(error);
88+
ctx.reply("An error occurred while clearing the list.");
10489
}
105-
})
90+
});
10691
}
92+
10793
help() {
10894
this.bot.help((ctx) => {
10995
ctx.reply(
110-
"Add an item : /add eggs, milk\nRemove an item : /remove eggs, milk\n Show the list : /list\nClear the list : /clear"
96+
"Add an item : /add eggs, milk\n" +
97+
"Remove an item : /remove eggs, milk\n" +
98+
"Show the list : /list\n" +
99+
"Clear the list : /clear"
111100
)
112101
})
113102
}
114-
approvedShoppers(token) {
115-
let canShop = false
116-
117-
switch(String(token)) {
118-
case String(process.env.jaymen):
119-
canShop = true;
120-
break;
121-
case String(process.env.baobei):
122-
canShop = true;
123-
break;
124-
case String(process.env.matt):
125-
canShop = true;
126-
break;
127-
default:
128-
break;
129-
}
130-
return canShop
131-
}
132103
connect() { this.bot.launch() }
133104
}
134105

135-
module.exports = EggCart
106+
module.exports = EggCart

0 commit comments

Comments
 (0)