blob: 145a68909188042cb7425b9112740bb7c05a0028 [file] [log] [blame]
Marc Kupietz2f17a762025-12-06 11:45:49 +01001const crypto = require('crypto');
2
3const nc_talk_url = process.env.NC_TALK_URL || 'https://cloud.ids-mannheim.de';
4const nc_talk_conversation = process.env.NC_TALK_CONVERSATION;
5const nc_talk_secret = process.env.NC_TALK_SECRET;
6
7// Function to send message to Nextcloud Talk
8async function sendToNextcloudTalk(message, silent = false, screenshotPath = null) {
9 if (!nc_talk_conversation || !nc_talk_secret) {
10 return;
11 }
12
13 try {
14 const axios = require('axios');
15 const fs = require('fs');
16 const sharp = require('sharp');
17
18 let fullMessage = message;
19 const MAX_MESSAGE_LENGTH = 32000; // Nextcloud Talk message size limit
20
21 // If a screenshot path is provided, try to embed it
22 if (screenshotPath && fs.existsSync(screenshotPath)) {
23 try {
24 // First, try to resize the image to reduce size
25 const resizedBuffer = await sharp(screenshotPath)
26 .resize(800, null, { // Resize to max width of 800px, maintain aspect ratio
27 withoutEnlargement: true,
28 fit: 'inside'
29 })
30 .png({ quality: 80, compressionLevel: 9 })
31 .toBuffer();
32
33 const base64Image = resizedBuffer.toString('base64');
34 const dataUri = `data:image/png;base64,${base64Image}`;
35 const messageWithImage = `${message}\n\n![Screenshot](${dataUri})`;
36
37 // Check if the message with image fits within the limit
38 if (messageWithImage.length <= MAX_MESSAGE_LENGTH) {
39 fullMessage = messageWithImage;
40 console.log(`Screenshot will be embedded (message size: ${messageWithImage.length} chars)`);
41 } else {
42 console.log(`Screenshot too large (${messageWithImage.length} chars), sending text-only notification`);
43 fullMessage = `${message}\n\n_Screenshot available locally but too large to embed (${Math.round(messageWithImage.length / 1024)}KB)_`;
44 }
45 } catch (imageError) {
46 console.error('Failed to process screenshot for Nextcloud Talk:', imageError.message);
47 fullMessage = `${message}\n\n_Screenshot available locally but could not be processed_`;
48 }
49 }
50
51 // Generate random header and signature
52 const randomHeader = crypto.randomBytes(32).toString('hex');
53 const messageToSign = randomHeader + fullMessage;
54 const signature = crypto.createHmac('sha256', nc_talk_secret)
55 .update(messageToSign)
56 .digest('hex');
57
58 // Send the message
59 await axios.post(
60 `${nc_talk_url}/ocs/v2.php/apps/spreed/api/v1/bot/${nc_talk_conversation}/message`,
61 {
62 message: fullMessage,
63 silent: silent
64 },
65 {
66 headers: {
67 'Content-Type': 'application/json',
68 'Accept': 'application/json',
69 'OCS-APIRequest': 'true',
70 'X-Nextcloud-Talk-Bot-Random': randomHeader,
71 'X-Nextcloud-Talk-Bot-Signature': signature
72 }
73 }
74 );
75 console.log('Message sent to Nextcloud Talk successfully');
76 } catch (error) {
77 console.error('Failed to send message to Nextcloud Talk:', error.message);
78 }
79}
80
81function ifConditionIt(title, condition, test) {
82 if (typeof it !== 'function') {
83 const { it } = require('mocha');
84 return condition ? it(title, test) : it.skip(title + " (skipped)", test)
85 }
86 return condition ? it(title, test) : it.skip(title + " (skipped)", test)
87}
88
89module.exports = {
90 sendToNextcloudTalk,
91 ifConditionIt,
92 nc_talk_conversation,
93 nc_talk_secret
94};