Split token generation and the bot itself
All checks were successful
continuous-integration/drone/push Build is passing

Signed-off-by: Sam Therapy <sam@samtherapy.net>
This commit is contained in:
Sam Therapy 2022-02-16 09:57:37 -06:00
parent d66bd0dda9
commit 39acf17729
Signed by: sam
GPG key ID: 4D8B07C18F31ACBD
8 changed files with 1039 additions and 446 deletions

View file

@ -3,18 +3,54 @@ type: docker
name: default
steps:
- name: lint
- name: dependencies
image: node
commands:
- yarn
- name: lint
image: node
depends_on:
- dependencies
commands:
- yarn lint
- name: build
image: node
depends_on:
- dependencies
commands:
- yarn build
- name: test
image: node
depends_on:
- build
commands:
- yarn test
- name: package
image: node
depends_on:
- lint
- test
commands:
- yarn package
when:
event:
- tag
- name: Release
image: plugins/gitea-release
depends_on:
- package
settings:
api_key:
from_secret: release_api_key
base_url: https://git.froth.zone
files:
- dist/imagebot-*
when:
event:
- tag

View file

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2021 Sam Therapy
Copyright (c) 2022 Sam Therapy
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View file

@ -4,9 +4,12 @@
A bot that posts (currently only local) images to the Fediverse.
Should be compatible with Mastodon, Misskey and Pleroma!
Compatible with Mastodon, Misskey and Pleroma!
## Quick start guide
## Downloading pre-built binaries
Download prebuilt binaries from [here](https://git.froth.zone/Sam/fediverse-imagebot/releases/latest) (currently only supports x64), or build from source, instructions below.
## Running from Source
1. You need to have `npm` and `nodejs` installed.
- Node 15 or greater is required.
@ -23,17 +26,17 @@ Should be compatible with Mastodon, Misskey and Pleroma!
5. Build: \
`yarn build`
6. Obtain a token. This can be done with an external tool or obtained by running `yarn token` and following the directions.
- `yarn token` will generate a configuration file located at `config.json`
7. Put images in the `images` folder.
- By default the bot will look for SFW images at `images/sfw` and NSFW images at `images/nsfw`. This can be configured with the `-d` flag.
8. Run the bot: \
`yarn local`
You're done! The bot should post a local image to the fediverse instance of your choosing!
## Running the bot
1. Obtain a token. I have another tool that does this for you, which can be found [here](https://git.froth.zone/Sam/js-feditoken) and put it in `config.json`, following the sample json file.
2. Put images in the `images` folder.
- By default the bot will look for SFW images at `images/sfw` and NSFW images at `images/nsfw`. This can be configured with the `-d` flag.
## Automating the bot
*TODO: Elaborate more*
@ -45,9 +48,3 @@ Example cron configuration:
This example will run the bot every hour on the hour with the post message `Message` using images from the default `images` directory.
An example of this pleroma configuration can be found at https://froth.zone/rinbot.
<iframe allowfullscreen sandbox="allow-top-navigation allow-scripts" width="400" height="400" src="https://fedifeed.com/api/v1/feed?user=rinbot&instance=https%3A%2F%2Ffroth.zone&instance_type=&theme=pleroma&size=100&header=true&replies=false&boosts=false"></iframe>
## Additional information
Additional help can be found by running `yarn local -h` or `yarn token -h`.

View file

@ -1,33 +1,32 @@
{
"dependencies": {
"@types/command-line-args": "^5.2.0",
"@types/command-line-usage": "^5.0.2",
"@types/node": "^17.0.8",
"@types/readline-sync": "^1.4.4",
"command-line-args": "^5.2.0",
"command-line-usage": "^6.1.1",
"megalodon": "^4.0.0",
"readline-sync": "^1.4.10",
"typescript": "^4.5.4"
},
"name": "fediverse-imagebot",
"version": "2.0.0",
"description": "Image bot for the fediverse (Pleroma, Mastodon, Misskey)",
"main": "dist/local.js",
"scripts": {
"build": "yarn run clean && tsc",
"clean": "rm -rf dist",
"token": "node ./dist/gen-token.js",
"lint": "eslint --ext .ts src",
"local": "node ./dist/local.js",
"test": "echo \"No tests yet!\" && exit 0"
},
"repository": "https://git.freecumextremist.com/NotSam/fediverse-imagebot.git",
"author": "Sam Therapy <sam@samtherapy.net>",
"license": "MIT",
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.9.0",
"@typescript-eslint/parser": "^5.9.0",
"eslint": "^8.6.0"
}
}
"dependencies": {
"command-line-args": "^5.2.1",
"command-line-usage": "^6.1.1",
"megalodon": "^4.0.0",
"typescript": "^4.5.5"
},
"name": "fediverse-imagebot",
"version": "1.0.0",
"description": "Image bot for the fediverse (Pleroma, Mastodon, Misskey)",
"main": "dist/local.js",
"scripts": {
"build": "yarn run clean && tsc",
"clean": "rm -rf dist",
"lint": "eslint --ext .ts src",
"local": "node ./dist/local.js",
"package": "pkg dist/token.js -t node16-linux-x64,node16-macos-x64,node16-win-x64 -o dist/imagebot-x64 -C Gzip",
"test": "echo \"No tests yet!\" && exit 0"
},
"repository": "https://git.froth.zone/Sam/fediverse-imagebot",
"author": "Sam Therapy <sam@samtherapy.net>",
"license": "MIT",
"devDependencies": {
"@types/command-line-args": "^5.2.0",
"@types/command-line-usage": "^5.0.2",
"@types/node": "^17.0.18",
"@typescript-eslint/eslint-plugin": "^5.12.0",
"@typescript-eslint/parser": "^5.12.0",
"eslint": "^8.9.0",
"pkg": "^5.5.2"
}
}

