Skip to content

Commit e172ca3

Browse files
committed
feat: minRep and allowedGroups, closes #7 , closes #6
1 parent 8ce2a32 commit e172ca3

File tree

6 files changed

+112
-4
lines changed

6 files changed

+112
-4
lines changed

languages/en-GB/openai.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"error.need-x-reputation-to-mention": "You need at least %1 reputation for mentioning chatgpt"
3+
}

languages/en-US/openai.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"error.need-x-reputation-to-mention": "You need at least %1 reputation for mentioning chatgpt"
3+
}

lib/controllers.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
'use strict';
22

3+
const groups = require.main.require('./src/groups');
4+
35
const Controllers = module.exports;
46

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);
610
res.render('admin/plugins/openai', {
711
title: 'OpenAI',
12+
groups: groupsData,
813
});
914
};

library.js

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,21 @@ const user = require.main.require('./src/user');
1414
const messaging = require.main.require('./src/messaging');
1515
const api = require.main.require('./src/api');
1616
const privileges = require.main.require('./src/privileges');
17+
const groups = require.main.require('./src/groups');
18+
const sockets = require.main.require('./src/socket.io');
1719

1820
const plugin = module.exports;
1921

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+
2032
plugin.init = async (params) => {
2133
const { router /* , middleware , controllers */ } = params;
2234
const settings = await meta.settings.get('openai')
@@ -29,14 +41,23 @@ plugin.init = async (params) => {
2941
routeHelpers.setupAdminPageRoute(router, '/admin/plugins/openai', controllers.renderAdminPage);
3042
};
3143

44+
async function getSettings() {
45+
const settings = await meta.settings.get('openai')
46+
return {...defaults, ...settings };
47+
}
48+
3249
plugin.actionMentionsNotify = async function (hookData) {
3350
try {
3451
const { notification } = hookData;
3552
if (!notification) {
3653
return;
3754
}
3855

39-
const settings = (await meta.settings.get('openai')) || {};
56+
const settings = await getSettings();
57+
if (!await canUseOpenAI(notification.from, settings)) {
58+
return;
59+
}
60+
4061
const chatgptusername = settings['chatgpt-username'];
4162
const chatgptUid = await user.getUidByUsername(chatgptusername);
4263
if (!chatgptUid) {
@@ -79,7 +100,11 @@ plugin.actionMessagingSave = async function (hookData) {
79100
if (message.system) {
80101
return;
81102
}
82-
const settings = (await meta.settings.get('openai')) || {};
103+
const settings = await getSettings();
104+
if (!await canUseOpenAI(message.fromuid, settings)) {
105+
return;
106+
}
107+
83108
const chatgptusername = settings['chatgpt-username'];
84109
const chatgptUid = await user.getUidByUsername(chatgptusername);
85110
const { roomId, content, fromuid } = message;
@@ -140,6 +165,55 @@ plugin.actionMessagingSave = async function (hookData) {
140165
}
141166
};
142167

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+
143217
async function getMessageIds(roomId, uid, start, stop) {
144218
const isPublic = await db.getObjectField(`chat:room:${roomId}`, 'public');
145219
if (parseInt(isPublic, 10) === 1) {

plugin.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@
1111
"modules": {
1212
"../admin/plugins/openai.js": "./public/lib/admin.js"
1313
},
14-
"templates": "templates"
14+
"templates": "templates",
15+
"languages": "languages"
1516
}

templates/admin/plugins/openai.tpl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,28 @@
4141
</select>
4242
</div>
4343
</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>
4466
</form>
4567
</div>
4668

0 commit comments

Comments
 (0)