-
Notifications
You must be signed in to change notification settings - Fork 1
/
AutoPostBot.ts
133 lines (112 loc) · 4.86 KB
/
AutoPostBot.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import * as dotenv from "dotenv"
import { BaseGeneratorPlugin } from "@/lib/BaseGeneratorPlugin"
import { BaseDestinationPlugin } from "@/lib/BaseDestinationPlugin"
dotenv.config()
export class AutoPostBot {
randomArticleChance: number
postMaxDelayInHours: number = 5
postMinDelayInHours: number = 0.5
initialDelayInSeconds: number = 1
private enabledGeneratorPlugins: string[] = []
private generatorPlugins: BaseGeneratorPlugin[] = []
private enabledDestinationPlugins: string[] = []
private destinationPlugins: BaseDestinationPlugin[] = []
constructor() {
this.postMaxDelayInHours = process.env.POST_MAX_DELAY_HOURS ? parseFloat(process.env.POST_MAX_DELAY_HOURS) : 0.5
this.postMinDelayInHours = process.env.POST_MIN_DELAY_HOURS ? parseFloat(process.env.POST_MIN_DELAY_HOURS) : 0.5
this.initialDelayInSeconds = process.env.INITIAL_DELAY_SECONDS ? parseFloat(process.env.INITIAL_DELAY_SECONDS) : 0
this.initialize = this.initialize.bind(this)
this.sendPost = this.sendPost.bind(this)
this.nextPost = this.nextPost.bind(this)
}
async sendPostToDestinations(Post: string) {
for (const destination of this.destinationPlugins) {
await destination.sendPost(Post)
}
}
async initialize() {
await this.loadPlugins()
if (!this.generatorPlugins.length) {
this.log("No generator plugins enabled. Exiting...")
await new Promise(resolve => setTimeout(resolve, 5000))
process.exit(1)
}
if (!this.destinationPlugins.length) {
this.log("No destination plugins enabled. Exiting...")
await new Promise(resolve => setTimeout(resolve, 5000))
process.exit(1)
}
if (this.initialDelayInSeconds > 0) {
process.stdout.write(`🤖 Starting in ${this.initialDelayInSeconds} seconds`)
// Pause for initial delay, show indicator every second, clear line before writing next indicator
for (let i = 0; i < this.initialDelayInSeconds; i++) {
process.stdout.write(`.`)
await new Promise(resolve => setTimeout(resolve, 1000))
}
console.log("")
} else {
this.log(`Starting...`)
}
await this.sendPost()
}
async loadPlugins() {
this.log("Loading plugins...")
const generators = process.env.ENABLED_GENERATORS!.split(",")
for (const generator of generators) {
const [plugin, chance] = generator.split(":")
const pluginClass = await import(`../dist/plugins/generators/${plugin}.js`)
.then(m => {
this.log(`...Loaded generator: ${plugin}`)
return m[plugin]
}).catch((err) => {
this.log(`Failed to load plugin: ${plugin}`)
this.log(err)
return undefined
})
const pluginInstance = new pluginClass({chance: parseFloat(chance)})
this.enabledGeneratorPlugins.push(plugin)
this.generatorPlugins.push(pluginInstance)
}
const destinations = process.env.ENABLED_DESTINATIONS!.split(",")
for (const destination of destinations) {
const pluginClass = await import(`../dist/plugins/destinations/${destination}.js`)
.then(m => {
this.log(`...Loaded destination: ${destination}`)
return m[destination]
}).catch((err) => {
this.log(`Failed to load plugin: ${destination}`)
this.log(err)
return undefined
})
const pluginInstance = new pluginClass()
this.enabledDestinationPlugins.push(destination)
this.destinationPlugins.push(pluginInstance)
}
}
nextPost() {
setTimeout(this.sendPost, ( 1000 * 60 * 60 * this.postMinDelayInHours ) + ( Math.random() * ( 1000 * 60 * 60 ) * this.postMaxDelayInHours ))
}
async sendPost() {
let plugin: BaseGeneratorPlugin | undefined
// pick random plugin based on plugin chance
while (!plugin) {
plugin = this.generatorPlugins[Math.floor(Math.random() * this.generatorPlugins.length)]
if (Math.random() > plugin.chance) {
plugin = undefined
}
}
this.log(`Rolled generator plugin: ${plugin.constructor.name}`)
const postContent = await plugin.generatePost()
if (!postContent) {
this.log("No Post generated.")
} else {
this.log(`Generated Post: ${postContent}`)
await this.sendPostToDestinations(postContent)
await plugin.confirmPostSent()
}
this.nextPost()
}
log(...args: any[]) {
console.log(`🤖`, ...args)
}
}