aboutsummaryrefslogtreecommitdiff
path: root/src/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/index.ts')
-rw-r--r--src/index.ts156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..f3dcd0f
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,156 @@
+import joplin from 'api';
+import { SettingItemType, ModelType, ToastType } from 'api/types';
+
+enum ItemChangeEventType {
+ create = 1,
+ update = 2,
+ delete = 3
+}
+
+const settingObjs = {
+ 'HooksEnabled': {
+ value: false,
+ type: SettingItemType.Bool,
+ section: 'WebAngling',
+ public: true,
+ label: 'Enable Webhooks. Must also enable Note Changes or Resource Changes.'
+ },
+ "URL": {
+ value: null,
+ type: SettingItemType.String,
+ section: 'WebAngling',
+ public: true,
+ label: 'Webhook URL.'
+ },
+ "Method": {
+ value: false,
+ type: SettingItemType.String,
+ section: 'WebAngling',
+ public: true,
+ label: 'HTTP Method to use sending webhook (e.g., POST, GET).',
+ isEnum: true,
+ options: {
+ 'POST': 'POST',
+ 'GET': 'GET',
+ },
+ },
+ "NoteChangesEnabled": {
+ value: false,
+ type: SettingItemType.Bool,
+ section: 'WebAngling',
+ public: true,
+ label: 'Send Webhooks on note changes.'
+ },
+ "ResourceChangesEnabled": {
+ value: false,
+ type: SettingItemType.Bool,
+ section: 'WebAngling',
+ public: true,
+ label: 'Send Webhooks on resource changes.'
+ },
+ "IncludeTitle": {
+ value: true,
+ type: SettingItemType.Bool,
+ section: 'WebAngling',
+ public: true,
+ label: 'Include Note/Resource title in webhook payload.'
+ }
+}
+
+async function registerSettings(){
+ await joplin.settings.registerSection('WebAngling', {
+ label: 'Web Angling',
+ iconName: 'fas fa-fish',
+ });
+ await joplin.settings.registerSettings(settingObjs)
+}
+
+async function onEvent(
+ event_type: string,
+ id: string,
+ change_type="Update",
+){
+ const anglerSettings = await joplin.settings.values(Object.keys(settingObjs));
+
+ if(!anglerSettings["HooksEnabled"]){
+ return
+ }
+
+ const obj_type = ModelType[await joplin.data.itemType(id)]
+ let title = undefined;
+ if(obj_type == "Note"){
+ if(!anglerSettings["NoteChangesEnabled"]){
+ return
+ }
+ if(anglerSettings["IncludeTitle"]){
+ const note = await joplin.data.get(['notes', id], { fields: ['title'] });
+ title = note.title
+ }
+ } else {
+ if(!anglerSettings["ResourceChangesEnabled"]){
+ return
+ }
+ }
+
+ const payload = {
+ object_type: obj_type,
+ object_id: id,
+ change_type: change_type,
+ title: title
+ }
+ try {
+ await doFetch(
+ anglerSettings["URL"],
+ payload,
+ anglerSettings["Method"] as string,
+ {},
+ "application/json",
+ )
+ } catch (error) {
+ await joplin.views.dialogs.showToast(
+ {
+ message: `Webhook error ${error.message}`,
+ type: ToastType.Error,
+ duration: 5000,
+ }
+ );
+ }
+}
+
+async function doFetch(url, payload, method = 'POST', headers = {}, contentType = 'application/json') {
+ const finalHeaders = {
+ 'Content-Type': contentType,
+ ...headers,
+ };
+
+ try {
+ const response = await fetch(url, {
+ method: method,
+ headers: finalHeaders,
+ body: contentType === 'application/json' ? JSON.stringify(payload) : payload,
+ });
+
+ if (!response.ok) {
+ throw new Error(`Webhook request failed with status ${response.status}`);
+ }
+
+ return response;
+ } catch (error) {
+ console.error("Webhook request error:", error);
+ throw error;
+ }
+}
+
+joplin.plugins.register({
+ onStart: async function() {
+ await registerSettings()
+
+ await joplin.workspace.onNoteChange(async (e) => {
+ await onEvent("note", e.id, ItemChangeEventType[e.event])
+ });
+
+ await joplin.workspace.onResourceChange(async (e) => {
+ await onEvent("resource", e.id, "update")
+ });
+ },
+});