Compare commits
5 Commits
21669b0b56
...
75ce65b3e7
Author | SHA1 | Date |
---|---|---|
Wouter Groeneveld | 75ce65b3e7 | |
Wouter Groeneveld | 4d687cd22e | |
Wouter Groeneveld | 60e8dbe69f | |
Wouter Groeneveld | 2266cd4789 | |
Wouter Groeneveld | 0c1228dab5 |
|
@ -42,7 +42,8 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||
["got", "npm:11.8.2"],
|
||||
["jest", "npm:26.6.3"],
|
||||
["jsdom", "virtual:defa486869c88441047200a53b3aa18d79743b272095f3ee31b5b7b80b2c93d87f722added867470dcb94104504489a1a89040ea8fd89dffb9cfb1864d4bf54e#npm:16.5.2"],
|
||||
["md5", "npm:2.3.0"]
|
||||
["md5", "npm:2.3.0"],
|
||||
["minimist", "npm:1.2.5"]
|
||||
],
|
||||
"linkType": "SOFT",
|
||||
}]
|
||||
|
@ -4754,7 +4755,8 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||
["got", "npm:11.8.2"],
|
||||
["jest", "npm:26.6.3"],
|
||||
["jsdom", "virtual:defa486869c88441047200a53b3aa18d79743b272095f3ee31b5b7b80b2c93d87f722added867470dcb94104504489a1a89040ea8fd89dffb9cfb1864d4bf54e#npm:16.5.2"],
|
||||
["md5", "npm:2.3.0"]
|
||||
["md5", "npm:2.3.0"],
|
||||
["minimist", "npm:1.2.5"]
|
||||
],
|
||||
"linkType": "SOFT",
|
||||
}]
|
||||
|
|
61
README.md
61
README.md
|
@ -1,4 +1,63 @@
|
|||
|
||||
# Plerobuddies
|
||||
|
||||
Yay! (TODO)
|
||||
Yay! **Working examples** say more than a 1000 words:
|
||||
|
||||
- [@acvilagers@chat.brainbaking.com](https://chat.brainbaking.com/@acvillagers)
|
||||
- [@gblegacy@chat.brainbaking.com](https://chat.brainbaking.com/@gblegacy)
|
||||
|
||||
![Screenshot from a Pleroma instance](https://raw.githubusercontent.com/wgroeneveld/plerobuddies/master/screenshot.jpg)
|
||||
|
||||
## Mastodon/Pleroma Buddies (bots)
|
||||
|
||||
Execute through `yarn toot` or `yarn node src/chat.js`. It cycles through all configured "buddies" and toots a message accordingly. Use your favorite `crontab` timestamp to fire off toots automatically.
|
||||
|
||||
If you'd like to let a specific buddy chat - for instance to configure them individually in your crontab - use the argument `buddy`:
|
||||
|
||||
`yarn toot --buddy [by-cool-buddy]`
|
||||
|
||||
The name should match the `buddy` property in the config file (_not_ the `name` property: that's the buddy directory name).
|
||||
|
||||
### Packaged buddies
|
||||
|
||||
1. **animalcrossing**: collect data from https://animalcrossing.fandom.com/wiki/ and randomly toot about a villager, including a link to the Fandom page and the birthday. Uses dirty scraping, no rate limit hit yet...
|
||||
2. **mobygames**: collect data through the Moby Games API so you'll need an API key: https://www.mobygames.com/info/api - the API is rate-limited at one call per second and 360 per hour. The above working example posts a random Game Boy game with two screenshots collected via the API. It's generic, so just configure `platform` in the config file (10 is GB).
|
||||
|
||||
### Creating a new buddy
|
||||
|
||||
Create a directory in `src/buddies/` and add it to `config.js` using the same name. Each buddy should have a `buddy.js` with one exposed method called `chat`, which gets executed with a config parameter. Look at the examples for more information. End the file with something like `module.exports = { chat }`.
|
||||
|
||||
The function `chat` should create a "toot", with the following structure:
|
||||
|
||||
```js
|
||||
{
|
||||
"toot": "hi there buddy!",
|
||||
"attach": [ "file1.jpg", "file2.jpg" ],
|
||||
"attachDescription": `Screenshots of game x`
|
||||
}
|
||||
```
|
||||
|
||||
An `attach` and its description are optional. Newlines using `\n` in a toot are allowed.
|
||||
|
||||
### Configuring the buddies
|
||||
|
||||
See `config.sample.js`. A config file should expose `buddies` as an array with the following structure:
|
||||
|
||||
```js
|
||||
{
|
||||
name: "buddyname", // same as the dir name
|
||||
buddy: "my cool buddy", // unique buddy id
|
||||
instance: "https://mastodon.social", // where to post to
|
||||
oauthToken: "my-token" // the oauth token for that server/user to post the status with
|
||||
}
|
||||
```
|
||||
|
||||
Optional config flags can be used in the chat function if desired.
|
||||
|
||||
There's a sanity check implemented: at minimum, each config should have name, buddy, instance, and oauthToken present.
|
||||
|
||||
## How to get an OAuth token from a Masto/Pleroma instance?
|
||||
|
||||
I've prepared a few utility functions in `registerApp.js` for you. First, call `await register()`, which prints an URL to go to. Next, fill in the client id, secret, and returned token, after granting the app access to read and write. Then, call `await fetchToken()`. Paste that token in the config file. Done!
|
||||
|
||||
Token refreshing is not (yet) implemented. Most tokens are valid for a year or so. Who knows what'll happen by then.
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
"form-data": "^4.0.0",
|
||||
"got": "^11.8.2",
|
||||
"jsdom": "^16.5.2",
|
||||
"md5": "^2.3.0"
|
||||
"md5": "^2.3.0",
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
|
@ -52,7 +52,7 @@ async function collectScreenshotsFor(game, buddyConfig) {
|
|||
|
||||
// for the gameboy: 10, 688 - see https://www.mobygames.com/browse/games/gameboy/list-games/
|
||||
async function collect(buddyConfig) {
|
||||
const { platform, totalAmountOfGamesForPlatform, mobyGamesToken } = buddyConfig
|
||||
const { platform, totalAmountOfGames = 600, mobyGamesToken } = buddyConfig
|
||||
|
||||
const overviewFile = `data/mobygames/games_${platform}.json`
|
||||
if(existsSync(overviewFile)) {
|
||||
|
@ -63,7 +63,7 @@ async function collect(buddyConfig) {
|
|||
|
||||
console.log(' -- mobygames: no overview json file found for platform, fetching...')
|
||||
const allGames = []
|
||||
for(let offset = 0; offset < totalAmountOfGamesForPlatform; offset += 100) {
|
||||
for(let offset = 0; offset < totalAmountOfGames; offset += 100) {
|
||||
console.log(` -- mobygames: fetching platform ${platform} offset ${offset}...`)
|
||||
const result = await axios.get(`${endpoint}/games?platform=${platform}&api_key=${mobyGamesToken}&offset=${offset}`)
|
||||
allGames.push(result.data.games)
|
||||
|
|
48
src/chat.js
48
src/chat.js
|
@ -1,4 +1,6 @@
|
|||
|
||||
const args = require('minimist')(process.argv.slice(2));
|
||||
|
||||
// the main juice
|
||||
|
||||
const { buddies } = require('./config')
|
||||
|
@ -6,18 +8,44 @@ if(!buddies) throw "Did you seutp your config?"
|
|||
|
||||
const { toot } = require('./toot');
|
||||
|
||||
(async function() {
|
||||
for await(buddyConfig of buddies) {
|
||||
console.log(`bootstrapping chat for ${buddyConfig.name}...`)
|
||||
const { chat } = require(`./buddies/${buddyConfig.name}/buddy`)
|
||||
|
||||
// contains 'toot', and maybe 'attach' / 'attachDescription'
|
||||
const message = await chat(buddyConfig)
|
||||
console.log(`buddy ${buddyConfig.name} has this to say: ${JSON.stringify(message)}`)
|
||||
function assertBuddyConfigCorrect(buddyConfig) {
|
||||
let errs = []
|
||||
[ 'name', 'buddy', 'instance', 'oauthToken' ].forEach(prop => {
|
||||
if(!buddyConfig[prop]) errs.push(`No '${prop}' property found`)
|
||||
})
|
||||
|
||||
await toot(message, buddyConfig)
|
||||
if(errs.length > 0) {
|
||||
console.error(`Whoops, a buddy is misconfigured: ${errs.join(', ')}. Exiting.`)
|
||||
process.exit(-1)
|
||||
}
|
||||
}
|
||||
|
||||
async function letBuddyChat(buddyConfig) {
|
||||
//assertBuddyConfigCorrect(buddyConfig)
|
||||
console.log(`bootstrapping chat for ${buddyConfig.name}...`)
|
||||
const { chat } = require(`./buddies/${buddyConfig.name}/buddy`)
|
||||
|
||||
// contains 'toot', and maybe 'attach' / 'attachDescription'
|
||||
const message = await chat(buddyConfig)
|
||||
console.log(`buddy ${buddyConfig.name} has this to say: ${JSON.stringify(message)}`)
|
||||
|
||||
await toot(message, buddyConfig)
|
||||
}
|
||||
|
||||
(async function() {
|
||||
if(args.buddy) {
|
||||
const config = buddies.find(b => b.buddy === args.buddy)
|
||||
if(!config) {
|
||||
console.error(`Whoops, you asked to let buddy "${args.buddy}" chat, but no config found? Exiting.`)
|
||||
process.exit(-1)
|
||||
}
|
||||
|
||||
await letBuddyChat(config)
|
||||
} else {
|
||||
for await(buddyConfig of buddies) {
|
||||
await letBuddyChat(buddyConfig)
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Done! for now... ')
|
||||
})()
|
||||
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
|
||||
// which ones are active?
|
||||
const buddies = [{
|
||||
buddy: "acvillagers",
|
||||
name: "animalcrossing",
|
||||
instance: "https://mastodon.social",
|
||||
oauthToken: "my-token"
|
||||
}, {
|
||||
buddy: "gblegacy",
|
||||
name: "mobygames",
|
||||
instance: "https://botsin.space",
|
||||
oauthToken: "my-token-for-botsin-space",
|
||||
|
|
Loading…
Reference in New Issue