mirror of
https://github.com/vicstu/obsidian_max_sync.git
synced 2026-07-22 08:31:03 +00:00
17 lines
10 KiB
JavaScript
17 lines
10 KiB
JavaScript
/*
|
|
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
if you want to view the source, please visit the github repository of this plugin
|
|
*/
|
|
|
|
"use strict";var v=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var H=Object.getOwnPropertyNames;var G=Object.prototype.hasOwnProperty;var V=(t,e)=>{for(var n in e)v(t,n,{get:e[n],enumerable:!0})},Y=(t,e,n,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of H(e))!G.call(t,r)&&r!==n&&v(t,r,{get:()=>e[r],enumerable:!(s=j(e,r))||s.enumerable});return t};var z=t=>Y(v({},"__esModule",{value:!0}),t);var ie={};V(ie,{default:()=>w});module.exports=z(ie);var S=require("obsidian");var a=require("obsidian");var b=require("obsidian");var A="https://bots-and-pages-myeasycoding.amvera.io",p=`**{{sender}}** \xB7 {{date}} {{time}}
|
|
{{text}}
|
|
{{attachment}}
|
|
{{transcription}}`,g="MAX/Inbox.md",d="MAX/template.md",h={userToken:"",targetFile:g,templateFile:d,attachmentsFolder:"Attachments"};function P(t){let e={...h,...t,targetFile:t?.targetFile?.trim()||g,templateFile:t?.templateFile?.trim()||d};return!e.userToken&&t?.apiSecretKey&&(e.userToken=""),e}var l=class{constructor(e){this.settings=e}buildUrl(e){return`${A.replace(/\/+$/,"")}${e}`}authHeaders(){return{"X-API-Key":this.settings.userToken}}async request(e){if(!this.settings.userToken.trim())throw new Error("User Token is not configured. Send /token to the MAX bot.");return(0,b.requestUrl)({...e,headers:{...this.authHeaders(),...e.headers}})}async checkHealth(){let e=await(0,b.requestUrl)({url:this.buildUrl("/health"),method:"GET"});if(e.status!==200)throw new Error(`HTTP ${e.status}`);if(e.json.status!=="ok")throw new Error("Unexpected health response")}async verifyToken(){let e=await this.request({url:this.buildUrl("/api/me"),method:"GET"});if(e.status!==200)throw new Error(`Invalid user token: HTTP ${e.status}`);let n=e.json;if(n.user_id==null)throw new Error("User id not returned");return n}async checkConnection(){let e={serverOk:!1,tokenOk:!1};try{await this.checkHealth(),e.serverOk=!0}catch(n){return e.serverError=n instanceof Error?n.message:String(n),e}if(!this.settings.userToken.trim())return e.tokenError="User Token is not configured",e;try{e.user=await this.verifyToken(),e.tokenOk=e.user.user_id!=null}catch(n){e.tokenError=n instanceof Error?n.message:String(n)}return e}async fetchMessages(e){let n=await this.request({url:this.buildUrl("/api/messages/sync"),method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({limit:e.limit})});if(n.status!==200)throw new Error(`Failed to fetch messages: HTTP ${n.status}`);return n.json}async markProcessed(e){if(e.length===0)return{updated:0,message_ids:[]};let n=await this.request({url:this.buildUrl("/api/messages/mark-processed"),method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message_ids:e})});if(n.status!==200)throw new Error(`Failed to mark messages synced: HTTP ${n.status}`);return n.json}async downloadMedia(e){let n=e.replace(/^\/+/,""),s=await this.request({url:this.buildUrl(`/api/media/${n}`),method:"GET"});if(s.status!==200)throw new Error(`Failed to download media: HTTP ${s.status}`);return s.arrayBuffer}};var f=class extends a.PluginSettingTab{constructor(e,n){super(e,n),this.plugin=n}display(){let{containerEl:e}=this;e.empty(),new a.Setting(e).setName("Max user token").setDesc("Personal token from the MAX bot (/token). Grants access only to your messages.").addText(n=>n.setPlaceholder("paste token from /token command").setValue(this.plugin.settings.userToken).onChange(async s=>{this.plugin.settings.userToken=s.trim(),await this.plugin.saveSettings()})),new a.Setting(e).setName("Connection check").setDesc("Checks server availability and token registration").addButton(n=>{n.setButtonText("Check").onClick(async()=>{n.setDisabled(!0);try{let s=await new l(this.plugin.settings).checkConnection();if(!s.serverOk){new a.Notice("Server unavailable",8e3);return}if(!s.tokenOk){new a.Notice("Server is up. Token not found.",8e3);return}new a.Notice("Server is up. Token registered.",8e3)}catch(s){let r=s instanceof Error?s.message:String(s);new a.Notice(`Connection check failed: ${r}`,8e3)}finally{n.setDisabled(!1)}})}),new a.Setting(e).setName("Template file").setDesc("Path to a .md file with the message template. Variables: {{date}}, {{time}}, {{created}}, {{sender}}, {{sender_id}}, {{message_id}}, {{type}}, {{text}}, {{attachment}}, {{transcription}}, {{tags}}").addText(n=>n.setPlaceholder(d).setValue(this.plugin.settings.templateFile).onChange(async s=>{this.plugin.settings.templateFile=s.trim()||d,await this.plugin.saveSettings()})),new a.Setting(e).setName("Target file").setDesc("Path to a file in the vault. New messages are appended to the end").addText(n=>n.setPlaceholder(g).setValue(this.plugin.settings.targetFile).onChange(async s=>{this.plugin.settings.targetFile=s.trim()||g,await this.plugin.saveSettings()})),new a.Setting(e).setName("Attachments Folder").setDesc("Folder where media files will be saved").addText(n=>n.setPlaceholder(h.attachmentsFolder).setValue(this.plugin.settings.attachmentsFolder).onChange(async s=>{this.plugin.settings.attachmentsFolder=s.trim()||h.attachmentsFolder,await this.plugin.saveSettings()}))}};function F(t){return P(t)}var c=require("obsidian");var K={image:"photo",audio:"voice",file:"document",document:"document",photo:"photo",voice:"voice",video:"video",text:"text",sticker:"sticker"},J=new Set(["photo","voice","video"]);function M(t){if(t.type)return t.type;let e=t.media_type?.toLowerCase();return!e||e==="text"?"text":K[e]??e}function Z(t){return t.transcribed!==void 0?t.transcribed:!!t.transcribed_text?.trim()}function W(t){let e=[],n=new Set,s=i=>{let o=i.trim().replace(/^#+/,"").toLowerCase();!o||n.has(o)||(n.add(o),e.push(o))};s("max");let r=M(t);if(J.has(r)&&s(r),t.tags)for(let i of t.tags.split(","))s(i);return Z(t)&&s("transcribed"),e}function y(t){return t.replace(/[<>:"/\\|?*]/g,"_").replace(/\s+/g,"_")}function T(t){let e=t.trim();if(!e)return null;let s=e.endsWith("Z")||/[+-]\d{2}:\d{2}$/.test(e)?e:`${e}Z`,r=new Date(s);return Number.isNaN(r.getTime())?null:r}function C(t){return T(t)?.getTime()??Date.now()}function u(t){return String(t).padStart(2,"0")}function Q(t){return T(t)?`${R(t)} ${$(t)}`:t}function R(t){let e=T(t);return e?[u(e.getDate()),u(e.getMonth()+1),e.getFullYear()].join("."):t}function $(t){let e=T(t);return e?[u(e.getHours()),u(e.getMinutes()),u(e.getSeconds())].join(":"):t}function ee(t,e){if(!e)return"";let n=M(t);return n==="photo"?`![[${e}]]`:n==="voice"?`\u{1F3A4} ![[${e}]]`:n==="video"?`\u{1F3AC} ![[${e}]]`:`\u{1F4CE} ![[${e}]]`}function te(t){return t.transcribed_text?.trim()?`## Transcription
|
|
${t.transcribed_text.trim()}`:""}function ne(t,e,n){let s=M(t),r=W(t);return{created:Q(t.created_at),date:R(t.created_at),time:$(t.created_at),sender:t.sender_name?.trim()||"Unknown",sender_id:String(t.sender_id),message_id:t.message_id,type:s,text:t.text?.trim()||"",attachment:ee(t,n),transcription:te(t),tags:r.map(i=>`#${i}`).join(" ")}}function se(t,e){return t.replace(/\{\{(\w+)\}\}/g,(n,s)=>e[s]??"")}function U(t,e,n,s){let r=s.trim()||p,i=ne(t,e,n);return se(r,i).trim()}function _(){return`# MAX Inbox
|
|
`}function E(t,e){let n=t.trimEnd();return n?`${n}
|
|
|
|
${e}
|
|
`:`${_().trimEnd()}
|
|
|
|
${e}
|
|
`}function L(t,e,n){let s=y(n||e.file_name||e.message_id);return`${t.attachmentsFolder}/${s}`}function N(t){if(M(t)==="photo")return y(`${t.message_id}.webp`);if(t.file_name?.trim())return y(t.file_name.trim());let n={voice:"ogg",audio:"ogg",video:"mp4",document:"bin",file:"bin"},s=t.media_type?.toLowerCase()??"",r=n[s]??"bin";return y(`${t.message_id}.${r}`)}var D=require("obsidian");async function B(t,e){let n=e.templateFile.trim();if(!n)return p;let s=t.vault.getAbstractFileByPath(n);if(!(s instanceof D.TFile))throw new Error(`Template file not found: ${n}`);let r=(await t.vault.read(s)).trim();if(!r)throw new Error(`Template file is empty: ${n}`);return r}async function X(t,e){let n=e.replace(/\\/g,"/").split("/").filter(Boolean),s="";for(let r of n)s=s?`${s}/${r}`:r,t.vault.getAbstractFileByPath(s)||await t.vault.createFolder(s)}async function re(t,e){let n=e.replace(/\\/g,"/").split("/").filter(Boolean);n.length<=1||await X(t,n.slice(0,-1).join("/"))}var x=class{constructor(e,n){this.app=e;this.settings=n}createClient(){return new l(this.settings)}async syncNewMessages(){await this.syncMessages({limit:50,label:"new"})}async syncMessages(e){let n=this.createClient();try{let s=await n.fetchMessages({limit:e.limit});if(s.count===0){new c.Notice("MAX: no new messages");return}await X(this.app,this.settings.attachmentsFolder),await re(this.app,this.settings.targetFile);let r=await B(this.app,this.settings),i=0;for(let o of s.messages)await this.importMessage(n,o,r),await n.markProcessed([o.message_id]),i+=1;new c.Notice(`MAX: imported ${i} ${e.label} message(s)`)}catch(s){let r=s instanceof Error?s.message:String(s);new c.Notice(`MAX sync failed: ${r}`),console.error("MAX sync failed:",s)}}async importMessage(e,n,s){let r=this.settings.targetFile.trim();if(!r)throw new Error("Target file is not configured");let i=this.app.vault.getAbstractFileByPath(r),o="";i instanceof c.TFile&&(o=await this.app.vault.read(i));let m=await this.resolveAttachment(e,n),k=U(n,this.settings,m,s);if(i instanceof c.TFile){let q=E(o,k);await this.app.vault.modify(i,q);return}let O=_(),I=E(O,k);await this.app.vault.create(r,I)}async resolveAttachment(e,n){if(!n.media_url)return null;try{return await this.downloadAttachment(e,n)}catch(s){return console.error("MAX attachment download failed:",s),new c.Notice(`MAX: attachment not saved for ${n.message_id}`,5e3),null}}async downloadAttachment(e,n){let s=N(n),r=L(this.settings,n,s);if(this.app.vault.getAbstractFileByPath(r)instanceof c.TFile)return r;let o=await e.downloadMedia(n.media_url),m=C(n.created_at);return await this.app.vault.createBinary(r,o,{ctime:m,mtime:m}),r}};var w=class extends S.Plugin{async onload(){await this.loadSettings(),this.addSettingTab(new f(this.app,this)),this.addCommand({id:"max-sync-new-messages",name:"Fetch new messages",callback:()=>{this.syncNewMessages()}})}onunload(){}async loadSettings(){this.settings=F(await this.loadData())}async saveSettings(){await this.saveData(this.settings)}createSyncService(){return new x(this.app,this.settings)}async syncNewMessages(){new S.Notice("MAX: fetching new messages..."),await this.createSyncService().syncNewMessages()}};
|