-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
156 lines (133 loc) · 3.68 KB
/
index.js
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import { Configuration, OpenAIApi } from 'openai'
import { getPageRpi } from '@epaperjs/core'
import { Rpi7In5V2 } from '@epaperjs/rpi-7in5-v2'
import * as mqtt from 'mqtt'
import express from 'express'
import path from 'path'
import { fileURLToPath } from 'url'
import { login } from 'masto'
import dotenv from 'dotenv'
dotenv.config()
const client = mqtt.connect(process.env.MQTT_HOST, {
username: process.env.MQTT_USER,
password: process.env.MQTT_PASSWORD,
clientId: process.env.CLIENT_ID,
clean: false,
reconnectPeriod: 1,
})
let msg = ''
let hasRequest = false
const configuration = new Configuration({ apiKey: process.env.OPENAI_API_KEY })
const openai = new OpenAIApi(configuration)
async function handleTouch() {
if (hasRequest) return
hasRequest = true
console.log('making api call to chatgpt')
const generatedArt = await getCompletionFromOpenAI()
client.publish('art', JSON.stringify(generatedArt))
hasRequest = false
}
async function getCompletionFromOpenAI() {
try {
const completion = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
temperature: 1.2,
messages: [
{
role: 'user',
content: process.env.OPENAI_CONTENT,
},
],
})
console.log(completion.data.choices[0].message.content)
return completion.data.choices[0].message.content
} catch (error) {
if (error.response) {
console.log(error.response.status)
console.log(error.response.data)
} else {
console.log(error.message)
}
}
}
async function tootArt(msg) {
// TIL mastodon cannot handle messages over 500 char
if (msg.length > 500) return
// setup mastodon
const masto = await login({
url: process.env.URL,
accessToken: process.env.TOKEN,
})
await masto.v1.statuses.create({
status: msg,
visibility: 'public',
})
console.log('Tooted!')
}
function getDisplay() {
return new Rpi7In5V2()
}
async function refreshDisplay() {
const displayDevice = getDisplay()
displayDevice.connect()
if (msg === '') return
const browserPage = await getPageRpi(
displayDevice.width,
displayDevice.height
)
const url = 'http://localhost:3000'
const imgOfUrl = await browserPage.screenshot(url, {
delay: 2000,
})
console.log('Waking up display')
console.log('msg: ', msg)
displayDevice.wake()
console.log(`Displaying ${url}`)
await displayDevice.displayPng(imgOfUrl)
displayDevice.sleep()
console.log('Putting display into low power mode')
}
// prints a received message
client.on('message', function (topic, payload) {
console.log(topic.toString(), payload.toString())
if (topic === 'art') {
console.log('New art!')
msg = JSON.parse(payload.toString())
tootArt(msg)
refreshDisplay()
} else if (topic === process.env.TOUCH_TOPIC) {
console.log('handleTouch')
handleTouch()
}
})
// reassurance that the connection worked
client.on('connect', () => {
console.log('Connected!')
refreshDisplay()
console.log('Display ready')
})
// prints an error message
client.on('error', (error) => {
console.log('Error:', error)
})
// MQTT pub/sub
// subscribe and publish to the same topic
client.subscribe('art')
client.subscribe(process.env.TOUCH_TOPIC)
// Local server
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const dir = path.join(__dirname, '/ui')
const port = 3000
const app = express()
// set the view engine to ejs
app.set('view engine', 'ejs', { async: true })
app.get('/', async (req, res) => {
res.render(path.join(dir, 'index'), {
chatbot_love_msg: msg,
})
console.log('Rendering index')
})
app.listen(port, function () {
console.log('Listening on http://localhost:3000/')
})