Compare commits

..

10 Commits

Author SHA1 Message Date
e37c000842 add MEDIA_DIR to .env.example 2023-02-10 08:29:59 -05:00
687a99fb39 allow calling so replybot can do regular statuses 2023-02-10 08:27:57 -05:00
6601b853b7 allows replybot to post regular statuses too 2023-02-10 08:12:07 -05:00
fcc56236d4 fix issue 2023-02-10 08:03:44 -05:00
ce687e56b0 update license file (like I need to lmao) 2023-02-09 20:37:21 -05:00
f8b788e670 fuckin markdown 2023-02-09 20:21:13 -05:00
9005fd302e update readme 2023-02-09 20:20:40 -05:00
a73d4ae70c remove errant README file 2023-02-09 20:19:35 -05:00
5da3a80317 Merge branch 'develop' of gitea.nicecrew.digital:matty/ncd-bot into develop 2023-02-09 20:18:34 -05:00
f2be2b8982 initial commit 2023-02-09 20:18:05 -05:00
10 changed files with 1405 additions and 5 deletions

4
.env.example Normal file
View File

@ -0,0 +1,4 @@
ADMIN_BEARER=""
REPLYBOT_BEARER=""
MEDIA_DIR="./lib/media"
INSTANCE_NAME="example.tld"

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.env
node_modules/
lib/media/

View File

@ -219,8 +219,7 @@ If you develop a new program, and you want it to be of the greatest possible use
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
Copyright (C) 2023 Matty Boombalatty
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

9
README.MD Normal file
View File

@ -0,0 +1,9 @@
This project requires NodeJS 18.14.0 and will probably only run effectively on a Linux machine.
1. Clone repository to directory
2. Enter `yarn` into terminal and press enter
3. Copy/move `.env.example` to `.env` in the root directory
4. Fill out the necessary information (_BEARER entries require BEARER tokens for authentication)
5. Run script by entering in to console "node nice-bot.js [SELECTION] [OPTIONS] (if applicable)"
I'll update this and add more features as times goes on. Yes, it is retarded spaghetti code but it works. I would recommend using `crontab` (see [CrontabGuru](https://crontab.guru/#*/_*_*_*_*)) to run the script every however long you'd like, if you want it to be automated. At the moment, this script does not support replying to mentions as they come, like how the `ebooks` accounts do.

View File

@ -1,3 +0,0 @@
# ncd-bot
Repository for the development and deployment of bots for the Fediverse.

33
lib/api.js Normal file
View File

@ -0,0 +1,33 @@
// API reference: https://api.pleroma.social/ and https://docs-develop.pleroma.social/backend/development/API/pleroma_api/
'use strict';
import fetch from 'node-fetch';
export const getLatestStatuses = async (count) =>{
const headers = {Authorization: `Bearer ${process.env.ADMIN_BEARER}`};
const statusUrlArr = [];
if (!count){
count = 1;
}
try{
const res = await fetch(`https://${process.env.INSTANCE_NAME}/api/v1/pleroma/admin/statuses?page_size=${count}&godmode=false&local_only=false`, {
method: "GET",
headers: headers,
});
const data = await res.json();
for (let account in data){
statusUrlArr.push([
data[account].id,
data[account].account.username,
data[account].pleroma.conversation_id,
data[account].mentions,
]);
};
} catch (error){
throw new Error(error);
};
//console.log(statusUrlArr);
return statusUrlArr;
};

61
lib/replybot.js Normal file
View File

@ -0,0 +1,61 @@
'use strict';
import fetch from 'node-fetch';
import { getLatestStatuses } from './api.js';
const chooseStatusID = (array) => {
return array[Math.floor(Math.random() * array.length)];
};
const emoteChoice = async () =>{ // pulls current emojis from the instance
const res = await fetch(`https://${process.env.INSTANCE_NAME}/api/v1/pleroma/emoji`, {
method: "GET",
});
const data = await res.json();
let emoteArray = [];
for (let e in data){
emoteArray.push(e);
}
return emoteArray[Math.floor(Math.random() * emoteArray.length)];
};
const statusChoice = async () =>{
const replyArr = [ // add desired replies here - it's just a big ass array
"example1",
"example 2",
"EXAMPLE 3",
];
return replyArr[Math.floor(Math.random() * replyArr.length)];
};
export const postRegularStatus = async () =>{
const headers = {Authorization: `Bearer ${process.env.REPLYBOT_BEARER}`, "Content-Type": "application/json"};
const emoji = await emoteChoice();
const word = await statusChoice();
const res = await fetch(`https://${process.env.INSTANCE_NAME}/api/v1/statuses`, {
method: "POST",
headers: headers,
body: JSON.stringify({status: `${word} :${emoji}:`}),
});
if (res.status === 200) {console.log('Replybot posted regular status!')} else {console.log('Replybot failed (regular status):', res.status, res.statusText, res.url, word, emoji)}
};
export const postReply = async () =>{
const headers = {Authorization: `Bearer ${process.env.REPLYBOT_BEARER}`, "Content-Type": "application/json"};
const mentions = [];
const statusIDArr = await getLatestStatuses(20);
const target = chooseStatusID(statusIDArr);
if (target[3]) {
for (let i = 0; i < target[3].length; i++){
mentions.push(target[3][i].acct);
}
};
const emoji = await emoteChoice();
const word = await statusChoice();
const res = await fetch(`https://${process.env.INSTANCE_NAME}/api/v1/statuses`, {
method: "POST",
headers: headers,
body: JSON.stringify({status: `${word} :${emoji}:`, in_reply_to_id: target[0], to: mentions}),
});
if (res.status === 200) {console.log('Replybot posted!')} else {console.log('Replybot failed:', res.status, res.statusText, res.url, word, emoji)}
};

21
nice-bot.js Executable file
View File

@ -0,0 +1,21 @@
#!/home/bot/.nvm/versions/node/v18.14.0/bin/node
'use strict';
import 'dotenv/config';
import { postRegularStatus, postReply } from './lib/replybot.js';
const choice = process.argv[2]; // command line switch
try{
switch (choice.toLowerCase()){
case 'replybot': // node nice-bot.js replybot [reply]
process.argv[3] === 'reply' ? postReply() : postRegularStatus();
break;
default:
console.log('Something went wrong with nice-bot (ya dun goof\'d)');
break;
};
} catch (error){
throw Error(error);
}

26
package.json Normal file
View File

@ -0,0 +1,26 @@
{
"dependencies": {
"dotenv": "^16.0.1",
"download-file": "^0.1.5",
"express": "^4.18.1",
"form-data": "^4.0.0",
"fs": "^0.0.1-security",
"google-images-url": "^1.0.2",
"mime": "^3.0.0",
"node-fetch": "2",
"path": "^0.12.7",
"pexels": "^1.4.0",
"sqlite3": "^5.0.11",
"yarn": "^1.22.19"
},
"name": "nice-poll",
"version": "1.0.0",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"type": "module",
"author": "",
"license": "ISC",
"description": ""
}

1247
yarn.lock Normal file

File diff suppressed because it is too large Load Diff