View file

@ -1,109 +0,0 @@
#!/usr/bin/env node
// Takes a user inputted fediverse instance and generates a token for the bot, and adds it to the configuration file
import commandLineArgs from "command-line-args";
import commandLineUsage from "command-line-usage";
import generator, { detector, OAuth } from "megalodon";
import { exit } from "process";
import { question } from "readline-sync";
import * as fs from "fs";
const optionDefinitions = [
{
name: "help",
type: Boolean,
alias: "h",
description: "Print this usage guide."
},
{
name: "verbose",
type: Boolean,
alias: "v",
description: "Print debugging output."
}
];
const args = commandLineArgs(optionDefinitions);
if (args.help) {
const usage = commandLineUsage([
{
header: "Token Grabber",
content: "Grabs tokens for the bot to use."
},
{
header: "Options",
optionList: optionDefinitions
},
{
content: "Project home: {underline https://git.freecumextremist.com/NotSam/fediverse-imagebot}"
}
]);
console.log(usage);
exit(0);
}
if (args.verbose) {
console.log("Running in verbose mode.");
console.log();
}
const instance: string = question("Instance URL: ");
callDetector(instance).then(type => {
const client = generator(type, instance);
client.registerApp("Node Imagebot", { website: "https://git.freecumextremist.com/NotSam/fediverse-imagebot" })
.then((appData) => {
const clientId = appData.clientId;
const clientSecret = appData.clientSecret;
console.log("Please open this URL in your browser for the authorization code.");
console.log(appData.url);
let code: string;
if (type === "misskey") {
code = appData.session_token || "";
question("Authenticate with Misskey, then hit return.");
} else {
code = question("Authorization Code: ");
}
client.fetchAccessToken(clientId, clientSecret, code)
.then((tokenData: OAuth.TokenData) => {
if (args.verbose) {
console.log(`Access Token: ${tokenData.accessToken}`);
console.log(`Refresh Token: ${tokenData.refreshToken}`);
}
const config = {
instance: instance,
type: type,
accessToken: tokenData.accessToken,
refreshToken: tokenData.refreshToken
};
fs.writeFileSync("./config.json", JSON.stringify(config, null, 2));
console.log("Saved config to ./config.json");
exit(0);
})
.catch((err: Error) => { // catch for fetchAccessToken
console.error("Access Token fetch failed.");
console.error("Run with -v to see the full error.");
if (args.verbose)
console.error(err);
exit(1);
});
})
.catch((err: Error) => { // catch for registerApp
console.error("App registration failure!");
console.error("Run with -v to see the full error.");
if (args.verbose)
console.error(err);
exit(1);
});
});
async function callDetector(instance: string) {
const type = await detector(instance).catch( (err) => {
console.error("This does not seem to be a valid instance!");
console.error("Supported instance types: Mastodon, Misskey, Pleroma");
console.error("Run with -v to see the full error.");
if (args.verbose)
console.error(err);
exit(1);
});
if (args.verbose)
console.log(`Detected ${instance} as a ${type} instance.`);
return type;
}

View file

@ -59,7 +59,7 @@ if (args.help) {
optionList: optionDefinitions
},
{
content: "Project home: {underline https://git.freecumextremist.com/NotSam/fediverse-imagebot}"
content: "Project home: {underline https://git.froth.zone/Sam/fediverse-imagebot}"
}
]);
console.log(usage);

View file

@ -7,7 +7,7 @@
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
"declaration": true, /* Generates corresponding '.d.ts' file. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /*es Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */

1244
yarn.lock

File diff suppressed because it is too large Load diff