diff --git a/composer-bot-extensions/composer-bot-extensions/content.js b/composer-bot-extensions/composer-bot-extensions/content.js index 1efd39d..76daa7e 100644 --- a/composer-bot-extensions/composer-bot-extensions/content.js +++ b/composer-bot-extensions/composer-bot-extensions/content.js @@ -3,4 +3,4 @@ const D={GET_CONVERSATIONS:"messages.get-conversations",GET_CONVERSATION:"messag `)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...n){const r=new this(e);return n.forEach(s=>r.set(s)),r}static accessor(e){const r=(this[Ne]=this[Ne]={accessors:{}}).accessors,s=this.prototype;function o(i){const a=$(i);r[a]||(xn(s,i),r[a]=!0)}return l.isArray(e)?e.forEach(o):o(e),this}};v.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);l.reduceDescriptors(v.prototype,({value:t},e)=>{let n=e[0].toUpperCase()+e.slice(1);return{get:()=>t,set(r){this[n]=r}}});l.freezeMethods(v);function le(t,e){const n=this||W,r=e||n,s=v.from(r.headers);let o=r.data;return l.forEach(t,function(a){o=a.call(n,o,s.normalize(),e?e.status:void 0)}),s.normalize(),o}function nt(t){return!!(t&&t.__CANCEL__)}function H(t,e,n){w.call(this,t??"canceled",w.ERR_CANCELED,e,n),this.name="CanceledError"}l.inherits(H,w,{__CANCEL__:!0});function rt(t,e,n){const r=n.config.validateStatus;!n.status||!r||r(n.status)?t(n):e(new w("Request failed with status code "+n.status,[w.ERR_BAD_REQUEST,w.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}function Nn(t){const e=/^([-+\w]{1,25})(:?\/\/|:)/.exec(t);return e&&e[1]||""}function Pn(t,e){t=t||10;const n=new Array(t),r=new Array(t);let s=0,o=0,i;return e=e!==void 0?e:1e3,function(f){const c=Date.now(),u=r[o];i||(i=c),n[s]=f,r[s]=c;let d=o,m=0;for(;d!==s;)m+=n[d++],d=d%t;if(s=(s+1)%t,s===o&&(o=(o+1)%t),c-i{n=u,s=null,o&&(clearTimeout(o),o=null),t(...c)};return[(...c)=>{const u=Date.now(),d=u-n;d>=r?i(c,u):(s=c,o||(o=setTimeout(()=>{o=null,i(s)},r-d)))},()=>s&&i(s)]}const Z=(t,e,n=3)=>{let r=0;const s=Pn(50,250);return In(o=>{const i=o.loaded,a=o.lengthComputable?o.total:void 0,f=i-r,c=s(f),u=i<=a;r=i;const d={loaded:i,total:a,progress:a?i/a:void 0,bytes:f,rate:c||void 0,estimated:c&&a&&u?(a-i)/c:void 0,event:o,lengthComputable:a!=null,[e?"download":"upload"]:!0};t(d)},n)},Pe=(t,e)=>{const n=t!=null;return[r=>e[0]({lengthComputable:n,total:t,loaded:r}),e[1]]},Ie=t=>(...e)=>l.asap(()=>t(...e)),Mn=_.hasStandardBrowserEnv?((t,e)=>n=>(n=new URL(n,_.origin),t.protocol===n.protocol&&t.host===n.host&&(e||t.port===n.port)))(new URL(_.origin),_.navigator&&/(msie|trident)/i.test(_.navigator.userAgent)):()=>!0,kn=_.hasStandardBrowserEnv?{write(t,e,n,r,s,o){const i=[t+"="+encodeURIComponent(e)];l.isNumber(n)&&i.push("expires="+new Date(n).toGMTString()),l.isString(r)&&i.push("path="+r),l.isString(s)&&i.push("domain="+s),o===!0&&i.push("secure"),document.cookie=i.join("; ")},read(t){const e=document.cookie.match(new RegExp("(^|;\\s*)("+t+")=([^;]*)"));return e?decodeURIComponent(e[3]):null},remove(t){this.write(t,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function Ln(t){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t)}function Fn(t,e){return e?t.replace(/\/?\/$/,"")+"/"+e.replace(/^\/+/,""):t}function st(t,e,n){let r=!Ln(e);return t&&(r||n==!1)?Fn(t,e):e}const Me=t=>t instanceof v?{...t}:t;function F(t,e){e=e||{};const n={};function r(c,u,d,m){return l.isPlainObject(c)&&l.isPlainObject(u)?l.merge.call({caseless:m},c,u):l.isPlainObject(u)?l.merge({},u):l.isArray(u)?u.slice():u}function s(c,u,d,m){if(l.isUndefined(u)){if(!l.isUndefined(c))return r(void 0,c,d,m)}else return r(c,u,d,m)}function o(c,u){if(!l.isUndefined(u))return r(void 0,u)}function i(c,u){if(l.isUndefined(u)){if(!l.isUndefined(c))return r(void 0,c)}else return r(void 0,u)}function a(c,u,d){if(d in e)return r(c,u);if(d in t)return r(void 0,c)}const f={url:o,method:o,data:o,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:a,headers:(c,u,d)=>s(Me(c),Me(u),d,!0)};return l.forEach(Object.keys({...t,...e}),function(u){const d=f[u]||s,m=d(t[u],e[u],u);l.isUndefined(m)&&d!==a||(n[u]=m)}),n}const ot=t=>{const e=F({},t);let{data:n,withXSRFToken:r,xsrfHeaderName:s,xsrfCookieName:o,headers:i,auth:a}=e;e.headers=i=v.from(i),e.url=Ze(st(e.baseURL,e.url,e.allowAbsoluteUrls),t.params,t.paramsSerializer),a&&i.set("Authorization","Basic "+btoa((a.username||"")+":"+(a.password?unescape(encodeURIComponent(a.password)):"")));let f;if(l.isFormData(n)){if(_.hasStandardBrowserEnv||_.hasStandardBrowserWebWorkerEnv)i.setContentType(void 0);else if((f=i.getContentType())!==!1){const[c,...u]=f?f.split(";").map(d=>d.trim()).filter(Boolean):[];i.setContentType([c||"multipart/form-data",...u].join("; "))}}if(_.hasStandardBrowserEnv&&(r&&l.isFunction(r)&&(r=r(e)),r||r!==!1&&Mn(e.url))){const c=s&&o&&kn.read(o);c&&i.set(s,c)}return e},Bn=typeof XMLHttpRequest<"u",Dn=Bn&&function(t){return new Promise(function(n,r){const s=ot(t);let o=s.data;const i=v.from(s.headers).normalize();let{responseType:a,onUploadProgress:f,onDownloadProgress:c}=s,u,d,m,g,p;function y(){g&&g(),p&&p(),s.cancelToken&&s.cancelToken.unsubscribe(u),s.signal&&s.signal.removeEventListener("abort",u)}let h=new XMLHttpRequest;h.open(s.method.toUpperCase(),s.url,!0),h.timeout=s.timeout;function E(){if(!h)return;const b=v.from("getAllResponseHeaders"in h&&h.getAllResponseHeaders()),R={data:!a||a==="text"||a==="json"?h.responseText:h.response,status:h.status,statusText:h.statusText,headers:b,config:t,request:h};rt(function(I){n(I),y()},function(I){r(I),y()},R),h=null}"onloadend"in h?h.onloadend=E:h.onreadystatechange=function(){!h||h.readyState!==4||h.status===0&&!(h.responseURL&&h.responseURL.indexOf("file:")===0)||setTimeout(E)},h.onabort=function(){h&&(r(new w("Request aborted",w.ECONNABORTED,t,h)),h=null)},h.onerror=function(){r(new w("Network Error",w.ERR_NETWORK,t,h)),h=null},h.ontimeout=function(){let O=s.timeout?"timeout of "+s.timeout+"ms exceeded":"timeout exceeded";const R=s.transitional||et;s.timeoutErrorMessage&&(O=s.timeoutErrorMessage),r(new w(O,R.clarifyTimeoutError?w.ETIMEDOUT:w.ECONNABORTED,t,h)),h=null},o===void 0&&i.setContentType(null),"setRequestHeader"in h&&l.forEach(i.toJSON(),function(O,R){h.setRequestHeader(R,O)}),l.isUndefined(s.withCredentials)||(h.withCredentials=!!s.withCredentials),a&&a!=="json"&&(h.responseType=s.responseType),c&&([m,p]=Z(c,!0),h.addEventListener("progress",m)),f&&h.upload&&([d,g]=Z(f),h.upload.addEventListener("progress",d),h.upload.addEventListener("loadend",g)),(s.cancelToken||s.signal)&&(u=b=>{h&&(r(!b||b.type?new H(null,t,h):b),h.abort(),h=null)},s.cancelToken&&s.cancelToken.subscribe(u),s.signal&&(s.signal.aborted?u():s.signal.addEventListener("abort",u)));const S=Nn(s.url);if(S&&_.protocols.indexOf(S)===-1){r(new w("Unsupported protocol "+S+":",w.ERR_BAD_REQUEST,t));return}h.send(o||null)})},qn=(t,e)=>{const{length:n}=t=t?t.filter(Boolean):[];if(e||n){let r=new AbortController,s;const o=function(c){if(!s){s=!0,a();const u=c instanceof Error?c:this.reason;r.abort(u instanceof w?u:new H(u instanceof Error?u.message:u))}};let i=e&&setTimeout(()=>{i=null,o(new w(`timeout ${e} of ms exceeded`,w.ETIMEDOUT))},e);const a=()=>{t&&(i&&clearTimeout(i),i=null,t.forEach(c=>{c.unsubscribe?c.unsubscribe(o):c.removeEventListener("abort",o)}),t=null)};t.forEach(c=>c.addEventListener("abort",o));const{signal:f}=r;return f.unsubscribe=()=>l.asap(a),f}},Un=function*(t,e){let n=t.byteLength;if(n{const s=jn(t,e);let o=0,i,a=f=>{i||(i=!0,r&&r(f))};return new ReadableStream({async pull(f){try{const{done:c,value:u}=await s.next();if(c){a(),f.close();return}let d=u.byteLength;if(n){let m=o+=d;n(m)}f.enqueue(new Uint8Array(u))}catch(c){throw a(c),c}},cancel(f){return a(f),s.return()}},{highWaterMark:2})},oe=typeof fetch=="function"&&typeof Request=="function"&&typeof Response=="function",it=oe&&typeof ReadableStream=="function",$n=oe&&(typeof TextEncoder=="function"?(t=>e=>t.encode(e))(new TextEncoder):async t=>new Uint8Array(await new Response(t).arrayBuffer())),at=(t,...e)=>{try{return!!t(...e)}catch{return!1}},Vn=it&&at(()=>{let t=!1;const e=new Request(_.origin,{body:new ReadableStream,method:"POST",get duplex(){return t=!0,"half"}}).headers.has("Content-Type");return t&&!e}),Le=64*1024,pe=it&&at(()=>l.isReadableStream(new Response("").body)),ee={stream:pe&&(t=>t.body)};oe&&(t=>{["text","arrayBuffer","blob","formData","stream"].forEach(e=>{!ee[e]&&(ee[e]=l.isFunction(t[e])?n=>n[e]():(n,r)=>{throw new w(`Response type '${e}' is not supported`,w.ERR_NOT_SUPPORT,r)})})})(new Response);const zn=async t=>{if(t==null)return 0;if(l.isBlob(t))return t.size;if(l.isSpecCompliantForm(t))return(await new Request(_.origin,{method:"POST",body:t}).arrayBuffer()).byteLength;if(l.isArrayBufferView(t)||l.isArrayBuffer(t))return t.byteLength;if(l.isURLSearchParams(t)&&(t=t+""),l.isString(t))return(await $n(t)).byteLength},Jn=async(t,e)=>{const n=l.toFiniteNumber(t.getContentLength());return n??zn(e)},Kn=oe&&(async t=>{let{url:e,method:n,data:r,signal:s,cancelToken:o,timeout:i,onDownloadProgress:a,onUploadProgress:f,responseType:c,headers:u,withCredentials:d="same-origin",fetchOptions:m}=ot(t);c=c?(c+"").toLowerCase():"text";let g=qn([s,o&&o.toAbortSignal()],i),p;const y=g&&g.unsubscribe&&(()=>{g.unsubscribe()});let h;try{if(f&&Vn&&n!=="get"&&n!=="head"&&(h=await Jn(u,r))!==0){let R=new Request(e,{method:"POST",body:r,duplex:"half"}),N;if(l.isFormData(r)&&(N=R.headers.get("content-type"))&&u.setContentType(N),R.body){const[I,X]=Pe(h,Z(Ie(f)));r=ke(R.body,Le,I,X)}}l.isString(d)||(d=d?"include":"omit");const E="credentials"in Request.prototype;p=new Request(e,{...m,signal:g,method:n.toUpperCase(),headers:u.normalize().toJSON(),body:r,duplex:"half",credentials:E?d:void 0});let S=await fetch(p,m);const b=pe&&(c==="stream"||c==="response");if(pe&&(a||b&&y)){const R={};["status","statusText","headers"].forEach(Ee=>{R[Ee]=S[Ee]});const N=l.toFiniteNumber(S.headers.get("content-length")),[I,X]=a&&Pe(N,Z(Ie(a),!0))||[];S=new Response(ke(S.body,Le,I,()=>{X&&X(),y&&y()}),R)}c=c||"text";let O=await ee[l.findKey(ee,c)||"text"](S,t);return!b&&y&&y(),await new Promise((R,N)=>{rt(R,N,{data:O,headers:v.from(S.headers),status:S.status,statusText:S.statusText,config:t,request:p})})}catch(E){throw y&&y(),E&&E.name==="TypeError"&&/Load failed|fetch/i.test(E.message)?Object.assign(new w("Network Error",w.ERR_NETWORK,t,p),{cause:E.cause||E}):w.from(E,E&&E.code,t,p)}}),me={http:cn,xhr:Dn,fetch:Kn};l.forEach(me,(t,e)=>{if(t){try{Object.defineProperty(t,"name",{value:e})}catch{}Object.defineProperty(t,"adapterName",{value:e})}});const Fe=t=>`- ${t}`,Wn=t=>l.isFunction(t)||t===null||t===!1,ct={getAdapter:t=>{t=l.isArray(t)?t:[t];const{length:e}=t;let n,r;const s={};for(let o=0;o`adapter ${a} `+(f===!1?"is not supported by the environment":"is not available in the build"));let i=e?o.length>1?`since : `+o.map(Fe).join(` `):" "+Fe(o[0]):"as no adapter specified";throw new w("There is no suitable adapter to dispatch the request "+i,"ERR_NOT_SUPPORT")}return r},adapters:me};function ue(t){if(t.cancelToken&&t.cancelToken.throwIfRequested(),t.signal&&t.signal.aborted)throw new H(null,t)}function Be(t){return ue(t),t.headers=v.from(t.headers),t.data=le.call(t,t.transformRequest),["post","put","patch"].indexOf(t.method)!==-1&&t.headers.setContentType("application/x-www-form-urlencoded",!1),ct.getAdapter(t.adapter||W.adapter)(t).then(function(r){return ue(t),r.data=le.call(t,t.transformResponse,r),r.headers=v.from(r.headers),r},function(r){return nt(r)||(ue(t),r&&r.response&&(r.response.data=le.call(t,t.transformResponse,r.response),r.response.headers=v.from(r.response.headers))),Promise.reject(r)})}const lt="1.11.0",ie={};["object","boolean","number","function","string","symbol"].forEach((t,e)=>{ie[t]=function(r){return typeof r===t||"a"+(e<1?"n ":" ")+t}});const De={};ie.transitional=function(e,n,r){function s(o,i){return"[Axios v"+lt+"] Transitional option '"+o+"'"+i+(r?". "+r:"")}return(o,i,a)=>{if(e===!1)throw new w(s(i," has been removed"+(n?" in "+n:"")),w.ERR_DEPRECATED);return n&&!De[i]&&(De[i]=!0,console.warn(s(i," has been deprecated since v"+n+" and will be removed in the near future"))),e?e(o,i,a):!0}};ie.spelling=function(e){return(n,r)=>(console.warn(`${r} is likely a misspelling of ${e}`),!0)};function Xn(t,e,n){if(typeof t!="object")throw new w("options must be an object",w.ERR_BAD_OPTION_VALUE);const r=Object.keys(t);let s=r.length;for(;s-- >0;){const o=r[s],i=e[o];if(i){const a=t[o],f=a===void 0||i(a,o,t);if(f!==!0)throw new w("option "+o+" must be "+f,w.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new w("Unknown option "+o,w.ERR_BAD_OPTION)}}const Y={assertOptions:Xn,validators:ie},x=Y.validators;let L=class{constructor(e){this.defaults=e||{},this.interceptors={request:new xe,response:new xe}}async request(e,n){try{return await this._request(e,n)}catch(r){if(r instanceof Error){let s={};Error.captureStackTrace?Error.captureStackTrace(s):s=new Error;const o=s.stack?s.stack.replace(/^.+\n/,""):"";try{r.stack?o&&!String(r.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(r.stack+=` -`+o):r.stack=o}catch{}}throw r}}_request(e,n){typeof e=="string"?(n=n||{},n.url=e):n=e||{},n=F(this.defaults,n);const{transitional:r,paramsSerializer:s,headers:o}=n;r!==void 0&&Y.assertOptions(r,{silentJSONParsing:x.transitional(x.boolean),forcedJSONParsing:x.transitional(x.boolean),clarifyTimeoutError:x.transitional(x.boolean)},!1),s!=null&&(l.isFunction(s)?n.paramsSerializer={serialize:s}:Y.assertOptions(s,{encode:x.function,serialize:x.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),Y.assertOptions(n,{baseUrl:x.spelling("baseURL"),withXsrfToken:x.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let i=o&&l.merge(o.common,o[n.method]);o&&l.forEach(["delete","get","head","post","put","patch","common"],p=>{delete o[p]}),n.headers=v.concat(i,o);const a=[];let f=!0;this.interceptors.request.forEach(function(y){typeof y.runWhen=="function"&&y.runWhen(n)===!1||(f=f&&y.synchronous,a.unshift(y.fulfilled,y.rejected))});const c=[];this.interceptors.response.forEach(function(y){c.push(y.fulfilled,y.rejected)});let u,d=0,m;if(!f){const p=[Be.bind(this),void 0];for(p.unshift(...a),p.push(...c),m=p.length,u=Promise.resolve(n);d{if(!r._listeners)return;let o=r._listeners.length;for(;o-- >0;)r._listeners[o](s);r._listeners=null}),this.promise.then=s=>{let o;const i=new Promise(a=>{r.subscribe(a),o=a}).then(s);return i.cancel=function(){r.unsubscribe(o)},i},e(function(o,i,a){r.reason||(r.reason=new H(o,i,a),n(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const n=this._listeners.indexOf(e);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const e=new AbortController,n=r=>{e.abort(r)};return this.subscribe(n),e.signal.unsubscribe=()=>this.unsubscribe(n),e.signal}static source(){let e;return{token:new ut(function(s){e=s}),cancel:e}}};function Qn(t){return function(n){return t.apply(null,n)}}function Yn(t){return l.isObject(t)&&t.isAxiosError===!0}const ye={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(ye).forEach(([t,e])=>{ye[e]=t});function ft(t){const e=new L(t),n=je(L.prototype.request,e);return l.extend(n,L.prototype,e,{allOwnKeys:!0}),l.extend(n,e,null,{allOwnKeys:!0}),n.create=function(s){return ft(F(t,s))},n}const T=ft(W);T.Axios=L;T.CanceledError=H;T.CancelToken=Gn;T.isCancel=nt;T.VERSION=lt;T.toFormData=se;T.AxiosError=w;T.Cancel=T.CanceledError;T.all=function(e){return Promise.all(e)};T.spread=Qn;T.isAxiosError=Yn;T.mergeConfig=F;T.AxiosHeaders=v;T.formToJSON=t=>tt(l.isHTMLForm(t)?new FormData(t):t);T.getAdapter=ct.getAdapter;T.HttpStatusCode=ye;T.default=T;const{Axios:ar,AxiosError:cr,CanceledError:lr,isCancel:ur,CancelToken:fr,VERSION:dr,all:hr,Cancel:pr,isAxiosError:mr,spread:yr,toFormData:gr,AxiosHeaders:wr,HttpStatusCode:br,formToJSON:Er,getAdapter:Sr,mergeConfig:Tr}=T,q=T.create({baseURL:"https://localhost:4000/api/v1/",headers:{"Content-Type":"application/json"}});class Zn{async sendSingleMessage(e){try{const{data:n}=await q.post("/messages",e);return console.log("[NestJS] Response (single):",n),n}catch(n){throw console.error("[NestJS] Error (single):",n),n}}async sendBulkMessages(e){try{const{data:n}=await q.post("/messages/bulk",{data:e});return console.log("[NestJS] Response (bulk):",n),n}catch(n){throw console.error("[NestJS] Error (bulk):",n),n}}async createAndSendToZulip(e){try{const n=await Promise.all(e.map(async s=>{if(Array.isArray(s.message)){const o=await Promise.all(s.message.map(async i=>Ae(i)?await _e(i):i));return{...s,message:o}}if(Ae(s.message||"")){console.log("Found blob URL, converting to Base64:",s.message);const o=await _e(s.message||"");return{...s,message:o}}return s})),{data:r}=await q.post("/messages/create-and-send",{data:n});return console.log("[NestJS] Response (create and send):",r),r}catch(n){throw console.error("[NestJS] Error (create and send):",n),n}}async sendLog(e){try{const{data:n}=await q.post("/messages/logs",e);return console.log("[NestJS] Response (logs):",n),n}catch(n){throw console.error("[NestJS] Error (logs):",n),n}}}const M=new Zn;class er{lastMessage;initialHistories=[];elTags={container_scroll:'//*[@data-testid="simple-collab-rail"]',conatainer_conversations:'//*[@data-testid="simple-collab-dnd-rail"]',container_chat:'[data-testid="message-wrapper"]',root_id:'[aria-selected="true"] [id^="chat-list-item"]',room_name:'[data-tid="chat-title"]',close_reply_btn:'[data-track-action-scenario="messageQuotedReplyDismissed"]',reply_btn:'[aria-label="Reply"]',chat_input:'[placeholder="Type a message"]'};_getImageFormEl(e){let n=Array.from(e.querySelectorAll("img[data-gallery-src]"));return n.length===0&&e.parentElement&&(n=Array.from(e.parentElement.querySelectorAll("img[data-gallery-src]"))),n}getCurrentRoomInfo(){let e;const n=document.querySelector('[role="treeitem"][aria-selected="true"][data-item-type="chat"]');if(n){const o=(n.getAttribute("data-fui-tree-item-value")||"").split("/").pop()||"";e=o.includes("|")?o.split("|")[1]:void 0}e||(e=document.querySelector(this.elTags.root_id)?.id?.replace("chat-list-item_",""));const r=document.querySelector(this.elTags.room_name)?.innerText;return{room_id:e,room_name:r}}_getFileLinks(e){const n=`attachments-${e?.date_time}`,r=document.getElementById(n);return r?Array.from(r.children).flatMap(i=>{const a=this.getAssetToken(),f=i.getAttribute("title");if(!f)return[];const c=f.split(/\r?\n/).map(m=>m.trim()).filter(Boolean),u=c[0]||null,d=c.find(m=>/^https?:\/\//.test(m));return d?[{name:u,url:d,token:a}]:[]}):[]}_getMessageByEl(e){if(!e)return[];const n=[],r=e.innerText?.trim()||"",o=(this._getImageFormEl(e)||[]).map(c=>c.getAttribute("src")).filter(Boolean);if(o.length>0){const c=document.getElementById(`message-body-${e?.date_time}`)?.querySelector('[data-tid="overlay-count-text"]');c&&c.innerText===r?n.push(...o):(n.push(...o),r&&n.push(r))}else r&&n.push(r);const i=this._getFileLinks(e)||[];i.length&&i.forEach(c=>{n.push(JSON.stringify({...c,type:"file"}))});const f=Array.from(e.querySelectorAll("img[itemtype]")).map(c=>c.getAttribute("alt")||"").filter(Boolean);return f.length>0&&n.push(f.join("")),n}parseMessageElement(e,n=!1){const r=e.querySelector(n?".fui-ChatMyMessage__timestamp":".fui-ChatMessage__timestamp"),s=e.querySelector(n?".fui-ChatMyMessage__author":".fui-ChatMessage__author");if(!r)return null;const o=r.getAttribute("datetime");if(!o)return null;const i=Number.isNaN(r.id.replace("timestamp-",""))?new Date(o).getTime():Number(r.id.replace("timestamp-","")),a=document.querySelector(`#content-${i}`);a.date_time=i;const{room_id:f,room_name:c}=this.getCurrentRoomInfo();return{name:s?.innerText,message:this._getMessageByEl(a),time:i,room_id:f,room_name:c,date_time:new Date(o).getTime()}}getAssetToken(){const e=Object.keys(localStorage).find(r=>{const s=localStorage[r];return s.includes('"credentialType":"AccessToken"')&&s.includes('"target":"https://graph.microsoft.com/.default')});return e?JSON.parse(localStorage[e]).secret:null}extractAllMessages(){const e=Array.from(document.querySelectorAll(".fui-ChatMyMessage")).map(r=>this.parseMessageElement(r,!0)).filter(r=>r!==null),n=Array.from(document.querySelectorAll(".fui-ChatMessage")).map(r=>this.parseMessageElement(r,!1)).filter(r=>r!==null);return console.log({myMessages:e,otherMessages:n}),[...e,...n].sort((r,s)=>r.time-s.time)}async detectNewMessages(){const e=this.extractAllMessages(),n=e.findIndex(o=>o.time===this.lastMessage?.time),r=e.slice(n+1);if(r.length===0){console.log("[Monitor] No new messages...");return}const s=r[0];return this.lastMessage=e.pop(),s}async start(e=1e4){console.log("[Monitor] Starting..."),this.initialHistories=this.extractAllMessages(),this.lastMessage=this.initialHistories.pop(),setInterval(async()=>await this.detectNewMessages(),e)}async _getConversationsInfo(e=this.elTags.conatainer_conversations){const n=document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;return n?Array.from(n.querySelectorAll('[data-item-type="chat"]')).map(o=>{const a=(o.getAttribute("data-fui-tree-item-value")||"").split("/").pop()||"",f=a.includes("|")?a.split("|")[1]:null,c=`title-chat-list-item_${f}`,d=document.getElementById(c)?.innerText||null;let m=null;return f?.includes("@thread.skype")?m="group":f?.includes("@oneToOne.skype")?m="personal":m="group",{id:f,name:d,type:m}}):(console.log("Không tìm thấy phần tử theo XPath."),M.sendLog({type:"error",message:`Not found selector: ${e}`}),[])}async _scrollToBottomByXPath(e=this.elTags.container_scroll,n){const{maxStableRounds:r=5,delay:s=300,maxScrolls:o=100}=n||{},i=document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;if(!i){console.warn("❌ Không tìm thấy phần tử với XPath:",e),M.sendLog({type:"error",message:`Not found selector: ${e}`});return}return new Promise(a=>{let f=-1,c=0,u=0;const d=setInterval(()=>{const m=i.scrollHeight;i.scrollTop=m,m===f?c++:(c=0,f=m),u++,(c>=r||u>=o)&&(clearInterval(d),a())},s)})}async handleGetConversations(){return await this._scrollToBottomByXPath(),this._getConversationsInfo()}}class tr{axios=null;constructor(){this.axios=T.create({baseURL:"MyCoolApp",headers:{"Content-Type":"application/json"}})}async send(e){if(!this.axios)return null;const{data:n}=await this.axios({method:"POST",url:"type",data:{message:e}});return n}}const qe=new tr;class nr{async index(e){try{const{data:n}=await q({url:"conversations",params:e});return console.log("[NestJS] Response (conversation-index):",n),n}catch(n){throw console.error("[NestJS] Error (conversation-index):",n),n}}async getConversationByPrefix(){try{const{data:e}=await q({url:"conversations/prefix",method:"POST"});return console.log("[NestJS] Response (conversation-prefix):",e),e}catch(e){throw console.error("[NestJS] Error (conversation-prefix):",e),e}}}const rr=new nr;class sr{service;port;constructor(e){this.service=new er,this.port=e}_forceHeightObserver;getElementByXPath(e){return document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}forceHeight(e,n="100px"){if(!e)return;e.style.setProperty("height",n,"important"),e.style.setProperty("resize","none","important");const r=()=>{e.style.setProperty("height",n,"important")};e.addEventListener("focus",r),e.addEventListener("input",r),e.addEventListener("blur",r);const s=new MutationObserver(()=>{e.style.setProperty("height",n,"important")});s.observe(e,{attributes:!0,attributeFilter:["style"]}),this._forceHeightObserver=s}_clickToConversation(e){const r=document.getElementById(`title-chat-list-item_${e}`)?.closest('[data-testid="list-item"]')??document.getElementById(`chat-list-item_${e}`);return r&&(r.scrollIntoView({behavior:"smooth",block:"center"}),setTimeout(()=>r.click(),200)),r?.click()}async _waitForMessagesToAppear(e=1e4){return new Promise((n,r)=>{const s=document.getElementById("chat-pane-list");let o=null;if(!s)return r(new Error("#chat-pane-list not found"));const i=()=>Array.from(s.children),a=()=>{const c=i();c.length>0&&(f.disconnect(),o&&clearTimeout(o),n(c))},f=new MutationObserver(()=>{a()});f.observe(s,{childList:!0,subtree:!0}),a(),o=setTimeout(()=>{f.disconnect(),r(new Error("Timeout waiting for chat messages to appear"))},e)})}async _waitToloadMessages(e=300){return new Promise(n=>{const r=document.getElementById("chat-pane-list");if(!r)throw new Error("#chat-pane-list not found");let s=null,o=[];const i=new MutationObserver(()=>{s&&clearTimeout(s),o=Array.from(r.children),s=setTimeout(()=>{i.disconnect(),n(o)},e)});i.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0})})}async _rightClickMessage(e){const n=this.service.elTags.container_chat,r=`content-${e}`,s=30,o=200;let i=0,a=document.querySelector(n);if(!a){console.error("Wrapper not found:",n),await M.sendLog({type:"error",message:`Not found selector: ${n}`});return}let f=document.querySelector(`#${r}`);for(;!f&&i{const r=document.querySelector(e);r?(r.scrollIntoView({behavior:"auto",block:"center"}),setTimeout(()=>{r?.click(),n(!0)},100)):(console.warn("Không tìm thấy phần tử:",e),n(!1))})}async getConversations(e){B.add(async()=>{console.log("[Queue] Handling GET_CONVERSATIONS");const n=await this.service.handleGetConversations();this.port.postMessage({type:"socket-response",event:D.RECEIVE_CONVERSATIONS,data:n})})}async getConversation(e){B.add(async()=>{if(console.log("[Queue] Handling GET_CONVERSATION"),!e.data?.id)return;const{room_id:n}=this.service.getCurrentRoomInfo();n!=e.data.id&&(this._clickToConversation(e.data.id),await this._waitForMessagesToAppear(),await this._waitToloadMessages());const r=this.service.extractAllMessages();this.port.postMessage({type:"socket-response",event:D.RECEIVE_CONVERSATION,data:r})})}async sendMessage({data:{conversation_id:e,message:n}}){B.add(async()=>{console.log("[Queue] Handling SEND_MESSAGE");const{room_id:r}=this.service.getCurrentRoomInfo();r!=e&&this._clickToConversation(e),await P(200),await qe.send(n)})}async replyMessage({data:{conversation_id:e,message:n,time:r}}){B.add(async()=>{console.log("[Queue] Handling REPLY_MESSAGE");let s=null;const{room_id:o}=this.service.getCurrentRoomInfo();o!=e&&(this._clickToConversation(e),s=await this._waitForMessagesToAppear(),await this._waitToloadMessages(),console.log({initialMessages:s})),await this._clickIfExists(this.service.elTags.close_reply_btn),await this._rightClickMessage(r);const i=document.querySelector(this.service.elTags.reply_btn);i&&i.click(),await P(200),console.log({message:n}),await qe.send(n)})}fixedHeightChatInput(e=20,n=2e3){(()=>{const s=document.querySelector(this.service.elTags.chat_input);s?(this.forceHeight(s,"100px"),console.log("✔ Fixed height applied to chat input")):e>0?setTimeout(()=>this.fixedHeightChatInput(e-1,n),n):(console.warn("✘ Element not found with provided XPath after retries"),M.sendLog({type:"error",message:`Not found selector: ${this.service.elTags.chat_input}`}))})()}async detectNewMessage(e=2e3){console.log("[Monitor] Starting..."),this.service.initialHistories=this.service.extractAllMessages(),this.service.lastMessage=this.service.initialHistories.pop(),setInterval(()=>{B.add(async()=>{try{const n=this.service.getCurrentRoomInfo(),r=document.querySelector('[aria-labelledby^="cn-normal-notification-main-content-"]')?.getAttribute("aria-labelledby");if(!r){const a=await this.service.detectNewMessages();if(!a){console.log("[Monitor] No new message...");return}if(n.room_id!==a?.room_id){console.log("[Monitor] Message from another room → skip");return}console.log("[Monitor] Found new message:",a),await this._sendLastMessage(a);return}const s=r.split(" ")[0].replace("cn-normal-notification-main-content-","");if(!s){console.warn("[Monitor] Could not extract room_id from aria-labelledby");return}console.log("[Monitor] Notification detected:",{roomId:s,ariaValue:r}),this._clickToConversation(s),await P(2e3);const i=this.service.extractAllMessages().at(-1);if(!i){console.log("[Queue] No last message found after sync");return}console.log("[Queue] Sending last message:",i),await this._sendLastMessage(i)}catch(n){console.error("[Monitor] Error detecting new message:",n)}})},e)}async _sendLastMessage(e){try{await M.sendSingleMessage(e),console.log("[API] Sent message successfully:",e)}catch(n){console.error("[API] Failed to send message:",n)}}filesMessages(){return this.service.extractAllMessages().filter(r=>Array.isArray(r.message)?r.message.some(s=>{try{return(typeof s=="string"?JSON.parse(s):s)?.type==="file"}catch{return!1}}):!1)}async clickToRefreshToken(e){const n=e.at(-1);document.getElementById(`attachments-${n?.date_time}`)?.querySelector('[aria-label="More attachment options"]')?.click(),await P(500)}startSyncConversations(){window._chatIntervals=window?._chatIntervals||{},window._chatIntervals.syncConversations?console.log("ℹ️ startSyncConversations already running"):(window._chatIntervals.syncConversations=window.setInterval(()=>{this.getConversations()},12e4),console.log("✅ startSyncConversations running"))}autoSyncConversationPrefixMessages(){if(window._chatIntervals=window._chatIntervals||{},window._chatIntervals.syncPrefixMessages){console.log("autoSyncConversationPrefixMessages already running");return}let e=!1;window._chatIntervals.syncPrefixMessages=window.setInterval(()=>{if(e){console.log("syncPrefixMessages skipped (still running)");return}e=!0,B.add(async()=>{try{const{data:n}=await rr.getConversationByPrefix();if(!n?.length)return;for(const r of n){this._clickToConversation(r.id),await P(5e3);const s=this.service.getCurrentRoomInfo();if(!s||s.room_id!==r.id){console.warn("room mismatch, skip:",r.id);continue}const o=this.filesMessages();o.length&&await this.clickToRefreshToken(o);const i=this.service.extractAllMessages();await M.createAndSendToZulip(i),await P(5e3)}}catch(n){console.error("autoSyncConversationPrefixMessages error:",n?.message),M.sendLog({type:"error",message:`auto_to_sync_conersations: ${n?.message}`})}finally{e=!1}})},6e4),console.log("autoSyncConversationPrefixMessages running safely")}}const dt=chrome.runtime.connect({name:"message"}),U=new sr(dt);dt.onMessage.addListener(t=>{if(console.log({msg:t}),t.type==="socket")switch(t.event){case D.GET_CONVERSATIONS:{U.getConversations(t);break}case D.GET_CONVERSATION:{U.getConversation(t);break}case D.SEND_MESSAGE:{U.sendMessage(t);break}case D.REPLY_MESSAGE:{U.replyMessage(t);break}}});U.startSyncConversations();U.autoSyncConversationPrefixMessages(); +`+o):r.stack=o}catch{}}throw r}}_request(e,n){typeof e=="string"?(n=n||{},n.url=e):n=e||{},n=F(this.defaults,n);const{transitional:r,paramsSerializer:s,headers:o}=n;r!==void 0&&Y.assertOptions(r,{silentJSONParsing:x.transitional(x.boolean),forcedJSONParsing:x.transitional(x.boolean),clarifyTimeoutError:x.transitional(x.boolean)},!1),s!=null&&(l.isFunction(s)?n.paramsSerializer={serialize:s}:Y.assertOptions(s,{encode:x.function,serialize:x.function},!0)),n.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?n.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:n.allowAbsoluteUrls=!0),Y.assertOptions(n,{baseUrl:x.spelling("baseURL"),withXsrfToken:x.spelling("withXSRFToken")},!0),n.method=(n.method||this.defaults.method||"get").toLowerCase();let i=o&&l.merge(o.common,o[n.method]);o&&l.forEach(["delete","get","head","post","put","patch","common"],p=>{delete o[p]}),n.headers=v.concat(i,o);const a=[];let f=!0;this.interceptors.request.forEach(function(y){typeof y.runWhen=="function"&&y.runWhen(n)===!1||(f=f&&y.synchronous,a.unshift(y.fulfilled,y.rejected))});const c=[];this.interceptors.response.forEach(function(y){c.push(y.fulfilled,y.rejected)});let u,d=0,m;if(!f){const p=[Be.bind(this),void 0];for(p.unshift(...a),p.push(...c),m=p.length,u=Promise.resolve(n);d{if(!r._listeners)return;let o=r._listeners.length;for(;o-- >0;)r._listeners[o](s);r._listeners=null}),this.promise.then=s=>{let o;const i=new Promise(a=>{r.subscribe(a),o=a}).then(s);return i.cancel=function(){r.unsubscribe(o)},i},e(function(o,i,a){r.reason||(r.reason=new H(o,i,a),n(r.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const n=this._listeners.indexOf(e);n!==-1&&this._listeners.splice(n,1)}toAbortSignal(){const e=new AbortController,n=r=>{e.abort(r)};return this.subscribe(n),e.signal.unsubscribe=()=>this.unsubscribe(n),e.signal}static source(){let e;return{token:new ut(function(s){e=s}),cancel:e}}};function Qn(t){return function(n){return t.apply(null,n)}}function Yn(t){return l.isObject(t)&&t.isAxiosError===!0}const ye={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(ye).forEach(([t,e])=>{ye[e]=t});function ft(t){const e=new L(t),n=je(L.prototype.request,e);return l.extend(n,L.prototype,e,{allOwnKeys:!0}),l.extend(n,e,null,{allOwnKeys:!0}),n.create=function(s){return ft(F(t,s))},n}const T=ft(W);T.Axios=L;T.CanceledError=H;T.CancelToken=Gn;T.isCancel=nt;T.VERSION=lt;T.toFormData=se;T.AxiosError=w;T.Cancel=T.CanceledError;T.all=function(e){return Promise.all(e)};T.spread=Qn;T.isAxiosError=Yn;T.mergeConfig=F;T.AxiosHeaders=v;T.formToJSON=t=>tt(l.isHTMLForm(t)?new FormData(t):t);T.getAdapter=ct.getAdapter;T.HttpStatusCode=ye;T.default=T;const{Axios:ar,AxiosError:cr,CanceledError:lr,isCancel:ur,CancelToken:fr,VERSION:dr,all:hr,Cancel:pr,isAxiosError:mr,spread:yr,toFormData:gr,AxiosHeaders:wr,HttpStatusCode:br,formToJSON:Er,getAdapter:Sr,mergeConfig:Tr}=T,q=T.create({baseURL:"https://localhost:4000/api/v1/",headers:{"Content-Type":"application/json"}});class Zn{async sendSingleMessage(e){try{const{data:n}=await q.post("/messages",e);return console.log("[NestJS] Response (single):",n),n}catch(n){throw console.error("[NestJS] Error (single):",n),n}}async sendBulkMessages(e){try{const{data:n}=await q.post("/messages/bulk",{data:e});return console.log("[NestJS] Response (bulk):",n),n}catch(n){throw console.error("[NestJS] Error (bulk):",n),n}}async createAndSendToZulip(e){try{const n=await Promise.all(e.map(async s=>{if(Array.isArray(s.message)){const o=await Promise.all(s.message.map(async i=>Ae(i)?await _e(i):i));return{...s,message:o}}if(Ae(s.message||"")){console.log("Found blob URL, converting to Base64:",s.message);const o=await _e(s.message||"");return{...s,message:o}}return s})),{data:r}=await q.post("/messages/create-and-send",{data:n});return console.log("[NestJS] Response (create and send):",r),r}catch(n){throw console.error("[NestJS] Error (create and send):",n),n}}async sendLog(e){try{const{data:n}=await q.post("/messages/logs",e);return console.log("[NestJS] Response (logs):",n),n}catch(n){throw console.error("[NestJS] Error (logs):",n),n}}}const M=new Zn;class er{lastMessage;initialHistories=[];lastClickedRoomId;elTags={container_scroll:'//*[@data-testid="simple-collab-rail"]',conatainer_conversations:'//*[@data-testid="simple-collab-dnd-rail"]',container_chat:'[data-testid="message-wrapper"]',root_id:'[aria-selected="true"] [id^="chat-list-item"]',room_name:'[data-tid="chat-title"]',close_reply_btn:'[data-track-action-scenario="messageQuotedReplyDismissed"]',reply_btn:'[aria-label="Reply"]',chat_input:'[placeholder="Type a message"]'};_getImageFormEl(e){let n=Array.from(e.querySelectorAll("img[data-gallery-src]"));return n.length===0&&e.parentElement&&(n=Array.from(e.parentElement.querySelectorAll("img[data-gallery-src]"))),n}getCurrentRoomInfo(){let e;const n=document.querySelector('[role="treeitem"][aria-selected="true"][data-item-type="chat"]');if(n){const o=(n.getAttribute("data-fui-tree-item-value")||"").split("/").pop()||"";e=o.includes("|")?o.split("|")[1]:void 0}e||(e=document.querySelector(this.elTags.root_id)?.id?.replace("chat-list-item_","")),e||(e=this.lastClickedRoomId);const r=document.querySelector(this.elTags.room_name)?.innerText;return{room_id:e,room_name:r}}_getFileLinks(e){const n=`attachments-${e?.date_time}`,r=document.getElementById(n);return r?Array.from(r.children).flatMap(i=>{const a=this.getAssetToken(),f=i.getAttribute("title");if(!f)return[];const c=f.split(/\r?\n/).map(m=>m.trim()).filter(Boolean),u=c[0]||null,d=c.find(m=>/^https?:\/\//.test(m));return d?[{name:u,url:d,token:a}]:[]}):[]}_getMessageByEl(e){if(!e)return[];const n=[],r=e.innerText?.trim()||"",o=(this._getImageFormEl(e)||[]).map(c=>c.getAttribute("src")).filter(Boolean);if(o.length>0){const c=document.getElementById(`message-body-${e?.date_time}`)?.querySelector('[data-tid="overlay-count-text"]');c&&c.innerText===r?n.push(...o):(n.push(...o),r&&n.push(r))}else r&&n.push(r);const i=this._getFileLinks(e)||[];i.length&&i.forEach(c=>{n.push(JSON.stringify({...c,type:"file"}))});const f=Array.from(e.querySelectorAll("img[itemtype]")).map(c=>c.getAttribute("alt")||"").filter(Boolean);return f.length>0&&n.push(f.join("")),n}parseMessageElement(e,n=!1){const r=e.querySelector(n?".fui-ChatMyMessage__timestamp":".fui-ChatMessage__timestamp"),s=e.querySelector(n?".fui-ChatMyMessage__author":".fui-ChatMessage__author");if(!r)return null;const o=r.getAttribute("datetime");if(!o)return null;const i=Number.isNaN(r.id.replace("timestamp-",""))?new Date(o).getTime():Number(r.id.replace("timestamp-","")),a=document.querySelector(`#content-${i}`);a.date_time=i;const{room_id:f,room_name:c}=this.getCurrentRoomInfo();return{name:s?.innerText,message:this._getMessageByEl(a),time:i,room_id:f,room_name:c,date_time:new Date(o).getTime()}}getAssetToken(){const e=Object.keys(localStorage).find(r=>{const s=localStorage[r];return s.includes('"credentialType":"AccessToken"')&&s.includes('"target":"https://graph.microsoft.com/.default')});return e?JSON.parse(localStorage[e]).secret:null}extractAllMessages(){const e=Array.from(document.querySelectorAll(".fui-ChatMyMessage")).map(r=>this.parseMessageElement(r,!0)).filter(r=>r!==null),n=Array.from(document.querySelectorAll(".fui-ChatMessage")).map(r=>this.parseMessageElement(r,!1)).filter(r=>r!==null);return console.log({myMessages:e,otherMessages:n}),[...e,...n].sort((r,s)=>r.time-s.time)}async detectNewMessages(){const e=this.extractAllMessages(),n=e.findIndex(o=>o.time===this.lastMessage?.time),r=e.slice(n+1);if(r.length===0){console.log("[Monitor] No new messages...");return}const s=r[0];return this.lastMessage=e.pop(),s}async start(e=1e4){console.log("[Monitor] Starting..."),this.initialHistories=this.extractAllMessages(),this.lastMessage=this.initialHistories.pop(),setInterval(async()=>await this.detectNewMessages(),e)}async _getConversationsInfo(e=this.elTags.conatainer_conversations){const n=document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;return n?Array.from(n.querySelectorAll('[data-item-type="chat"]')).map(o=>{const a=(o.getAttribute("data-fui-tree-item-value")||"").split("/").pop()||"",f=a.includes("|")?a.split("|")[1]:null,c=`title-chat-list-item_${f}`,d=document.getElementById(c)?.innerText||null;let m=null;return f?.includes("@thread.skype")?m="group":f?.includes("@oneToOne.skype")?m="personal":m="group",{id:f,name:d,type:m}}):(console.log("Không tìm thấy phần tử theo XPath."),M.sendLog({type:"error",message:`Not found selector: ${e}`}),[])}async _scrollToBottomByXPath(e=this.elTags.container_scroll,n){const{maxStableRounds:r=5,delay:s=300,maxScrolls:o=100}=n||{},i=document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;if(!i){console.warn("❌ Không tìm thấy phần tử với XPath:",e),M.sendLog({type:"error",message:`Not found selector: ${e}`});return}return new Promise(a=>{let f=-1,c=0,u=0;const d=setInterval(()=>{const m=i.scrollHeight;i.scrollTop=m,m===f?c++:(c=0,f=m),u++,(c>=r||u>=o)&&(clearInterval(d),a())},s)})}async handleGetConversations(){return await this._scrollToBottomByXPath(),this._getConversationsInfo()}}class tr{axios=null;constructor(){this.axios=T.create({baseURL:"MyCoolApp",headers:{"Content-Type":"application/json"}})}async send(e){if(!this.axios)return null;const{data:n}=await this.axios({method:"POST",url:"type",data:{message:e}});return n}}const qe=new tr;class nr{async index(e){try{const{data:n}=await q({url:"conversations",params:e});return console.log("[NestJS] Response (conversation-index):",n),n}catch(n){throw console.error("[NestJS] Error (conversation-index):",n),n}}async getConversationByPrefix(){try{const{data:e}=await q({url:"conversations/prefix",method:"POST"});return console.log("[NestJS] Response (conversation-prefix):",e),e}catch(e){throw console.error("[NestJS] Error (conversation-prefix):",e),e}}}const rr=new nr;class sr{service;port;constructor(e){this.service=new er,this.port=e}_forceHeightObserver;getElementByXPath(e){return document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}forceHeight(e,n="100px"){if(!e)return;e.style.setProperty("height",n,"important"),e.style.setProperty("resize","none","important");const r=()=>{e.style.setProperty("height",n,"important")};e.addEventListener("focus",r),e.addEventListener("input",r),e.addEventListener("blur",r);const s=new MutationObserver(()=>{e.style.setProperty("height",n,"important")});s.observe(e,{attributes:!0,attributeFilter:["style"]}),this._forceHeightObserver=s}_clickToConversation(e){const r=document.getElementById(`title-chat-list-item_${e}`)?.closest('[data-testid="list-item"]')??document.getElementById(`chat-list-item_${e}`);r&&(this.service.lastClickedRoomId=e,r.scrollIntoView({behavior:"smooth",block:"center"}),setTimeout(()=>r.click(),200))}async _waitForMessagesToAppear(e=1e4){return new Promise((n,r)=>{const s=document.getElementById("chat-pane-list");let o=null;if(!s)return r(new Error("#chat-pane-list not found"));const i=()=>Array.from(s.children),a=()=>{const c=i();c.length>0&&(f.disconnect(),o&&clearTimeout(o),n(c))},f=new MutationObserver(()=>{a()});f.observe(s,{childList:!0,subtree:!0}),a(),o=setTimeout(()=>{f.disconnect(),r(new Error("Timeout waiting for chat messages to appear"))},e)})}async _waitToloadMessages(e=300){return new Promise(n=>{const r=document.getElementById("chat-pane-list");if(!r)throw new Error("#chat-pane-list not found");let s=null,o=[];const i=new MutationObserver(()=>{s&&clearTimeout(s),o=Array.from(r.children),s=setTimeout(()=>{i.disconnect(),n(o)},e)});i.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0})})}async _rightClickMessage(e){const n=this.service.elTags.container_chat,r=`content-${e}`,s=30,o=200;let i=0,a=document.querySelector(n);if(!a){console.error("Wrapper not found:",n),await M.sendLog({type:"error",message:`Not found selector: ${n}`});return}let f=document.querySelector(`#${r}`);for(;!f&&i{const r=document.querySelector(e);r?(r.scrollIntoView({behavior:"auto",block:"center"}),setTimeout(()=>{r?.click(),n(!0)},100)):(console.warn("Không tìm thấy phần tử:",e),n(!1))})}async getConversations(e){B.add(async()=>{console.log("[Queue] Handling GET_CONVERSATIONS");const n=await this.service.handleGetConversations();this.port.postMessage({type:"socket-response",event:D.RECEIVE_CONVERSATIONS,data:n})})}async getConversation(e){B.add(async()=>{if(console.log("[Queue] Handling GET_CONVERSATION"),!e.data?.id)return;const{room_id:n}=this.service.getCurrentRoomInfo();n!=e.data.id&&(this._clickToConversation(e.data.id),await this._waitForMessagesToAppear(),await this._waitToloadMessages());const r=this.service.extractAllMessages();this.port.postMessage({type:"socket-response",event:D.RECEIVE_CONVERSATION,data:r})})}async sendMessage({data:{conversation_id:e,message:n}}){B.add(async()=>{console.log("[Queue] Handling SEND_MESSAGE");const{room_id:r}=this.service.getCurrentRoomInfo();r!=e&&this._clickToConversation(e),await P(200),await qe.send(n)})}async replyMessage({data:{conversation_id:e,message:n,time:r}}){B.add(async()=>{console.log("[Queue] Handling REPLY_MESSAGE");let s=null;const{room_id:o}=this.service.getCurrentRoomInfo();o!=e&&(this._clickToConversation(e),s=await this._waitForMessagesToAppear(),await this._waitToloadMessages(),console.log({initialMessages:s})),await this._clickIfExists(this.service.elTags.close_reply_btn),await this._rightClickMessage(r);const i=document.querySelector(this.service.elTags.reply_btn);i&&i.click(),await P(200),console.log({message:n}),await qe.send(n)})}fixedHeightChatInput(e=20,n=2e3){(()=>{const s=document.querySelector(this.service.elTags.chat_input);s?(this.forceHeight(s,"100px"),console.log("✔ Fixed height applied to chat input")):e>0?setTimeout(()=>this.fixedHeightChatInput(e-1,n),n):(console.warn("✘ Element not found with provided XPath after retries"),M.sendLog({type:"error",message:`Not found selector: ${this.service.elTags.chat_input}`}))})()}async detectNewMessage(e=2e3){console.log("[Monitor] Starting..."),this.service.initialHistories=this.service.extractAllMessages(),this.service.lastMessage=this.service.initialHistories.pop(),setInterval(()=>{B.add(async()=>{try{const n=this.service.getCurrentRoomInfo(),r=document.querySelector('[aria-labelledby^="cn-normal-notification-main-content-"]')?.getAttribute("aria-labelledby");if(!r){const a=await this.service.detectNewMessages();if(!a){console.log("[Monitor] No new message...");return}if(n.room_id!==a?.room_id){console.log("[Monitor] Message from another room → skip");return}console.log("[Monitor] Found new message:",a),await this._sendLastMessage(a);return}const s=r.split(" ")[0].replace("cn-normal-notification-main-content-","");if(!s){console.warn("[Monitor] Could not extract room_id from aria-labelledby");return}console.log("[Monitor] Notification detected:",{roomId:s,ariaValue:r}),this._clickToConversation(s),await P(2e3);const i=this.service.extractAllMessages().at(-1);if(!i){console.log("[Queue] No last message found after sync");return}console.log("[Queue] Sending last message:",i),await this._sendLastMessage(i)}catch(n){console.error("[Monitor] Error detecting new message:",n)}})},e)}async _sendLastMessage(e){try{await M.sendSingleMessage(e),console.log("[API] Sent message successfully:",e)}catch(n){console.error("[API] Failed to send message:",n)}}filesMessages(){return this.service.extractAllMessages().filter(r=>Array.isArray(r.message)?r.message.some(s=>{try{return(typeof s=="string"?JSON.parse(s):s)?.type==="file"}catch{return!1}}):!1)}async clickToRefreshToken(e){const n=e.at(-1);document.getElementById(`attachments-${n?.date_time}`)?.querySelector('[aria-label="More attachment options"]')?.click(),await P(500)}startSyncConversations(){window._chatIntervals=window?._chatIntervals||{},window._chatIntervals.syncConversations?console.log("ℹ️ startSyncConversations already running"):(window._chatIntervals.syncConversations=window.setInterval(()=>{this.getConversations()},12e4),console.log("✅ startSyncConversations running"))}autoSyncConversationPrefixMessages(){if(window._chatIntervals=window._chatIntervals||{},window._chatIntervals.syncPrefixMessages){console.log("autoSyncConversationPrefixMessages already running");return}let e=!1;window._chatIntervals.syncPrefixMessages=window.setInterval(()=>{if(e){console.log("syncPrefixMessages skipped (still running)");return}e=!0,B.add(async()=>{try{const{data:n}=await rr.getConversationByPrefix();if(!n?.length)return;for(const r of n){this._clickToConversation(r.id),await P(5e3);const s=this.service.getCurrentRoomInfo();if(!s||s.room_id!==r.id){console.warn("room mismatch, skip:",r.id);continue}const o=this.filesMessages();o.length&&await this.clickToRefreshToken(o);const i=this.service.extractAllMessages();await M.createAndSendToZulip(i),await P(5e3)}}catch(n){console.error("autoSyncConversationPrefixMessages error:",n?.message),M.sendLog({type:"error",message:`auto_to_sync_conersations: ${n?.message}`})}finally{e=!1}})},6e4),console.log("autoSyncConversationPrefixMessages running safely")}}const dt=chrome.runtime.connect({name:"message"}),U=new sr(dt);dt.onMessage.addListener(t=>{if(console.log({msg:t}),t.type==="socket")switch(t.event){case D.GET_CONVERSATIONS:{U.getConversations(t);break}case D.GET_CONVERSATION:{U.getConversation(t);break}case D.SEND_MESSAGE:{U.sendMessage(t);break}case D.REPLY_MESSAGE:{U.replyMessage(t);break}}});U.startSyncConversations();U.autoSyncConversationPrefixMessages(); diff --git a/composer-bot-extensions/src/services/content.service.ts b/composer-bot-extensions/src/services/content.service.ts index 33cde9c..770ec36 100644 --- a/composer-bot-extensions/src/services/content.service.ts +++ b/composer-bot-extensions/src/services/content.service.ts @@ -59,17 +59,16 @@ export class ContentService { } private _clickToConversation(id: string) { - // New Teams DOM: find via title element → closest treeitem const titleEl = document.getElementById(`title-chat-list-item_${id}`); const el = titleEl?.closest('[data-testid="list-item"]') ?? document.getElementById(`chat-list-item_${id}`); if (el) { + this.service.lastClickedRoomId = id; el.scrollIntoView({ behavior: "smooth", block: "center" }); setTimeout(() => el.click(), 200); } - return el?.click(); } private async _waitForMessagesToAppear( diff --git a/composer-bot-extensions/src/services/teams-chat.service.ts b/composer-bot-extensions/src/services/teams-chat.service.ts index 7ac8041..3ae0b11 100644 --- a/composer-bot-extensions/src/services/teams-chat.service.ts +++ b/composer-bot-extensions/src/services/teams-chat.service.ts @@ -5,6 +5,7 @@ export class TeamsChatService { // private readonly MY_NAME = "Apactech com"; public lastMessage?: IMessage; public initialHistories: IMessage[] = []; + public lastClickedRoomId?: string; public elTags = { container_scroll: '//*[@data-testid="simple-collab-rail"]', @@ -58,6 +59,11 @@ export class TeamsChatService { ?.id?.replace("chat-list-item_", ""); } + // Fallback: tracked from programmatic click + if (!roomId) { + roomId = this.lastClickedRoomId; + } + const roomName = ( document.querySelector(this.elTags.room_name) as HTMLElement )?.innerText;