nodebb-plugin-openai 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/languages/en-GB/openai.json +3 -0
- package/languages/en-US/openai.json +3 -0
- package/lib/controllers.js +6 -1
- package/library.js +81 -2
- package/package.json +2 -2
- package/plugin.json +2 -1
- package/templates/admin/plugins/openai.tpl +22 -0
package/lib/controllers.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const groups = require.main.require('./src/groups');
|
|
4
|
+
|
|
3
5
|
const Controllers = module.exports;
|
|
4
6
|
|
|
5
|
-
Controllers.renderAdminPage = function (req, res/* , next */) {
|
|
7
|
+
Controllers.renderAdminPage = async function (req, res/* , next */) {
|
|
8
|
+
const groupsData = await groups.getNonPrivilegeGroups('groups:createtime', 0, -1);
|
|
9
|
+
groupsData.sort((a, b) => b.system - a.system);
|
|
6
10
|
res.render('admin/plugins/openai', {
|
|
7
11
|
title: 'OpenAI',
|
|
12
|
+
groups: groupsData,
|
|
8
13
|
});
|
|
9
14
|
};
|
package/library.js
CHANGED
|
@@ -13,9 +13,22 @@ const topics = require.main.require('./src/topics');
|
|
|
13
13
|
const user = require.main.require('./src/user');
|
|
14
14
|
const messaging = require.main.require('./src/messaging');
|
|
15
15
|
const api = require.main.require('./src/api');
|
|
16
|
+
const privileges = require.main.require('./src/privileges');
|
|
17
|
+
const groups = require.main.require('./src/groups');
|
|
18
|
+
const sockets = require.main.require('./src/socket.io');
|
|
16
19
|
|
|
17
20
|
const plugin = module.exports;
|
|
18
21
|
|
|
22
|
+
const defaults = {
|
|
23
|
+
apikey: '',
|
|
24
|
+
'chatgpt-username': '',
|
|
25
|
+
enablePrivateMessages: 'off',
|
|
26
|
+
model: 'gpt-3.5-turbo',
|
|
27
|
+
minimumReputation: 0,
|
|
28
|
+
allowedGroups: '[]',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
|
|
19
32
|
plugin.init = async (params) => {
|
|
20
33
|
const { router /* , middleware , controllers */ } = params;
|
|
21
34
|
const settings = await meta.settings.get('openai')
|
|
@@ -28,6 +41,11 @@ plugin.init = async (params) => {
|
|
|
28
41
|
routeHelpers.setupAdminPageRoute(router, '/admin/plugins/openai', controllers.renderAdminPage);
|
|
29
42
|
};
|
|
30
43
|
|
|
44
|
+
async function getSettings() {
|
|
45
|
+
const settings = await meta.settings.get('openai')
|
|
46
|
+
return {...defaults, ...settings };
|
|
47
|
+
}
|
|
48
|
+
|
|
31
49
|
plugin.actionMentionsNotify = async function (hookData) {
|
|
32
50
|
try {
|
|
33
51
|
const { notification } = hookData;
|
|
@@ -35,13 +53,21 @@ plugin.actionMentionsNotify = async function (hookData) {
|
|
|
35
53
|
return;
|
|
36
54
|
}
|
|
37
55
|
|
|
38
|
-
const settings =
|
|
56
|
+
const settings = await getSettings();
|
|
57
|
+
if (!await canUseOpenAI(notification.from, settings)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
39
61
|
const chatgptusername = settings['chatgpt-username'];
|
|
40
62
|
const chatgptUid = await user.getUidByUsername(chatgptusername);
|
|
41
63
|
if (!chatgptUid) {
|
|
42
64
|
return;
|
|
43
65
|
}
|
|
44
66
|
if (notification.tid && notification.bodyLong.startsWith(`@${chatgptusername}`)) {
|
|
67
|
+
const canReply = await privileges.topics.can('topics:reply', notification.tid, chatgptUid);
|
|
68
|
+
if (!canReply) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
45
71
|
const message = notification.bodyLong.replace(new RegExp(`^@${chatgptusername}`), '');
|
|
46
72
|
if (message.length) {
|
|
47
73
|
const response = await chatComplete(message);
|
|
@@ -74,7 +100,11 @@ plugin.actionMessagingSave = async function (hookData) {
|
|
|
74
100
|
if (message.system) {
|
|
75
101
|
return;
|
|
76
102
|
}
|
|
77
|
-
const settings =
|
|
103
|
+
const settings = await getSettings();
|
|
104
|
+
if (!await canUseOpenAI(message.fromuid, settings)) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
78
108
|
const chatgptusername = settings['chatgpt-username'];
|
|
79
109
|
const chatgptUid = await user.getUidByUsername(chatgptusername);
|
|
80
110
|
const { roomId, content, fromuid } = message;
|
|
@@ -135,6 +165,55 @@ plugin.actionMessagingSave = async function (hookData) {
|
|
|
135
165
|
}
|
|
136
166
|
};
|
|
137
167
|
|
|
168
|
+
async function canUseOpenAI(uid, settings) {
|
|
169
|
+
if (!await checkReputation(uid, settings)) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
if (!await checkGroupMembership(uid, settings)) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async function checkReputation(uid, settings) {
|
|
179
|
+
const reputation = await user.getUserField(uid, 'reputation');
|
|
180
|
+
const hasEnoughRep = parseInt(settings.minimumReputation, 10) === 0 || parseInt(reputation, 10) >= parseInt(settings.minimumReputation, 10);
|
|
181
|
+
|
|
182
|
+
if (!hasEnoughRep) {
|
|
183
|
+
sockets.server.in(`uid_${uid}`).emit('event:alert', {
|
|
184
|
+
type: 'danger',
|
|
185
|
+
title: '[[global:alert.error]]',
|
|
186
|
+
message: `[[openai:error.need-x-reputation-to-mention, ${settings.minimumReputation}]]`,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
return hasEnoughRep;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async function checkGroupMembership(uid, settings) {
|
|
193
|
+
let allowedGroups = [];
|
|
194
|
+
try {
|
|
195
|
+
allowedGroups = JSON.parse(settings.allowedGroups) || [];
|
|
196
|
+
} catch (err) {
|
|
197
|
+
console.error(err);
|
|
198
|
+
allowedGroups = [];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (!allowedGroups.length) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const isMembers = await groups.isMemberOfGroups(uid, allowedGroups);
|
|
206
|
+
const memberOfAny = isMembers.includes(true);
|
|
207
|
+
if (!memberOfAny) {
|
|
208
|
+
sockets.server.in(`uid_${uid}`).emit('event:alert', {
|
|
209
|
+
type: 'danger',
|
|
210
|
+
title: '[[global:alert.error]]',
|
|
211
|
+
message: `[[error:no-privileges]]`,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return memberOfAny;
|
|
215
|
+
}
|
|
216
|
+
|
|
138
217
|
async function getMessageIds(roomId, uid, start, stop) {
|
|
139
218
|
const isPublic = await db.getObjectField(`chat:room:${roomId}`, 'public');
|
|
140
219
|
if (parseInt(isPublic, 10) === 1) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodebb-plugin-openai",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A NodeBB OpenAI plugin",
|
|
5
5
|
"main": "library.js",
|
|
6
6
|
"repository": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"compatibility": "^3.2.0"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"openai": "4.53.
|
|
36
|
+
"openai": "4.53.2"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@commitlint/cli": "19.3.0",
|
package/plugin.json
CHANGED
|
@@ -41,6 +41,28 @@
|
|
|
41
41
|
</select>
|
|
42
42
|
</div>
|
|
43
43
|
</div>
|
|
44
|
+
<div class="">
|
|
45
|
+
<h5 class="fw-bold tracking-tight settings-header">Restrictions</h5>
|
|
46
|
+
|
|
47
|
+
<div class="mb-3">
|
|
48
|
+
<label class="form-label" for="minimumReputation">Minimum Reputation</label>
|
|
49
|
+
<input type="text" id="minimumReputation" name="minimumReputation" title="Minimum Reputation" class="form-control">
|
|
50
|
+
<p class="form-text">
|
|
51
|
+
Minimum reputation required to mention chatgpt user. (0 to disable)
|
|
52
|
+
</p>
|
|
53
|
+
</div>
|
|
54
|
+
<div class="mb-3">
|
|
55
|
+
<label class="form-label" form="allowedGroups">Allowed Groups</label>
|
|
56
|
+
<select class="form-select" multiple id="allowedGroups" name="allowedGroups" size="10">
|
|
57
|
+
{{{ each groups }}}
|
|
58
|
+
<option value="{./displayName}">{./displayName}</option>
|
|
59
|
+
{{{ end }}}
|
|
60
|
+
</select>
|
|
61
|
+
<p class="form-text">
|
|
62
|
+
Only users in these groups will be able to mention the chatgpt user. Leave blank to allow all groups.
|
|
63
|
+
</p>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
44
66
|
</form>
|
|
45
67
|
</div>
|
|
46
68
|
|