From fe78d4faf05aa8a9880a63afebc5e117f611b999 Mon Sep 17 00:00:00 2001 From: Mark Sinclair Date: Tue, 10 Jan 2023 16:23:42 +0000 Subject: [PATCH] GitHub Actions: support sending notification messages to matrix --- .github/workflows/support-files/.env.example | 6 ++ .github/workflows/support-files/.gitignore | 4 +- .../notifications/send_message.js | 26 ++++++ .../notifications/send_message_to_matrix.js | 81 +++++++++++++++++++ .github/workflows/support-files/package.json | 10 ++- 5 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/support-files/notifications/send_message_to_matrix.js diff --git a/.github/workflows/support-files/.env.example b/.github/workflows/support-files/.env.example index f869af7605..82e3526223 100644 --- a/.github/workflows/support-files/.env.example +++ b/.github/workflows/support-files/.env.example @@ -2,6 +2,12 @@ KEYBASE_NYM_CHANNEL= KEYBASE_NYMBOT_USERNAME= KEYBASE_NYMBOT_PAPERKEY= +MATRIX_SERVER= +MATRIX_ROOM= +MATRIX_USER_ID= +MATRIX_TOKEN= +MATRIX_DEVICE_ID= + NYM_NOTIFICATION_KIND=nightly NYM_PROJECT_NAME=Nightly Build diff --git a/.github/workflows/support-files/.gitignore b/.github/workflows/support-files/.gitignore index 2ca1a3414b..37f81d053b 100644 --- a/.github/workflows/support-files/.gitignore +++ b/.github/workflows/support-files/.gitignore @@ -2,4 +2,6 @@ node_modules .idea # don't commit the lock file to avoid cross-platform issues -package-lock.json \ No newline at end of file +package-lock.json + +scratch \ No newline at end of file diff --git a/.github/workflows/support-files/notifications/send_message.js b/.github/workflows/support-files/notifications/send_message.js index 671e40bd84..4a6c0fb6af 100644 --- a/.github/workflows/support-files/notifications/send_message.js +++ b/.github/workflows/support-files/notifications/send_message.js @@ -1,6 +1,7 @@ require('dotenv').config(); const Bot = require('keybase-bot'); +const { sendMatrixMessage } = require('./send_message_to_matrix'); let context = { kinds: ['nym-wallet', 'ts-packages', 'network-explorer', 'nightly', 'nym-connect','security'], @@ -38,6 +39,28 @@ function validateContext() { 'Paperkey is not defined. Please set env var KEYBASE_NYMBOT_PAPERKEY', ); } + if (context.env.MATRIX_ROOM) { + if (!context.env.MATRIX_SERVER) { + throw new Error( + 'Matrix server is not defined. Please set env var MATRIX_SERVER', + ); + } + if (!context.env.MATRIX_USER_ID) { + throw new Error( + 'Matrix user id is not defined. Please set env var MATRIX_USER_ID', + ); + } + if (!context.env.MATRIX_TOKEN) { + throw new Error( + 'Matrix token is not defined. Please set env var MATRIX_TOKEN', + ); + } + if (!context.env.MATRIX_DEVICE_ID) { + throw new Error( + 'Matrix device id is not defined. Please set env var MATRIX_DEVICE_ID', + ); + } + } } /** @@ -147,6 +170,9 @@ async function main() { console.log('-----------------------------------------'); } await sendKeybaseMessage(messageBody); + if(context.env.MATRIX_ROOM) { + await sendMatrixMessage(context, messageBody, context.env.MATRIX_ROOM) + } } // call main function and let NodeJS handle the promise diff --git a/.github/workflows/support-files/notifications/send_message_to_matrix.js b/.github/workflows/support-files/notifications/send_message_to_matrix.js new file mode 100644 index 0000000000..85f1849b93 --- /dev/null +++ b/.github/workflows/support-files/notifications/send_message_to_matrix.js @@ -0,0 +1,81 @@ +const sdk = require('matrix-js-sdk'); +global.Olm = require('olm'); +const { LocalStorage } = require('node-localstorage'); +const localStorage = new LocalStorage('./scratch'); +const { + LocalStorageCryptoStore, +} = require('matrix-js-sdk/lib/crypto/store/localStorage-crypto-store'); + +const vfile = require('to-vfile'); +const unified = require('unified'); +const remarkParse = require('remark-parse'); +const remarkHtml = require('remark-html'); +const emoji = require('remark-emoji'); + +// hide all matrix client output +console.error = (error) => console.log('❌ error: ', error); +process.stderr.write = () => {}; +process.stdout.write = () => {}; + + +function createClient(context, room, message) { + const server = context.env.MATRIX_SERVER; + const token = context.env.MATRIX_TOKEN; + const deviceId = context.env.MATRIX_DEVICE_ID; + const userId = context.env.MATRIX_USER_ID; + + const client = sdk.createClient({ + baseUrl: server, + accessToken: token, + userId, + deviceId, + sessionStore: new sdk.WebStorageSessionStore(localStorage), + cryptoStore: new LocalStorageCryptoStore(localStorage), + }); + + client.on('sync', async function(state, prevState, res) { + if (state !== 'PREPARED') return; + client.setGlobalErrorOnUnknownDevices(false); + try { + await client.joinRoom(room); + await client.sendEvent( + room, + 'm.room.message', + { + msgtype: 'm.text', + format: 'org.matrix.custom.html', + body: message, + formatted_body: message, + }, + '', + ); + } catch (error) { + console.error('Job failed: ' + error.message); + } + client.stopClient(); + process.exit(0); + }); + + return client; +} + +async function markdownToHtml(messageAsMarkdown) { + const file = await unified() + .use(emoji) + .use(remarkParse) + .use(remarkHtml) + .process(await vfile({ path: 'test.md', contents: messageAsMarkdown})); + console.log({file}); + return String(file); +} + +async function sendMatrixMessage(contextArg, messageAsMarkdown, roomId) { + const messageAsHtml = await markdownToHtml(messageAsMarkdown); + const client = createClient(contextArg, roomId, messageAsHtml); + await client.initCrypto(); + await client.startClient({ initialSyncLimit: 1 }); +} + +module.exports = { + sendMatrixMessage, +}; diff --git a/.github/workflows/support-files/package.json b/.github/workflows/support-files/package.json index b73f32259d..8f20c34091 100644 --- a/.github/workflows/support-files/package.json +++ b/.github/workflows/support-files/package.json @@ -11,7 +11,15 @@ "dotenv": "^16.0.0", "handlebars": "^4.7.7", "keybase-bot": "^3.6.1", - "octokit": "^1.7.1" + "matrix-js-sdk": "^9.3.0", + "node-localstorage": "^2.1.6", + "octokit": "^1.7.1", + "olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz", + "remark-emoji": "^2.2.0", + "remark-html": "^13.0.2", + "remark-parse": "^9.0.0", + "to-vfile": "^6.1.0", + "unified": "^9.2.2" }, "devDependencies": { "prettier": "2.3.2"