@lansenger/openclaw-channel-lansenger 1.1.21 → 1.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +23 -10
- package/dist/index.openclaw.bundle.js +23 -10
- package/openclaw.plugin.json +71 -183
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
var
|
|
1
|
+
var Nn=Object.defineProperty;var ee=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});var y=(n,e)=>()=>(n&&(e=n(n=0)),e);var Rn=(n,e)=>{for(var t in e)Nn(n,t,{get:e[t],enumerable:!0})};var u=y(()=>{});var ue,Qt=y(()=>{u();ue=class{static parseVersion(e){let t=e.match(/^(\d{4})\.(\d+)\.(\d+)(?:-(\d+))?/);return t?{year:parseInt(t[1],10),month:parseInt(t[2],10),patch:parseInt(t[3],10),build:t[4]?parseInt(t[4],10):void 0}:null}static isVersion2026323_2OrLater(e){let t=this.parseVersion(e);if(!t)return!1;if(t.year>2026)return!0;if(t.year===2026){if(t.month>3)return!0;if(t.month===3){if(t.patch>23)return!0;if(t.patch===23)return(t.build||0)>=2}}return!1}static getOpenClawVersion(e){return e?.openclaw?.version?e.openclaw.version:e?.version?e.version:null}static isNewSdkSupported(e){let t=this.getOpenClawVersion(e);return t?this.isVersion2026323_2OrLater(t):!1}}});var ft,V,gt,ae,mt=y(()=>{u();Qt();ft=null;try{ft=ee("openclaw/plugin-sdk")}catch{}V=null;try{V={pluginEntry:ee("openclaw/plugin-sdk/plugin-entry"),core:ee("openclaw/plugin-sdk/core"),runtimeStore:ee("openclaw/plugin-sdk/runtime-store"),defineChannelPluginEntry:ee("openclaw/plugin-sdk/core").defineChannelPluginEntry}}catch{}gt=class n{static instance;isNewSdk=!1;constructor(){}static getInstance(){return n.instance||(n.instance=new n),n.instance}init(e){this.isNewSdk=ue.isNewSdkSupported(e);let t=ue.getOpenClawVersion(e);(!t||!ue.isNewSdkSupported(e))&&console.warn(`OpenClaw version ${t} is not supported. This plugin requires OpenClaw 2026.3.23-2 or later.`)}isUsingNewSdk(){return this.isNewSdk&&V!==null}getSdk(){return this.isUsingNewSdk()&&V?V:ft||{}}createPluginEntry(e){return this.isUsingNewSdk()&&V.defineChannelPluginEntry?V.defineChannelPluginEntry(e):e}createChannelPlugin(e){return this.isUsingNewSdk()&&V.core?.createChatChannelPlugin?V.core.createChatChannelPlugin(e):e}createRuntimeStore(e){return this.isUsingNewSdk()&&V.runtimeStore?.createPluginRuntimeStore?V.runtimeStore.createPluginRuntimeStore(e):{...e}}},ae=gt.getInstance()});var ht,Zt,fe,_e,er,tr,rr,nr,or,ar,F,ge=y(()=>{u();ht={};try{ht=ee("openclaw/plugin-sdk")}catch{try{ht={...ee("openclaw/plugin-sdk/core")}}catch{console.warn("OpenClaw plugin SDK not found, using fallback")}}({emptyPluginConfigSchema:Zt=()=>({type:"object"}),normalizeAccountId:fe=n=>n,applyAccountNameToChannelSection:_e=n=>n?.cfg,deleteAccountFromConfigSection:er=n=>n?.cfg||{},setAccountEnabledInConfigSection:tr=n=>n?.cfg||{},migrateBaseNameToDefaultAccount:rr=n=>n?.cfg,formatPairingApproveHint:nr=()=>"",PAIRING_APPROVED_MESSAGE:or="Pairing approved",addWildcardAllowFrom:ar=()=>[],DEFAULT_ACCOUNT_ID:F="default"}=ht)});var kt=y(()=>{u()});function sr(n){let e=n.apiGatewayWssUrl||n.apiGatewayUrl||be.apiGatewayUrl;return e=e.replace(/^`|`$/g,""),e.replace(/^http/,"ws")}function Y(n){return(n.apiGatewayUrl||be.apiGatewayUrl).replace(/^`|`$/g,"")}function R(n){return n.botType||be.botType}function yt(n){return n.webhookPort||be.webhookPort}function ir(n){return n.webhookPath||be.webhookPath}var be,x,cr=y(()=>{u();kt();be={botType:"smart",webhookPort:3e3,webhookPath:"/lanxin/events",apiGatewayUrl:"https://open.e.lanxin.cn/open/apigw",dmPolicy:"pairing",allowFrom:[]},x={auth:{tenantAccessToken:"/auth/v3/tenant_access_token/internal",appToken:"/v1/apptoken/create"},smartBot:{privateMessage:"/v1/bot/messages/create",groupMessage:"/v1/messages/group/create",groupsList:"/v2/groups/fetch",uploadMedia:"/v1/medias/create"},webhookBot:{message:"/bot/v1/hook/messages/create"},calendar:{createEvent:"/v1/calendar/events/create",getEvent:"/v1/calendar/events/%s",updateEvent:"/v1/calendar/events/%s",deleteEvent:"/v1/calendar/events/%s",listEvents:"/v1/calendar/events/list"},meeting:{createMeeting:"/v1/meetings/create",getMeeting:"/v1/meetings/%s",updateMeeting:"/v1/meetings/%s",deleteMeeting:"/v1/meetings/%s",listMeetings:"/v1/meetings/list",startMeeting:"/v1/meetings/%s/start",endMeeting:"/v1/meetings/%s/end"}}});var z=y(()=>{u();cr();kt()});function $e(n){me.setRuntime?me.setRuntime(n):me.runtime=n}function wt(){if(me.getRuntime)return me.getRuntime();{let n=me.runtime;if(!n)throw new Error("Lansenger plugin runtime not initialized");return n}}var me,lr=y(()=>{u();mt();me=ae.createRuntimeStore({error:"Lansenger plugin runtime not initialized"})});var Tt=y(()=>{u();lr()});async function dr(n,e,t,r,o,a,s){s?.({lastOutboundAt:Date.now()});try{let c=await he(r.config,e,n,t==="group");c.ok?a?.info(`[lanxin:${r.accountId}] Message sent successfully: ${c.messageId}`):a?.error(`[lanxin:${r.accountId}] Failed to send message: ${c.error}`)}catch(c){a?.error(`[lanxin:${r.accountId}] Failed to send reply: ${c instanceof Error?c.message:String(c)}`)}}var pr=y(()=>{u();L()});function ur(){return ke||(ke=new Fe),ke}function se(){return ke||(ke=new Fe),ke}var Fe,ke,Ge=y(()=>{u();L();Fe=class{bindings=[];constructor(){i.debug("Initialized binding manager with in-memory storage")}bindBotToAgent(e,t){let r=this.bindings.findIndex(o=>o.botId===e);r>=0?(this.bindings[r]={botId:e,agentId:t,lastUpdated:new Date().toISOString()},i.debug(`Updated binding: ${e} -> ${t}`)):(this.bindings.push({botId:e,agentId:t,lastUpdated:new Date().toISOString()}),i.debug(`Added binding: ${e} -> ${t}`))}getBotAgent(e,t){let r=this.bindings.find(o=>o.botId===e);return r?r.agentId:t?.agentId?t.agentId:"default"}getAllBindings(){return[...this.bindings]}removeBinding(e){let t=this.bindings.length;this.bindings=this.bindings.filter(r=>r.botId!==e),this.bindings.length<t&&i.info(`Removed binding for bot: ${e}`)}hasBinding(e){return this.bindings.some(t=>t.botId===e)}initializeFromConfig(e,t){if(e)for(let[r,o]of Object.entries(e))o.appId&&o.agentId&&(this.bindBotToAgent(o.appId,o.agentId),i.debug(`Initialized binding from account config: ${o.appId} -> ${o.agentId}`));if(t?.bindings){for(let r of t.bindings)if(r.match?.channel==="Lansenger"&&r.match?.accountId&&r.agentId&&e){for(let[o,a]of Object.entries(e))if(o===r.match.accountId&&a.appId){this.bindBotToAgent(a.appId,r.agentId),i.debug(`Initialized binding from OpenClaw bindings: ${a.appId} -> ${r.agentId}`);break}}}}},ke=null});function U(n,e=A.UNKNOWN,t,r){return new We(n,e,t,r)}function je(n,e){return i.logError(n,e),n.message}var A,We,O,It,i,G=y(()=>{u();(function(n){n.AUTHENTICATION="AUTHENTICATION",n.API="API",n.CONFIGURATION="CONFIGURATION",n.NETWORK="NETWORK",n.VALIDATION="VALIDATION",n.WEBSOCKET="WEBSOCKET",n.MEDIA="MEDIA",n.UNKNOWN="UNKNOWN"})(A||(A={}));We=class extends Error{type;code;context;constructor(e,t=A.UNKNOWN,r,o){super(e),this.name="LansengerError",this.type=t,this.code=r,this.context=o}};(function(n){n.DEBUG="DEBUG",n.INFO="INFO",n.WARN="WARN",n.ERROR="ERROR",n.FATAL="FATAL"})(O||(O={}));It=class{openclawLog;logCache=[];maxCacheSize=500;setOpenClawLog(e){if(this.openclawLog=e,this.logCache.length>0){let t=[...this.logCache];this.logCache=[],t.forEach(({level:r,message:o,context:a})=>{try{this.logInternal(r,o,a)}catch(s){console.error("[Lansenger] Failed to output cached log:",s)}})}}clearCache(){this.logCache=[]}getCacheSize(){return this.logCache.length}getCallerInfo(){try{let t=new Error().stack||"",r=t.split(`
|
|
2
2
|
`).slice(2);for(let a of r){let s=a.match(/\((.*):(\d+):(\d+)\)/);if(s){let c=s[1],l=s[2],d=c.split("/").pop();if(d!=="error-handling.ts")return`${d}:${l}`}}let o=t.split(`
|
|
3
|
-
`).slice(4);for(let a of o){let s=a.match(/\((.*):(\d+):(\d+)\)/);if(s){let c=s[1],l=s[2];return`${c.split("/").pop()}:${l}`}}}catch{}return""}sanitizeContext(e){if(!e)return e;let t={...e};return["appSecret","secret","password","token","hookToken","encryptKey","verificationToken"].forEach(o=>{t[o]&&(t[o]="***REDACTED***")}),t}formatMessage(e){return e.replace(/\n/g," ").replace(/\s+/g," ").trim()}log(e,t,r){let o=new Date().toISOString(),a=this.getCallerInfo(),s=this.formatMessage(t),c=`[${o}] [${e}] ${a?`[${a}] `:""}${s}`,l=this.sanitizeContext(r);if(this.openclawLog)switch(e){case D.DEBUG:l?this.openclawLog.debug?.(`${c} ${JSON.stringify(l)}`):this.openclawLog.debug?.(c);break;case D.INFO:l?this.openclawLog.info(`${c} ${JSON.stringify(l)}`):this.openclawLog.info(c);break;case D.WARN:l?this.openclawLog.info(`${c} ${JSON.stringify(l)}`):this.openclawLog.info(c);break;case D.ERROR:case D.FATAL:l?this.openclawLog.error(`${c} ${JSON.stringify(l)}`):this.openclawLog.error(c);break;default:l?this.openclawLog.info(`${c} ${JSON.stringify(l)}`):this.openclawLog.info(c)}else switch(e){case D.DEBUG:console.debug(c,l);break;case D.INFO:console.info(c,l);break;case D.WARN:console.warn(c,l);break;case D.ERROR:console.error(c,l);break;case D.FATAL:console.error(c,l);break;default:console.log(c,l)}}debug(e,t){this.log(D.DEBUG,e,t)}info(e,t){this.log(D.INFO,e,t)}warn(e,t){this.log(D.WARN,e,t)}error(e,t){this.log(D.ERROR,e,t)}fatal(e,t){this.log(D.FATAL,e,t)}logError(e,t){e instanceof We?this.error(e.message,{type:e.type,code:e.code,...t,...e.context}):this.error(e.message,{stack:e.stack,...t})}},i=new It});function N(n){return n||X({})}function F(n){return N(n)}function qe(n){return N(n)}var Q=w(()=>{u();z()});var Tt,M,Z=w(()=>{u();z();W();Tt=class{cache=new Map;refreshPromises=new Map;getCacheKey(e){return`${e.appId}:${e.appSecret}`}isTokenExpired(e){let t=Date.now(),r=e.acquiredAt+e.expiresIn*1e3,o=5*60*1e3;return t>=r-o}async getAppToken(e){if(!e.appId||!e.appSecret)throw U("AppId and AppSecret are required",A.AUTHENTICATION,"MISSING_CREDENTIALS");let t=this.getCacheKey(e),r=this.cache.get(t);if(r&&!this.isTokenExpired(r)){let a=r.appToken;return i.debug("Using cached appToken",{cacheKey:t}),a}if(this.refreshPromises.has(t)){let a=this.refreshPromises.get(t);return i.debug("Using existing refresh promise",{cacheKey:t}),a}let o=this.refreshAppToken(e,t);this.refreshPromises.set(t,o);try{let a=await o;return i.info("Successfully refreshed appToken",{cacheKey:t}),a}finally{this.refreshPromises.delete(t)}}async refreshAppToken(e,t){try{let r=X(e),o=x.auth.appToken,a=`${r}${o}`;i.info(`refresh appToken url: ${a}, endpoint: ${o}, apiGatewayUrl: ${r}`);let s=new URLSearchParams({grant_type:"client_credential",appid:e.appId,secret:e.appSecret}),c=`${a}?${s.toString()}`;i.info(`Refreshing appToken for appId: ${e.appId}`),i.info(`Request URL: ${c}`);let l=new AbortController,d=setTimeout(()=>l.abort(),3e4);try{let p=await fetch(c,{method:"GET",headers:{"Content-Type":"application/json"},signal:l.signal});if(clearTimeout(d),i.info("AppToken refresh response received",{status:p.status,statusText:p.statusText}),!p.ok)throw U(`HTTP ${p.status}: ${p.statusText}`,A.NETWORK,`HTTP_${p.status}`,{url:a,status:p.status,statusText:p.statusText});let f=await p.json();if(i.info("AppToken refresh response data",{errCode:f.errCode,errMsg:f.errMsg}),f.errCode!==0)throw U(f.errMsg,A.AUTHENTICATION,`ERR_${f.errCode}`,{errCode:f.errCode,errMsg:f.errMsg});if(!f.data?.appToken)throw U("No appToken returned",A.AUTHENTICATION,"MISSING_TOKEN");let g={appToken:f.data.appToken,acquiredAt:Date.now(),expiresIn:f.data.expiresIn};return this.cache.set(t,g),i.info("AppToken refreshed successfully",{expiresIn:f.data.expiresIn}),f.data.appToken}catch(p){throw clearTimeout(d),p}}catch(r){throw i.error("Error in refreshAppToken",{error:r,appId:e.appId}),r instanceof Error?U(`Failed to refresh appToken: ${r.message}`,A.AUTHENTICATION,"REFRESH_FAILED",{originalError:r.message,appId:e.appId,stack:r.stack}):U(`Failed to refresh appToken: ${String(r)}`,A.AUTHENTICATION,"REFRESH_FAILED")}}clearCache(e){let t=this.getCacheKey(e);this.cache.delete(t)}clearAllCache(){this.cache.clear()}},M=new Tt});async function K(n,e,t,r,o){if(!e?.trim())return i.warn("No groupId provided"),{ok:!1,error:"No groupId provided"};try{i.debug("Sending smart bot group message",{groupId:e,msgType:t,outlines:o?.outlines});let a=await M.getAppToken(n),s=F(n.apiGatewayUrl),c=x.smartBot.groupMessage,l=new URLSearchParams;l.append("app_token",a),o?.userToken&&l.append("user_token",o.userToken),i.debug("Sending message to Lanxin API",{apiUrl:s,endpoint:c,groupId:e,msgType:t});let d=await fetch(`${s}${c}?${l.toString()}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({groupId:e,outlines:o?.outlines,msgType:t,msgData:r,entryId:o?.entryId})});if(!d.ok){let f=`HTTP ${d.status}: ${d.statusText}`;return i.error(f,{url:`${s}${c}`,status:d.status}),{ok:!1,error:f}}let p=await d.json();return p.errCode!==0?(i.error("Lanxin API error",{errCode:p.errCode,errMsg:p.errMsg}),{ok:!1,error:p.errMsg}):(i.info("Group message sent successfully",{messageId:p.data?.msgId,groupId:e,msgType:t}),{ok:!0,messageId:p.data?.msgId})}catch(a){return i.error("Error sending group message",{error:a,groupId:e,msgType:t}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function ir(n,e,t,r){return await K(n,e,"formatText",{formatText:{formatType:1,text:t}},r)}async function J(n,e,t,r){if(!e?.trim())return i.warn("No hookToken provided"),{ok:!1,error:"No hookToken provided"};try{i.info("Sending webhook bot message",{msgType:t,hookToken:e.slice(0,10)+"..."});let o=await M.getAppToken(n),a=qe(n.apiGatewayUrl),s=x.webhookBot.message,c=new URLSearchParams;o&&c.append("app_token",o),c.append("hook_token",e),i.debug("Sending message to Lanxin API",{apiUrl:a,endpoint:s,msgType:t});let l=await fetch(`${a}${s}?${c.toString()}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({msgType:t,msgData:r})});if(!l.ok){let p=`HTTP ${l.status}: ${l.statusText}`;return i.error(p,{url:`${a}${s}`,status:l.status}),{ok:!1,error:p}}let d=await l.json();return d.errCode!==0?(i.error("Lanxin API error",{errCode:d.errCode,errMsg:d.errMsg}),{ok:!1,error:d.errMsg}):(i.info("Webhook message sent successfully",{messageId:d.data?.msgId,msgType:t}),{ok:!0,messageId:d.data?.msgId})}catch(o){return i.error("Error sending webhook message",{error:o,msgType:t}),{ok:!1,error:o instanceof Error?o.message:String(o)}}}var be=w(()=>{u();Q();z();Z();W()});async function Se(n,e,t,r,o){if(!t?.trim())return i.warn("No recipient provided"),{ok:!1,error:"No recipient provided"};if(!r?.title||!r?.link)return i.warn("Title and link are required for linkCard"),{ok:!1,error:"Title and link are required for linkCard"};try{if(i.debug("Sending linkCard message",{to:t,title:r.title,isGroup:o?.isGroup}),n==="smart"){if(o?.isGroup)return await K(e,t,"linkCard",{linkCard:r});{let a=await M.getAppToken(e),s=F(e.apiGatewayUrl),c=x.smartBot.privateMessage;i.debug("Sending message to Lanxin API",{apiUrl:s,endpoint:c,to:t,msgType:"linkCard"});let l=await fetch(`${s}${c}?app_token=${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userIdList:[t],msgType:"linkCard",msgData:{linkCard:r}})});if(!l.ok){let p=`HTTP ${l.status}: ${l.statusText}`;return i.error(p,{url:`${s}${c}`,status:l.status}),{ok:!1,error:p}}let d=await l.json();return d.errCode!==0?(i.error("Lanxin API error",{errCode:d.errCode,errMsg:d.errMsg}),{ok:!1,error:d.errMsg}):(i.info("LinkCard message sent successfully",{messageId:d.data?.msgId,to:t}),{ok:!0,messageId:d.data?.msgId})}}else if(n==="webhook"){let a=o?.hookToken||e.hookToken;return a?await J(e,a,"linkCard",{linkCard:r}):(i.warn("No hookToken provided for webhook bot"),{ok:!1,error:"No hookToken provided for webhook bot"})}return i.warn(`Unknown bot type: ${n}`),{ok:!1,error:`Unknown bot type: ${n}`}}catch(a){return i.error("Error sending linkCard message",{error:a,to:t,title:r.title}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function se(n,e,t,r,o){if(!t?.trim())return i.warn("No recipient provided"),{ok:!1,error:"No recipient provided"};if(!r?.bodyTitle)return i.warn("bodyTitle is required for appCard"),{ok:!1,error:"bodyTitle is required for appCard"};if(r.isDynamic&&!r.headStatusInfo)return i.warn("headStatusInfo is required for dynamic appCard"),{ok:!1,error:"headStatusInfo is required for dynamic appCard"};if(r.isDynamic&&!r.headStatusInfo?.description)return i.warn("headStatusInfo.description is required for dynamic appCard"),{ok:!1,error:"headStatusInfo.description is required for dynamic appCard"};try{if(i.debug("Sending appCard message",{to:t,bodyTitle:r.bodyTitle,isDynamic:r.isDynamic,isGroup:o?.isGroup}),n==="smart"){if(o?.isGroup)return await K(e,t,"appCard",{appCard:r});{let a=await M.getAppToken(e),s=F(e.apiGatewayUrl),c=x.smartBot.privateMessage;i.debug("Sending message to Lanxin API",{apiUrl:s,endpoint:c,to:t,msgType:"appCard"});let l=await fetch(`${s}${c}?app_token=${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userIdList:[t],msgType:"appCard",msgData:{appCard:r}})});if(!l.ok){let p=`HTTP ${l.status}: ${l.statusText}`;return i.error(p,{url:`${s}${c}`,status:l.status}),{ok:!1,error:p}}let d=await l.json();return d.errCode!==0?(i.error("Lanxin API error",{errCode:d.errCode,errMsg:d.errMsg}),{ok:!1,error:d.errMsg}):(i.info("AppCard message sent successfully",{messageId:d.data?.msgId,to:t}),{ok:!0,messageId:d.data?.msgId})}}else if(n==="webhook"){let a=o?.hookToken||e.hookToken;return a?await J(e,a,"appCard",{appCard:r}):(i.warn("No hookToken provided for webhook bot"),{ok:!1,error:"No hookToken provided for webhook bot"})}return i.warn(`Unknown bot type: ${n}`),{ok:!1,error:`Unknown bot type: ${n}`}}catch(a){return i.error("Error sending appCard message",{error:a,to:t,bodyTitle:r.bodyTitle}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function ve(n,e,t,r,o){if(!t?.trim())return i.warn("No recipient provided"),{ok:!1,error:"No recipient provided"};try{if(i.debug("Sending oacard message",{to:t,isGroup:o?.isGroup}),n==="smart"){if(o?.isGroup)return await K(e,t,"oacard",{oacard:r});{let a=await M.getAppToken(e),s=F(e.apiGatewayUrl),c=x.smartBot.privateMessage;i.debug("Sending message to Lanxin API",{apiUrl:s,endpoint:c,to:t,msgType:"oacard"});let l=await fetch(`${s}${c}?app_token=${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userIdList:[t],msgType:"oacard",msgData:{oacard:r}})});if(!l.ok){let p=`HTTP ${l.status}: ${l.statusText}`;return i.error(p,{url:`${s}${c}`,status:l.status}),{ok:!1,error:p}}let d=await l.json();return d.errCode!==0?(i.error("Lanxin API error",{errCode:d.errCode,errMsg:d.errMsg}),{ok:!1,error:d.errMsg}):(i.info("Oacard message sent successfully",{messageId:d.data?.msgId,to:t}),{ok:!0,messageId:d.data?.msgId})}}else if(n==="webhook"){let a=o?.hookToken||e.hookToken;return a?await J(e,a,"oacard",{oacard:r}):(i.warn("No hookToken provided for webhook bot"),{ok:!1,error:"No hookToken provided for webhook bot"})}return i.warn(`Unknown bot type: ${n}`),{ok:!1,error:`Unknown bot type: ${n}`}}catch(a){return i.error("Error sending oacard message",{error:a,to:t}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function Ae(n,e,t,r,o){if(!t?.trim())return i.warn("No recipient provided"),{ok:!1,error:"No recipient provided"};if(!r||r.length===0)return i.warn("appArticles array is required and must not be empty"),{ok:!1,error:"appArticles array is required and must not be empty"};for(let a of r)if(!a.title||!a.imageUrl||!a.url)return i.warn("Each article must have title, imageUrl, and url"),{ok:!1,error:"Each article must have title, imageUrl, and url"};try{if(i.debug("Sending appArticles message",{to:t,articleCount:r.length,isGroup:o?.isGroup}),n==="smart"){if(o?.isGroup)return await K(e,t,"appArticles",{appArticles:r});{let a=await M.getAppToken(e),s=F(e.apiGatewayUrl),c=x.smartBot.privateMessage;i.debug("Sending message to Lanxin API",{apiUrl:s,endpoint:c,to:t,msgType:"appArticles",articleCount:r.length});let l=await fetch(`${s}${c}?app_token=${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userIdList:[t],msgType:"appArticles",msgData:{appArticles:r}})});if(!l.ok){let p=`HTTP ${l.status}: ${l.statusText}`;return i.error(p,{url:`${s}${c}`,status:l.status}),{ok:!1,error:p}}let d=await l.json();return d.errCode!==0?(i.error("Lanxin API error",{errCode:d.errCode,errMsg:d.errMsg}),{ok:!1,error:d.errMsg}):(i.info("AppArticles message sent successfully",{messageId:d.data?.msgId,to:t,articleCount:r.length}),{ok:!0,messageId:d.data?.msgId})}}else if(n==="webhook"){let a=o?.hookToken||e.hookToken;return a?await J(e,a,"appArticles",{appArticles:r}):(i.warn("No hookToken provided for webhook bot"),{ok:!1,error:"No hookToken provided for webhook bot"})}return i.warn(`Unknown bot type: ${n}`),{ok:!1,error:`Unknown bot type: ${n}`}}catch(a){return i.error("Error sending appArticles message",{error:a,to:t,articleCount:r.length}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function Me(n,e,t,r,o){if(!t?.trim())return i.warn("No recipient provided"),{ok:!1,error:"No recipient provided"};try{if(i.debug("Sending system message",{to:t,isGroup:o?.isGroup}),n==="smart"){if(o?.isGroup)return await K(e,t,"system",{system:r});{let a=await M.getAppToken(e),s=F(e.apiGatewayUrl),c=x.smartBot.privateMessage;i.debug("Sending message to Lanxin API",{apiUrl:s,endpoint:c,to:t,msgType:"system"});let l=await fetch(`${s}${c}?app_token=${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userIdList:[t],msgType:"system",msgData:{system:r}})});if(!l.ok){let p=`HTTP ${l.status}: ${l.statusText}`;return i.error(p,{url:`${s}${c}`,status:l.status}),{ok:!1,error:p}}let d=await l.json();return d.errCode!==0?(i.error("Lanxin API error",{errCode:d.errCode,errMsg:d.errMsg}),{ok:!1,error:d.errMsg}):(i.info("System message sent successfully",{messageId:d.data?.msgId,to:t}),{ok:!0,messageId:d.data?.msgId})}}else if(n==="webhook"){let a=o?.hookToken||e.hookToken;return a?await J(e,a,"system",{system:r}):(i.warn("No hookToken provided for webhook bot"),{ok:!1,error:"No hookToken provided for webhook bot"})}return i.warn(`Unknown bot type: ${n}`),{ok:!1,error:`Unknown bot type: ${n}`}}catch(a){return i.error("Error sending system message",{error:a,to:t}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}var xt=w(()=>{u();Q();z();Z();be();W()});async function cr(n,e,t,r,o){try{i.info(`[lanxin:${r}] Handling approval callback: ${e} for ${n} by ${t}`);let a,s,c;if(e==="approve")a="\u5DF2\u540C\u610F",s="#52C41A",c="\u540C\u610F\u4E86";else if(e==="reject")a="\u5DF2\u62D2\u7EDD",s="#FF4757",c="\u62D2\u7EDD\u4E86";else{i.error(`[lanxin:${r}] Invalid action: ${e}`);return}let l=L(o);await se(l,o,t,{headTitle:"\u5BA1\u6279\u4EFB\u52A1",isDynamic:!0,headStatusInfo:{description:`<div style="color:${s}">${a}</div>`,colour:s},bodyTitle:'<div style="color:#000000;font-size:17pt;text-align:left">\u7CFB\u7EDF\u7EF4\u62A4\u64CD\u4F5C\u5BA1\u6279</div>',bodySubTitle:'<div style="color:#242E3E;font-size:13pt;text-align:left">\u8FD0\u7EF4\u90E8\u95E8 [2026] 001\u53F7</div>',bodyContent:`<div style="color: #000000;font-size: 15pt;text-align: left;text-indent: 2em">\u5BA1\u6279\u5DF2\u5904\u7406\uFF1A${c}\u6B64\u64CD\u4F5C</div><div style="color: #000000;font-size: 15pt;text-align: left;margin-top: 10px;"><strong>\u6267\u884C\u547D\u4EE4\uFF1A</strong></div><div style="color: #FF4757;font-size: 14pt;text-align: left;background-color: #F5F5F5;padding: 10px;border-left: 3px solid #FF4757;margin: 5px 0;">rm -rf /test</div><div style="color: #000000;font-size: 15pt;text-align: left;margin-top: 10px;"><strong>\u64CD\u4F5C\u8BF4\u660E\uFF1A</strong></div><div style="color: #000000;font-size: 14pt;text-align: left;margin: 5px 0;">\u5220\u9664\u6D4B\u8BD5\u76EE\u5F55\uFF0C\u6E05\u7406\u7CFB\u7EDF\u7A7A\u95F4</div><div style="color: #000000;font-size: 14pt;text-align: left;margin-top: 10px;"><strong>\u5904\u7406\u7ED3\u679C\uFF1A</strong></div><div style="color: ${s};font-size: 14pt;text-align: left;margin: 5px 0;">${a}</div>`,fields:[{key:'<div style="color: #242E3E">\u7533\u8BF7\u4EBA\uFF1A</div>',value:'<div style="color: #000000">\u8FD0\u7EF4\u5DE5\u7A0B\u5E08</div>'},{key:'<div style="color: #242E3E">\u7533\u8BF7\u65F6\u95F4\uFF1A</div>',value:'<div style="color: #000000">2026-04-14 10:00</div>'},{key:'<div style="color: #242E3E">\u64CD\u4F5C\u7C7B\u578B\uFF1A</div>',value:'<div style="color: #000000">\u7CFB\u7EDF\u7EF4\u62A4</div>'},{key:'<div style="color: #242E3E">\u5BA1\u6279ID\uFF1A</div>',value:`<div style="color: #000000">${n}</div>`},{key:'<div style="color: #242E3E">\u5904\u7406\u4EBA\uFF1A</div>',value:`<div style="color: #000000">${t}</div>`},{key:'<div style="color: #242E3E">\u5904\u7406\u65F6\u95F4\uFF1A</div>',value:`<div style="color: #000000">${new Date().toLocaleString()}</div>`}],links:[]}),i.info(`[lanxin:${r}] Approval callback handled successfully: ${e} for ${n}`)}catch(a){i.error(`[lanxin:${r}] Error handling approval callback: ${a instanceof Error?a.message:String(a)}`)}}var $t=w(()=>{u();W();xt();G()});import ie from"node:fs";import Pn from"node:os";import Ce from"node:path";import Un from"node:https";import Nn from"node:http";import{fileURLToPath as Ln}from"node:url";function lr(n){let e=n.match(/\.([a-zA-Z0-9]+)(\?|$)/);return e?e[1].toLowerCase():"bin"}async function Ee(n,e="unknown"){if(n.startsWith("/")||n.startsWith("file://"))return{path:n.replace("file://",""),isTemp:!1};let t=lr(n),r=Date.now(),o=Pn.tmpdir(),a=Ce.join(o,"openclaw-lansenger","media","inbound",e);ie.existsSync(a)||ie.mkdirSync(a,{recursive:!0});let s=new URL(n),c=Ce.basename(s.pathname);Ce.extname(c)||(c+="."+lr(n));let l=`${r}_${c}`,d=Ce.join(a,l);return new Promise((p,f)=>{let g=n.startsWith("https")?Un:Nn,m=ie.createWriteStream(d);g.get(n,T=>{if(T.statusCode===301||T.statusCode===302){m.close();try{ie.unlinkSync(d)}catch{}let v=T.headers.location;if(!v){f(new Error("Redirect without location header"));return}Ee(v,e).then(p).catch(f);return}if(T.statusCode!==200){m.close();try{ie.unlinkSync(d)}catch{}f(new Error(`Failed to download: HTTP ${T.statusCode}`));return}T.pipe(m),m.on("finish",()=>{m.close(),p({path:d,isTemp:!1})}),m.on("error",v=>{try{ie.unlinkSync(d)}catch{}f(v)})}).on("error",T=>{m.close();try{ie.unlinkSync(d)}catch{}f(T)})})}var Dn,Ua,He=w(()=>{u();Dn=Ln(import.meta.url),Ua=Ce.dirname(Dn)});var ur={};vn(ur,{applyAccountConfig:()=>St,parseToken:()=>bt,processAllowFrom:()=>dr,updateOpenStaffId:()=>ye,validateToken:()=>pr});var dr,bt,pr,St,ye,ze=w(()=>{u();ge();G();Ge();dr=n=>n?Array.isArray(n)?n.flat().filter(e=>typeof e=="string"):[]:[],bt=n=>{let e,t,r,o;if(n){let a=n.replace(/^`|`$/g,""),s=a.indexOf(":");if(s!==-1){e=a.substring(0,s).trim();let c=a.indexOf(":",s+1);if(c!==-1){t=a.substring(s+1,c).trim();let l=a.substring(c+1).trim();if((l.match(/:/g)||[]).length>=2){let p=l.split(":"),f=p[p.length-1].trim();if(!f.includes("://")&&!f.includes("/")&&f.length>0){let g=l.lastIndexOf(":");g!==-1?(r=l.substring(0,g).trim(),o=f):r=l}else r=l}else r=l}else t=a.substring(s+1).trim()}}return{appId:e,appSecret:t,domain:r,agentId:o}},pr=n=>{if(!n)return{valid:!1,error:"Token is required"};let{appId:e,appSecret:t,domain:r}=bt(n);return!e||!t||!r?{valid:!1,error:"Token format is invalid. Required format: {AppID}:{AppSecret}:{APIGateway}[:{AgentId}]"}:!r.startsWith("http://")&&!r.startsWith("https://")?{valid:!1,error:"API Gateway URL must start with http:// or https://"}:{valid:!0}},St=({cfg:n,accountId:e,input:t})=>{i.info(`applyAccountConfig: ${e}, ${t.name} ${JSON.stringify(t)}`);let r=t.token,o=pr(r);if(!o.valid)throw i.error(o.error),new Error(o.error);let a=Re({cfg:n,channelKey:"Lansenger",accountId:e,name:t.name}),s=e!==_?Xt({cfg:a,channelKey:"Lansenger"}):a,{appId:c,appSecret:l,domain:d,agentId:p}=bt(r),f=t.url,g=f?.trim()||d?.trim();i.info(`Debug: domain=${f}, domainFromToken=${d}, apiGatewayUrl=${g}, agentId=${p}`),(!g||g==="https")&&(i.error(`Invalid apiGatewayUrl: ${g}`),g=void 0);let m=t.dmAllowlist,T;m&&(T=m,i.info(`Adding staffId: ${T}`)),c&&p&&(sr().bindBotToAgent(c,p),i.info(`Bound bot ${c} to agent ${p}`));let v=s.channels?.Lansenger??{},$=v.accounts??{},O=null;if(c){for(let[S,C]of Object.entries($))if(C.appId===c){O=S,i.info(`Found existing account with appId ${c}: ${S}`);break}}let I=O||e;I||(c?I=`bot_${c.split("-")[1]||Math.floor(Math.random()*1e4)}`:I=_),I===_&&c&&$[_]&&(I=`bot_${c.split("-")[1]||Math.floor(Math.random()*1e4)}`,i.info(`Default account already exists, creating new accountId: ${I}`));let b=$[I]??{},k=dr(v.allowFrom);T&&(k.includes(T)||k.push(T));let y=s.bindings??[];return p&&c&&(y=y.filter(S=>S.match?.accountId!==I),y.push({type:"route",agentId:p,match:{channel:"Lansenger",accountId:I}}),i.info(`Created binding: ${p} -> Lansenger/${I}`)),{...s,channels:{...s.channels??{},Lansenger:{...v,enabled:!0,...k.length>0?{allowFrom:k}:{},accounts:{...$,[I]:{...b,enabled:!0,...c?{appId:c}:{},...l?{appSecret:l}:{},...g?{apiGatewayUrl:g}:{},...p?{agentId:p}:{}}}}},...y.length>0?{bindings:y}:{}}},ye=({cfg:n,accountId:e,staffId:t})=>{i.info(`updateOpenStaffId: ${e}, ${t}`);let r=n.channels?.Lansenger??{},o=r.accounts??{},a=o[e]??{};return{...n,channels:{...n.channels??{},Lansenger:{...r,accounts:{...o,[e]:{...a,openStaffId:t}}}}}}});import*as fr from"http";import{URL as On}from"url";function Rn(n,e){return Math.floor(Math.random()*(e-n+1))+n}async function gr(n){let{account:e,config:t,log:r,statusSink:o}=n,{appId:a}=e,s=e.config.botType??"smart",c=e.config.connectionMode??"websocket";return ae().initializeFromConfig(t.channels?.Lansenger?.accounts,t),r.info(`[lanxin:${e.accountId}] Initialized bindings from config`),c==="webhook"||c==="https"?_n({account:e,log:r,statusSink:o},{account:e,config:t,log:r,thinkingThresholdMs:0,botNames:[],statusSink:o}):await Bn({account:e,config:t,log:r,thinkingThresholdMs:0,botNames:[],statusSink:o})}async function Bn(n){let{account:e,log:t,statusSink:r}=n,o=e.accountId;t.info(`[lanxin:${o}] Starting WebSocket provider config=${JSON.stringify(e.config)} (botType=${e.config.botType??"smart"}, appId=${e.appId}) on port ${kt(e.config)} `);let a=e.appId;if(we[a]){let l=we[a];if(ce[l]){let{client:d}=ce[l];if(d.isConnected())return t.info(`[lanxin:${o}] WebSocket client already exists for appId ${a}, reusing existing connection from account ${l}`),{stop:ce[l].stop}}}if(ce[o]){let{client:l}=ce[o];if(l.isConnected())return t.info(`[lanxin:${o}] WebSocket client already connected, reusing existing connection`),we[a]=o,{stop:ce[o].stop}}let{client:s,stop:c}=await kr({account:e,log:t,statusSink:r,onMessage:l=>{mr(l,n)},onConnect:()=>{t.info(`[lanxin:${o}] WebSocket provider started`)},onDisconnect:(l,d)=>{t.info(`[lanxin:${o}] WebSocket disconnected: ${l} ${d}`),we[a]===o&&delete we[a]},onError:l=>{t.error(`[lanxin:${o}] WebSocket error: ${l instanceof Error?l.message:JSON.stringify(l)}`)},onpong:()=>{t.info(`[lanxin:${o}] WebSocket heartbeat pong received`)}});return ce[o]={client:s,stop:c},we[a]=o,{stop:c}}function _n(n,e){let{account:t,log:r,statusSink:o}=n,a=kt(t.config);t.config.webhookPort=a+Rn(1,100);let s=t.config.webhookPort,c=tr(t.config),l=fr.createServer(async(p,f)=>{if(p.method!=="POST"||p.url!==c){f.statusCode=404,f.end("Not Found");return}let g="";p.on("data",m=>g+=m.toString()),p.on("end",async()=>{try{let m=JSON.parse(g);r.info(`webhook: Received payload: ${JSON.stringify(m)}`);let T=t.config.encryptKey||"NTQxNEY5NUM2NDFBMENGREU2MjI5MTRGMDdERTEzNjc",v=yr(m,T,r);if(v.length===0){f.statusCode=200,f.end(JSON.stringify({errCode:0,errMsg:"ok"}));return}for(let $ of v)await mr($,e);f.statusCode=200,f.end(JSON.stringify({errCode:0,errMsg:"ok"}))}catch(m){f.statusCode=400,f.end("Bad Request"),r.error(`webhook: Error processing request: ${m instanceof Error?m.message:String(m)}`)}})});return l.listen(s,()=>{r.info(`[lanxin:${t.accountId}] Webhook server listening on port ${s}, path ${c}`),o?.({running:!0,lastStartAt:Date.now(),mode:"webhook",botType:t.config.botType??"smart"})}),l.on("error",p=>{p.code==="EADDRINUSE"?r.error(`[lanxin:${t.accountId}] Port ${s} is already in use. If you have multiple accounts using webhook mode, each needs a different webhookPort.`):r.error(`[lanxin:${t.accountId}] Webhook server error: ${p.message}`),o?.({running:!1,lastError:p.message})}),{stop:()=>{r.info(`[lanxin:${t.accountId}] Stopping Webhook server`),l.closeAllConnections(),l.close(),o?.({running:!1,lastStopAt:Date.now()})}}}async function mr(n,e){i.debug(`[lanxin:${e.account.accountId}] Received event: ${JSON.stringify(n)} testMode: ${e.account.config.testMode?.enabled??!1}`);let t=n.data,r;if(t?.type==="staff_info"&&t?.data){let I=t.data;if(r=I.staffId,r){let b=t.id||`${r}_${I.timestamp||Date.now()}`;Ie.setStaffId(e.account.accountId,r),i.info(`[lanxin:${e.account.accountId}] Cached staffId: ${r}`);try{let{updateOpenStaffId:y}=await Promise.resolve().then(()=>(ze(),ur));y({cfg:e.config,accountId:e.account.accountId,staffId:r}),i.info(`[lanxin:${e.account.accountId}] Updated openStaffId in config: ${r}`)}catch(y){i.error(`[lanxin:${e.account.accountId}] Error updating openStaffId in config: ${y instanceof Error?y.message:String(y)}`)}try{let y=await E.staff.getStaffInfo(e.account.config,r);y?(Ie.setStaffInfo(e.account.accountId,y),i.info(`[lanxin:${e.account.accountId}] Cached staff info: name=${y.name}, orgName=${y.orgName}, status=${y.status}`)):i.info(`[lanxin:${e.account.accountId}] Failed to fetch staff info for staffId: ${r}`)}catch(y){i.error(`[lanxin:${e.account.accountId}] Error fetching staff info: ${y instanceof Error?y.message:String(y)}`)}if(e.account.config.testMode?.enabled??!1){i.info(`[lanxin:${e.account.accountId}] Test mode enabled, sending staff_info to staffId`);let y=`Test Mode - Staff Info
|
|
3
|
+
`).slice(4);for(let a of o){let s=a.match(/\((.*):(\d+):(\d+)\)/);if(s){let c=s[1],l=s[2];return`${c.split("/").pop()}:${l}`}}}catch{}return""}sanitizeContext(e){if(!e)return e;let t={...e};return["appSecret","secret","password","token","hookToken","encryptKey","verificationToken"].forEach(o=>{t[o]&&(t[o]="***REDACTED***")}),t}formatMessage(e){return(typeof e=="string"?e:String(e)).replace(/\n/g," ").replace(/\s+/g," ").trim()}logInternal(e,t,r){let o=new Date().toISOString(),a=this.getCallerInfo(),s=this.formatMessage(t),c=`[${o}] [${e}] ${a?`[${a}] `:""}${s}`,l=this.sanitizeContext(r);if(this.openclawLog)switch(e){case O.DEBUG:l?this.openclawLog.debug?.(`${c} ${JSON.stringify(l)}`):this.openclawLog.debug?.(c);break;case O.INFO:l?this.openclawLog.info(`${c} ${JSON.stringify(l)}`):this.openclawLog.info(c);break;case O.WARN:l?this.openclawLog.info(`${c} ${JSON.stringify(l)}`):this.openclawLog.info(c);break;case O.ERROR:case O.FATAL:l?this.openclawLog.error(`${c} ${JSON.stringify(l)}`):this.openclawLog.error(c);break;default:l?this.openclawLog.info(`${c} ${JSON.stringify(l)}`):this.openclawLog.info(c)}else switch(e){case O.DEBUG:console.debug?.(c,l);break;case O.INFO:console.info?.(c,l);break;case O.WARN:console.warn?.(c,l);break;case O.ERROR:console.error(c,l);break;case O.FATAL:console.error(c,l);break;default:console.log(c,l)}}log(e,t,r){if(!this.openclawLog){this.logCache.length>=this.maxCacheSize&&this.logCache.shift(),this.logCache.push({level:e,message:t,context:r});return}this.logInternal(e,t,r)}debug(e,t){this.log(O.DEBUG,e,t)}info(e,t){this.log(O.INFO,e,t)}warn(e,t){this.log(O.WARN,e,t)}error(e,t){this.log(O.ERROR,e,t)}fatal(e,t){this.log(O.FATAL,e,t)}logError(e,t){e instanceof We?this.error(e.message,{type:e.type,code:e.code,...t,...e.context}):this.error(e.message,{stack:e.stack,...t})}},i=new It});function N(n){return n||Y({})}function W(n){return N(n)}function qe(n){return N(n)}var Q=y(()=>{u();z()});var xt,C,Z=y(()=>{u();z();G();xt=class{cache=new Map;refreshPromises=new Map;getCacheKey(e){return`${e.appId}:${e.appSecret}`}isTokenExpired(e){let t=Date.now(),r=e.acquiredAt+e.expiresIn*1e3,o=5*60*1e3;return t>=r-o}async getAppToken(e){if(!e.appId||!e.appSecret)throw U("AppId and AppSecret are required",A.AUTHENTICATION,"MISSING_CREDENTIALS");let t=this.getCacheKey(e),r=this.cache.get(t);if(r&&!this.isTokenExpired(r)){let a=r.appToken;return i.debug("Using cached appToken",{cacheKey:t}),a}if(this.refreshPromises.has(t)){let a=this.refreshPromises.get(t);return i.debug("Using existing refresh promise",{cacheKey:t}),a}let o=this.refreshAppToken(e,t);this.refreshPromises.set(t,o);try{let a=await o;return i.info("Successfully refreshed appToken",{cacheKey:t}),a}finally{this.refreshPromises.delete(t)}}async refreshAppToken(e,t){try{let r=Y(e),o=x.auth.appToken,a=`${r}${o}`;i.info(`refresh appToken url: ${a}, endpoint: ${o}, apiGatewayUrl: ${r}`);let s=new URLSearchParams({grant_type:"client_credential",appid:e.appId,secret:e.appSecret}),c=`${a}?${s.toString()}`;i.info(`Refreshing appToken for appId: ${e.appId}`),i.info(`Request URL: ${c}`);let l=new AbortController,d=setTimeout(()=>l.abort(),3e4);try{let p=await fetch(c,{method:"GET",headers:{"Content-Type":"application/json"},signal:l.signal});if(clearTimeout(d),i.info("AppToken refresh response received",{status:p.status,statusText:p.statusText}),!p.ok)throw U(`HTTP ${p.status}: ${p.statusText}`,A.NETWORK,`HTTP_${p.status}`,{url:a,status:p.status,statusText:p.statusText});let f=await p.json();if(i.info("AppToken refresh response data",{errCode:f.errCode,errMsg:f.errMsg}),f.errCode!==0)throw U(f.errMsg,A.AUTHENTICATION,`ERR_${f.errCode}`,{errCode:f.errCode,errMsg:f.errMsg});if(!f.data?.appToken)throw U("No appToken returned",A.AUTHENTICATION,"MISSING_TOKEN");let g={appToken:f.data.appToken,acquiredAt:Date.now(),expiresIn:f.data.expiresIn};return this.cache.set(t,g),i.info("AppToken refreshed successfully",{expiresIn:f.data.expiresIn}),f.data.appToken}catch(p){throw clearTimeout(d),p}}catch(r){throw i.error("Error in refreshAppToken",{error:r,appId:e.appId}),r instanceof Error?U(`Failed to refresh appToken: ${r.message}`,A.AUTHENTICATION,"REFRESH_FAILED",{originalError:r.message,appId:e.appId,stack:r.stack}):U(`Failed to refresh appToken: ${String(r)}`,A.AUTHENTICATION,"REFRESH_FAILED")}}clearCache(e){let t=this.getCacheKey(e);this.cache.delete(t)}clearAllCache(){this.cache.clear()}},C=new xt});async function K(n,e,t,r,o){if(!e?.trim())return i.warn("No groupId provided"),{ok:!1,error:"No groupId provided"};try{i.debug("Sending smart bot group message",{groupId:e,msgType:t,outlines:o?.outlines});let a=await C.getAppToken(n),s=W(n.apiGatewayUrl),c=x.smartBot.groupMessage,l=new URLSearchParams;l.append("app_token",a),o?.userToken&&l.append("user_token",o.userToken),i.debug("Sending message to Lanxin API",{apiUrl:s,endpoint:c,groupId:e,msgType:t});let d=await fetch(`${s}${c}?${l.toString()}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({groupId:e,outlines:o?.outlines,msgType:t,msgData:r,entryId:o?.entryId})});if(!d.ok){let f=`HTTP ${d.status}: ${d.statusText}`;return i.error(f,{url:`${s}${c}`,status:d.status}),{ok:!1,error:f}}let p=await d.json();return p.errCode!==0?(i.error("Lanxin API error",{errCode:p.errCode,errMsg:p.errMsg}),{ok:!1,error:p.errMsg}):(i.info("Group message sent successfully",{messageId:p.data?.msgId,groupId:e,msgType:t}),{ok:!0,messageId:p.data?.msgId})}catch(a){return i.error("Error sending group message",{error:a,groupId:e,msgType:t}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function fr(n,e,t,r){return await K(n,e,"formatText",{formatText:{formatType:1,text:t}},r)}async function J(n,e,t,r){if(!e?.trim())return i.warn("No hookToken provided"),{ok:!1,error:"No hookToken provided"};try{i.info("Sending webhook bot message",{msgType:t,hookToken:e.slice(0,10)+"..."});let o=await C.getAppToken(n),a=qe(n.apiGatewayUrl),s=x.webhookBot.message,c=new URLSearchParams;o&&c.append("app_token",o),c.append("hook_token",e),i.debug("Sending message to Lanxin API",{apiUrl:a,endpoint:s,msgType:t});let l=await fetch(`${a}${s}?${c.toString()}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({msgType:t,msgData:r})});if(!l.ok){let p=`HTTP ${l.status}: ${l.statusText}`;return i.error(p,{url:`${a}${s}`,status:l.status}),{ok:!1,error:p}}let d=await l.json();return d.errCode!==0?(i.error("Lanxin API error",{errCode:d.errCode,errMsg:d.errMsg}),{ok:!1,error:d.errMsg}):(i.info("Webhook message sent successfully",{messageId:d.data?.msgId,msgType:t}),{ok:!0,messageId:d.data?.msgId})}catch(o){return i.error("Error sending webhook message",{error:o,msgType:t}),{ok:!1,error:o instanceof Error?o.message:String(o)}}}var Se=y(()=>{u();Q();z();Z();G()});async function ve(n,e,t,r,o){if(!t?.trim())return i.warn("No recipient provided"),{ok:!1,error:"No recipient provided"};if(!r?.title||!r?.link)return i.warn("Title and link are required for linkCard"),{ok:!1,error:"Title and link are required for linkCard"};try{if(i.debug("Sending linkCard message",{to:t,title:r.title,isGroup:o?.isGroup}),n==="smart"){if(o?.isGroup)return await K(e,t,"linkCard",{linkCard:r});{let a=await C.getAppToken(e),s=W(e.apiGatewayUrl),c=x.smartBot.privateMessage;i.debug("Sending message to Lanxin API",{apiUrl:s,endpoint:c,to:t,msgType:"linkCard"});let l=await fetch(`${s}${c}?app_token=${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userIdList:[t],msgType:"linkCard",msgData:{linkCard:r}})});if(!l.ok){let p=`HTTP ${l.status}: ${l.statusText}`;return i.error(p,{url:`${s}${c}`,status:l.status}),{ok:!1,error:p}}let d=await l.json();return d.errCode!==0?(i.error("Lanxin API error",{errCode:d.errCode,errMsg:d.errMsg}),{ok:!1,error:d.errMsg}):(i.info("LinkCard message sent successfully",{messageId:d.data?.msgId,to:t}),{ok:!0,messageId:d.data?.msgId})}}else if(n==="webhook"){let a=o?.hookToken||e.hookToken;return a?await J(e,a,"linkCard",{linkCard:r}):(i.warn("No hookToken provided for webhook bot"),{ok:!1,error:"No hookToken provided for webhook bot"})}return i.warn(`Unknown bot type: ${n}`),{ok:!1,error:`Unknown bot type: ${n}`}}catch(a){return i.error("Error sending linkCard message",{error:a,to:t,title:r.title}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function ie(n,e,t,r,o){if(!t?.trim())return i.warn("No recipient provided"),{ok:!1,error:"No recipient provided"};if(!r?.bodyTitle)return i.warn("bodyTitle is required for appCard"),{ok:!1,error:"bodyTitle is required for appCard"};if(r.isDynamic&&!r.headStatusInfo)return i.warn("headStatusInfo is required for dynamic appCard"),{ok:!1,error:"headStatusInfo is required for dynamic appCard"};if(r.isDynamic&&!r.headStatusInfo?.description)return i.warn("headStatusInfo.description is required for dynamic appCard"),{ok:!1,error:"headStatusInfo.description is required for dynamic appCard"};try{if(i.debug("Sending appCard message",{to:t,bodyTitle:r.bodyTitle,isDynamic:r.isDynamic,isGroup:o?.isGroup}),n==="smart"){if(o?.isGroup)return await K(e,t,"appCard",{appCard:r});{let a=await C.getAppToken(e),s=W(e.apiGatewayUrl),c=x.smartBot.privateMessage;i.debug("Sending message to Lanxin API",{apiUrl:s,endpoint:c,to:t,msgType:"appCard"});let l=await fetch(`${s}${c}?app_token=${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userIdList:[t],msgType:"appCard",msgData:{appCard:r}})});if(!l.ok){let p=`HTTP ${l.status}: ${l.statusText}`;return i.error(p,{url:`${s}${c}`,status:l.status}),{ok:!1,error:p}}let d=await l.json();return d.errCode!==0?(i.error("Lanxin API error",{errCode:d.errCode,errMsg:d.errMsg}),{ok:!1,error:d.errMsg}):(i.info("AppCard message sent successfully",{messageId:d.data?.msgId,to:t}),{ok:!0,messageId:d.data?.msgId})}}else if(n==="webhook"){let a=o?.hookToken||e.hookToken;return a?await J(e,a,"appCard",{appCard:r}):(i.warn("No hookToken provided for webhook bot"),{ok:!1,error:"No hookToken provided for webhook bot"})}return i.warn(`Unknown bot type: ${n}`),{ok:!1,error:`Unknown bot type: ${n}`}}catch(a){return i.error("Error sending appCard message",{error:a,to:t,bodyTitle:r.bodyTitle}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function Ae(n,e,t,r,o){if(!t?.trim())return i.warn("No recipient provided"),{ok:!1,error:"No recipient provided"};try{if(i.debug("Sending oacard message",{to:t,isGroup:o?.isGroup}),n==="smart"){if(o?.isGroup)return await K(e,t,"oacard",{oacard:r});{let a=await C.getAppToken(e),s=W(e.apiGatewayUrl),c=x.smartBot.privateMessage;i.debug("Sending message to Lanxin API",{apiUrl:s,endpoint:c,to:t,msgType:"oacard"});let l=await fetch(`${s}${c}?app_token=${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userIdList:[t],msgType:"oacard",msgData:{oacard:r}})});if(!l.ok){let p=`HTTP ${l.status}: ${l.statusText}`;return i.error(p,{url:`${s}${c}`,status:l.status}),{ok:!1,error:p}}let d=await l.json();return d.errCode!==0?(i.error("Lanxin API error",{errCode:d.errCode,errMsg:d.errMsg}),{ok:!1,error:d.errMsg}):(i.info("Oacard message sent successfully",{messageId:d.data?.msgId,to:t}),{ok:!0,messageId:d.data?.msgId})}}else if(n==="webhook"){let a=o?.hookToken||e.hookToken;return a?await J(e,a,"oacard",{oacard:r}):(i.warn("No hookToken provided for webhook bot"),{ok:!1,error:"No hookToken provided for webhook bot"})}return i.warn(`Unknown bot type: ${n}`),{ok:!1,error:`Unknown bot type: ${n}`}}catch(a){return i.error("Error sending oacard message",{error:a,to:t}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function Ce(n,e,t,r,o){if(!t?.trim())return i.warn("No recipient provided"),{ok:!1,error:"No recipient provided"};if(!r||r.length===0)return i.warn("appArticles array is required and must not be empty"),{ok:!1,error:"appArticles array is required and must not be empty"};for(let a of r)if(!a.title||!a.imageUrl||!a.url)return i.warn("Each article must have title, imageUrl, and url"),{ok:!1,error:"Each article must have title, imageUrl, and url"};try{if(i.debug("Sending appArticles message",{to:t,articleCount:r.length,isGroup:o?.isGroup}),n==="smart"){if(o?.isGroup)return await K(e,t,"appArticles",{appArticles:r});{let a=await C.getAppToken(e),s=W(e.apiGatewayUrl),c=x.smartBot.privateMessage;i.debug("Sending message to Lanxin API",{apiUrl:s,endpoint:c,to:t,msgType:"appArticles",articleCount:r.length});let l=await fetch(`${s}${c}?app_token=${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userIdList:[t],msgType:"appArticles",msgData:{appArticles:r}})});if(!l.ok){let p=`HTTP ${l.status}: ${l.statusText}`;return i.error(p,{url:`${s}${c}`,status:l.status}),{ok:!1,error:p}}let d=await l.json();return d.errCode!==0?(i.error("Lanxin API error",{errCode:d.errCode,errMsg:d.errMsg}),{ok:!1,error:d.errMsg}):(i.info("AppArticles message sent successfully",{messageId:d.data?.msgId,to:t,articleCount:r.length}),{ok:!0,messageId:d.data?.msgId})}}else if(n==="webhook"){let a=o?.hookToken||e.hookToken;return a?await J(e,a,"appArticles",{appArticles:r}):(i.warn("No hookToken provided for webhook bot"),{ok:!1,error:"No hookToken provided for webhook bot"})}return i.warn(`Unknown bot type: ${n}`),{ok:!1,error:`Unknown bot type: ${n}`}}catch(a){return i.error("Error sending appArticles message",{error:a,to:t,articleCount:r.length}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function Me(n,e,t,r,o){if(!t?.trim())return i.warn("No recipient provided"),{ok:!1,error:"No recipient provided"};try{if(i.debug("Sending system message",{to:t,isGroup:o?.isGroup}),n==="smart"){if(o?.isGroup)return await K(e,t,"system",{system:r});{let a=await C.getAppToken(e),s=W(e.apiGatewayUrl),c=x.smartBot.privateMessage;i.debug("Sending message to Lanxin API",{apiUrl:s,endpoint:c,to:t,msgType:"system"});let l=await fetch(`${s}${c}?app_token=${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userIdList:[t],msgType:"system",msgData:{system:r}})});if(!l.ok){let p=`HTTP ${l.status}: ${l.statusText}`;return i.error(p,{url:`${s}${c}`,status:l.status}),{ok:!1,error:p}}let d=await l.json();return d.errCode!==0?(i.error("Lanxin API error",{errCode:d.errCode,errMsg:d.errMsg}),{ok:!1,error:d.errMsg}):(i.info("System message sent successfully",{messageId:d.data?.msgId,to:t}),{ok:!0,messageId:d.data?.msgId})}}else if(n==="webhook"){let a=o?.hookToken||e.hookToken;return a?await J(e,a,"system",{system:r}):(i.warn("No hookToken provided for webhook bot"),{ok:!1,error:"No hookToken provided for webhook bot"})}return i.warn(`Unknown bot type: ${n}`),{ok:!1,error:`Unknown bot type: ${n}`}}catch(a){return i.error("Error sending system message",{error:a,to:t}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}var bt=y(()=>{u();Q();z();Z();Se();G()});async function gr(n,e,t,r,o){try{i.info(`[lanxin:${r}] Handling approval callback: ${e} for ${n} by ${t}`);let a,s,c;if(e==="approve")a="\u5DF2\u540C\u610F",s="#52C41A",c="\u540C\u610F\u4E86";else if(e==="reject")a="\u5DF2\u62D2\u7EDD",s="#FF4757",c="\u62D2\u7EDD\u4E86";else{i.error(`[lanxin:${r}] Invalid action: ${e}`);return}let l=R(o);await ie(l,o,t,{headTitle:"\u5BA1\u6279\u4EFB\u52A1",isDynamic:!0,headStatusInfo:{description:`<div style="color:${s}">${a}</div>`,colour:s},bodyTitle:'<div style="color:#000000;font-size:17pt;text-align:left">\u7CFB\u7EDF\u7EF4\u62A4\u64CD\u4F5C\u5BA1\u6279</div>',bodySubTitle:'<div style="color:#242E3E;font-size:13pt;text-align:left">\u8FD0\u7EF4\u90E8\u95E8 [2026] 001\u53F7</div>',bodyContent:`<div style="color: #000000;font-size: 15pt;text-align: left;text-indent: 2em">\u5BA1\u6279\u5DF2\u5904\u7406\uFF1A${c}\u6B64\u64CD\u4F5C</div><div style="color: #000000;font-size: 15pt;text-align: left;margin-top: 10px;"><strong>\u6267\u884C\u547D\u4EE4\uFF1A</strong></div><div style="color: #FF4757;font-size: 14pt;text-align: left;background-color: #F5F5F5;padding: 10px;border-left: 3px solid #FF4757;margin: 5px 0;">rm -rf /test</div><div style="color: #000000;font-size: 15pt;text-align: left;margin-top: 10px;"><strong>\u64CD\u4F5C\u8BF4\u660E\uFF1A</strong></div><div style="color: #000000;font-size: 14pt;text-align: left;margin: 5px 0;">\u5220\u9664\u6D4B\u8BD5\u76EE\u5F55\uFF0C\u6E05\u7406\u7CFB\u7EDF\u7A7A\u95F4</div><div style="color: #000000;font-size: 14pt;text-align: left;margin-top: 10px;"><strong>\u5904\u7406\u7ED3\u679C\uFF1A</strong></div><div style="color: ${s};font-size: 14pt;text-align: left;margin: 5px 0;">${a}</div>`,fields:[{key:'<div style="color: #242E3E">\u7533\u8BF7\u4EBA\uFF1A</div>',value:'<div style="color: #000000">\u8FD0\u7EF4\u5DE5\u7A0B\u5E08</div>'},{key:'<div style="color: #242E3E">\u7533\u8BF7\u65F6\u95F4\uFF1A</div>',value:'<div style="color: #000000">2026-04-14 10:00</div>'},{key:'<div style="color: #242E3E">\u64CD\u4F5C\u7C7B\u578B\uFF1A</div>',value:'<div style="color: #000000">\u7CFB\u7EDF\u7EF4\u62A4</div>'},{key:'<div style="color: #242E3E">\u5BA1\u6279ID\uFF1A</div>',value:`<div style="color: #000000">${n}</div>`},{key:'<div style="color: #242E3E">\u5904\u7406\u4EBA\uFF1A</div>',value:`<div style="color: #000000">${t}</div>`},{key:'<div style="color: #242E3E">\u5904\u7406\u65F6\u95F4\uFF1A</div>',value:`<div style="color: #000000">${new Date().toLocaleString()}</div>`}],links:[]}),i.info(`[lanxin:${r}] Approval callback handled successfully: ${e} for ${n}`)}catch(a){i.error(`[lanxin:${r}] Error handling approval callback: ${a instanceof Error?a.message:String(a)}`)}}var $t=y(()=>{u();G();bt();L()});import ce from"node:fs";import Fn from"node:os";import Ee from"node:path";import Gn from"node:https";import Wn from"node:http";import{fileURLToPath as jn}from"node:url";function mr(n){let e=n.match(/\.([a-zA-Z0-9]+)(\?|$)/);return e?e[1].toLowerCase():"bin"}async function Pe(n,e="unknown"){if(n.startsWith("/")||n.startsWith("file://"))return{path:n.replace("file://",""),isTemp:!1};let t=mr(n),r=Date.now(),o=Fn.tmpdir(),a=Ee.join(o,"openclaw-lansenger","media","inbound",e);ce.existsSync(a)||ce.mkdirSync(a,{recursive:!0});let s=new URL(n),c=Ee.basename(s.pathname);Ee.extname(c)||(c+="."+mr(n));let l=`${r}_${c}`,d=Ee.join(a,l);return new Promise((p,f)=>{let g=n.startsWith("https")?Gn:Wn,m=ce.createWriteStream(d);g.get(n,I=>{if(I.statusCode===301||I.statusCode===302){m.close();try{ce.unlinkSync(d)}catch{}let v=I.headers.location;if(!v){f(new Error("Redirect without location header"));return}Pe(v,e).then(p).catch(f);return}if(I.statusCode!==200){m.close();try{ce.unlinkSync(d)}catch{}f(new Error(`Failed to download: HTTP ${I.statusCode}`));return}I.pipe(m),m.on("finish",()=>{m.close(),p({path:d,isTemp:!1})}),m.on("error",v=>{try{ce.unlinkSync(d)}catch{}f(v)})}).on("error",I=>{m.close();try{ce.unlinkSync(d)}catch{}f(I)})})}var qn,qa,He=y(()=>{u();qn=jn(import.meta.url),qa=Ee.dirname(qn)});var yr={};Rn(yr,{applyAccountConfig:()=>vt,parseToken:()=>St,processAllowFrom:()=>hr,updateOpenStaffId:()=>ye,validateToken:()=>kr});var hr,St,kr,vt,ye,ze=y(()=>{u();ge();L();Ge();hr=n=>n?Array.isArray(n)?n.flat().filter(e=>typeof e=="string"):[]:[],St=n=>{let e,t,r,o;if(n){let a=n.replace(/^`|`$/g,""),s=a.indexOf(":");if(s!==-1){e=a.substring(0,s).trim();let c=a.indexOf(":",s+1);if(c!==-1){t=a.substring(s+1,c).trim();let l=a.substring(c+1).trim();if((l.match(/:/g)||[]).length>=2){let p=l.split(":"),f=p[p.length-1].trim();if(!f.includes("://")&&!f.includes("/")&&f.length>0){let g=l.lastIndexOf(":");g!==-1?(r=l.substring(0,g).trim(),o=f):r=l}else r=l}else r=l}else t=a.substring(s+1).trim()}}return{appId:e,appSecret:t,domain:r,agentId:o}},kr=n=>{if(!n)return{valid:!1,error:"Token is required"};let{appId:e,appSecret:t,domain:r}=St(n);return!e||!t||!r?{valid:!1,error:"Token format is invalid. Required format: {AppID}:{AppSecret}:{APIGateway}[:{AgentId}]"}:!r.startsWith("http://")&&!r.startsWith("https://")?{valid:!1,error:"API Gateway URL must start with http:// or https://"}:{valid:!0}},vt=({cfg:n,accountId:e,input:t})=>{i.info(`applyAccountConfig: ${e}, ${t.name} ${JSON.stringify(t)}`);let r=t.token,o=kr(r);if(!o.valid)throw i.error(o.error),new Error(o.error);let a=_e({cfg:n,channelKey:"Lansenger",accountId:e,name:t.name}),s=e!==F?rr({cfg:a,channelKey:"Lansenger"}):a,{appId:c,appSecret:l,domain:d,agentId:p}=St(r),f=t.url,g=f?.trim()||d?.trim();i.info(`Debug: domain=${f}, domainFromToken=${d}, apiGatewayUrl=${g}, agentId=${p}`),(!g||g==="https")&&(i.error(`Invalid apiGatewayUrl: ${g}`),g=void 0);let m=t.dmAllowlist,I;m&&(I=m,i.info(`Adding staffId: ${I}`)),c&&p&&(ur().bindBotToAgent(c,p),i.info(`Bound bot ${c} to agent ${p}`));let v=s.channels?.Lansenger??{},b=v.accounts??{},D=null;if(c){for(let[S,M]of Object.entries(b))if(M.appId===c){D=S,i.info(`Found existing account with appId ${c}: ${S}`);break}}let T=D||e;T||(c?T=`bot_${c.split("-")[1]||Math.floor(Math.random()*1e4)}`:T=F),T===F&&c&&b[F]&&(T=`bot_${c.split("-")[1]||Math.floor(Math.random()*1e4)}`,i.info(`Default account already exists, creating new accountId: ${T}`));let $=b[T]??{},k=hr(v.allowFrom);I&&(k.includes(I)||k.push(I));let w=s.bindings??[];return p&&c&&(w=w.filter(S=>S.match?.accountId!==T),w.push({type:"route",agentId:p,match:{channel:"Lansenger",accountId:T}}),i.info(`Created binding: ${p} -> Lansenger/${T}`)),{...s,channels:{...s.channels??{},Lansenger:{...v,enabled:!0,...k.length>0?{allowFrom:k}:{},accounts:{...b,[T]:{...$,enabled:!0,...c?{appId:c}:{},...l?{appSecret:l}:{},...g?{apiGatewayUrl:g}:{},...p?{agentId:p}:{},approval:{enabled:!0,highRiskTools:"write,delete,trash,rm"}}}}},...w.length>0?{bindings:w}:{}}},ye=({cfg:n,accountId:e,staffId:t})=>{i.info(`updateOpenStaffId: ${e}, ${t}`);let r=n.channels?.Lansenger??{},o=r.accounts??{},a=o[e]??{};return{...n,channels:{...n.channels??{},Lansenger:{...r,accounts:{...o,[e]:{...a,openStaffId:t}}}}}}});import*as wr from"http";import{URL as Hn}from"url";function zn(n,e){return Math.floor(Math.random()*(e-n+1))+n}async function Tr(n){let{account:e,config:t,log:r,statusSink:o}=n,{appId:a}=e,s=e.config.botType??"smart",c=e.config.connectionMode??"websocket";return se().initializeFromConfig(t.channels?.Lansenger?.accounts,t),r.info(`[lanxin:${e.accountId}] Initialized bindings from config`),c==="webhook"||c==="https"?Kn({account:e,log:r,statusSink:o},{account:e,config:t,log:r,thinkingThresholdMs:0,botNames:[],statusSink:o}):await Jn({account:e,config:t,log:r,thinkingThresholdMs:0,botNames:[],statusSink:o})}async function Jn(n){let{account:e,log:t,statusSink:r}=n,o=e.accountId;t.info(`[lanxin:${o}] Starting WebSocket provider config=${JSON.stringify(e.config)} (botType=${e.config.botType??"smart"}, appId=${e.appId}) on port ${yt(e.config)} `);let a=e.appId;if(we[a]){let l=we[a];if(le[l]){let{client:d}=le[l];if(d.isConnected())return t.info(`[lanxin:${o}] WebSocket client already exists for appId ${a}, reusing existing connection from account ${l}`),{stop:le[l].stop}}}if(le[o]){let{client:l}=le[o];if(l.isConnected())return t.info(`[lanxin:${o}] WebSocket client already connected, reusing existing connection`),we[a]=o,{stop:le[o].stop}}let{client:s,stop:c}=await br({account:e,log:t,statusSink:r,onMessage:l=>{Ir(l,n)},onConnect:()=>{t.info(`[lanxin:${o}] WebSocket provider started`)},onDisconnect:(l,d)=>{t.info(`[lanxin:${o}] WebSocket disconnected: ${l} ${d}`),we[a]===o&&delete we[a]},onError:l=>{t.error(`[lanxin:${o}] WebSocket error: ${l instanceof Error?l.message:JSON.stringify(l)}`)},onpong:()=>{t.info(`[lanxin:${o}] WebSocket heartbeat pong received`)}});return le[o]={client:s,stop:c},we[a]=o,{stop:c}}function Kn(n,e){let{account:t,log:r,statusSink:o}=n,a=yt(t.config);t.config.webhookPort=a+zn(1,100);let s=t.config.webhookPort,c=ir(t.config),l=wr.createServer(async(p,f)=>{if(p.method!=="POST"||p.url!==c){f.statusCode=404,f.end("Not Found");return}let g="";p.on("data",m=>g+=m.toString()),p.on("end",async()=>{try{let m=JSON.parse(g);r.info(`webhook: Received payload: ${JSON.stringify(m)}`);let I=t.config.encryptKey||"NTQxNEY5NUM2NDFBMENGREU2MjI5MTRGMDdERTEzNjc",v=$r(m,I,r);if(v.length===0){f.statusCode=200,f.end(JSON.stringify({errCode:0,errMsg:"ok"}));return}for(let b of v)await Ir(b,e);f.statusCode=200,f.end(JSON.stringify({errCode:0,errMsg:"ok"}))}catch(m){f.statusCode=400,f.end("Bad Request"),r.error(`webhook: Error processing request: ${m instanceof Error?m.message:String(m)}`)}})});return l.listen(s,()=>{r.info(`[lanxin:${t.accountId}] Webhook server listening on port ${s}, path ${c}`),o?.({running:!0,lastStartAt:Date.now(),mode:"webhook",botType:t.config.botType??"smart"})}),l.on("error",p=>{p.code==="EADDRINUSE"?r.error(`[lanxin:${t.accountId}] Port ${s} is already in use. If you have multiple accounts using webhook mode, each needs a different webhookPort.`):r.error(`[lanxin:${t.accountId}] Webhook server error: ${p.message}`),o?.({running:!1,lastError:p.message})}),{stop:()=>{r.info(`[lanxin:${t.accountId}] Stopping Webhook server`),l.closeAllConnections(),l.close(),o?.({running:!1,lastStopAt:Date.now()})}}}async function Ir(n,e){i.debug(`[lanxin:${e.account.accountId}] Received event: ${JSON.stringify(n)} testMode: ${e.account.config.testMode?.enabled??!1}`);let t=n.data,r;if(t?.type==="staff_info"&&t?.data){let T=t.data;if(r=T.staffId,r){let $=t.id||`${r}_${T.timestamp||Date.now()}`;Te.setStaffId(e.account.accountId,r),i.info(`[lanxin:${e.account.accountId}] Cached staffId: ${r}`);try{let{updateOpenStaffId:w}=await Promise.resolve().then(()=>(ze(),yr));w({cfg:e.config,accountId:e.account.accountId,staffId:r}),i.info(`[lanxin:${e.account.accountId}] Updated openStaffId in config: ${r}`)}catch(w){i.error(`[lanxin:${e.account.accountId}] Error updating openStaffId in config: ${w instanceof Error?w.message:String(w)}`)}try{let w=await E.staff.getStaffInfo(e.account.config,r);w?(Te.setStaffInfo(e.account.accountId,w),i.info(`[lanxin:${e.account.accountId}] Cached staff info: name=${w.name}, orgName=${w.orgName}, status=${w.status}`)):i.info(`[lanxin:${e.account.accountId}] Failed to fetch staff info for staffId: ${r}`)}catch(w){i.error(`[lanxin:${e.account.accountId}] Error fetching staff info: ${w instanceof Error?w.message:String(w)}`)}if(e.account.config.testMode?.enabled??!1){i.info(`[lanxin:${e.account.accountId}] Test mode enabled, sending staff_info to staffId`);let w=`Test Mode - Staff Info
|
|
4
4
|
|
|
5
5
|
StaffId: ${r}
|
|
6
|
-
Timestamp: ${
|
|
7
|
-
[\u6587\u4EF6] ${de.path}`}else i.error(`[lanxin:${e.account.accountId}] Failed to get media URL for attachment: ${B.id}`)}catch(q){i.error(`[lanxin:${e.account.accountId}] Error processing attachment: ${q instanceof Error?q.message:String(q)}`)}}let b=yt(),k=b.channel;if(!k?.reply?.dispatchReplyWithBufferedBlockDispatcher){i.error(`[lanxin:${e.account.accountId}] dispatchReplyWithBufferedBlockDispatcher not available`);return}let S=ae().getBotAgent(e.account.appId,e.account.config);i.info(`[lanxin:${e.account.accountId}] Using agent: ${S} for appId: ${e.account.appId}`);let C={Body:I,RawBody:I,CommandBody:I,From:m,To:m,SessionKey:`agent:${S}:lanxin:${g==="p2p"?m:l}`,AccountId:e.account.accountId,MessageSid:d||`msg_${Date.now()}`,ChatType:"direct",ConversationLabel:m,SenderId:m,CommandAuthorized:!0,Provider:"lanxin",Surface:"lanxin",OriginatingChannel:"lanxin",OriginatingTo:m,DeliveryContext:{channel:"lanxin",to:m,accountId:e.account.accountId,agentId:S}};i.info(`[lanxin:${e.account.accountId}] Dispatching message with context: ${JSON.stringify(C)}`);let j=!1,R=e.thinkingThresholdMs>0?setTimeout(async()=>{j||i.info(`[lanxin:${e.account.accountId}] Message processing taking too long, sending placeholder`)},e.thinkingThresholdMs):null;try{await k.reply.dispatchReplyWithBufferedBlockDispatcher({ctx:C,cfg:b.config?.loadConfig?.()??e.config,replyResolver:null,agentId:S,dispatcherOptions:{deliver:async B=>{j=!0,R&&clearTimeout(R),i.info(`[lanxin:${e.account.accountId}] Received OpenClaw reply: ${JSON.stringify(B)}`);let q=B,de=typeof q=="string"?q:q?.text??q?.body??"";i.info(`[lanxin:${e.account.accountId}] Reply text: ${de.slice(0,80)}`);let lt=(de||"").trim();if(!lt||lt==="NO_REPLY"||lt.endsWith("NO_REPLY")){i.info(`[lanxin:${e.account.accountId}] Skipping empty or NO_REPLY message`);return}let dt=Ie.getStaffId(e.account.accountId);if(dt){i.info(`[lanxin:${e.account.accountId}] Sending message to cached staffId: ${dt}`);let pt=await Pe(e.account.config,dt,de,1);pt.ok?i.info(`[lanxin:${e.account.accountId}] Message sent successfully: ${pt.messageId}`):i.error(`[lanxin:${e.account.accountId}] Failed to send message: ${pt.error}`)}else i.info(`[lanxin:${e.account.accountId}] No cached staffId found, using provided chatId: ${l}`),await or(B,l,g||"p2p",e.account,e.config,i,e.statusSink)},onError:B=>{j=!0,R&&clearTimeout(R),i.error(`[lanxin:${e.account.accountId}] Dispatcher error: ${B.message}`)}}})}catch(B){j=!0,R&&clearTimeout(R),i.error(`[lanxin:${e.account.accountId}] Dispatch error: ${B instanceof Error?B.message:String(B)}`)}}}var ce,we,hr=w(()=>{u();wt();ar();Ge();$t();G();He();ce={},we={}});var Je,te,Mt,Ct,Et,Pt,Ut,Nt,Lt,E,$r=w(()=>{u();z();Z();W();Je=globalThis.Blob;if(!Je){let{Blob:n}=oe("buffer");Je=n}te=class{async getAppToken(e){return await M.getAppToken(e)}async fetchApi(e,t,r={}){let a=null;for(let s=1;s<=3;s++)try{let c=await this.getAppToken(e),d=`${X(e)}${t}?app_token=${c}`;i.info(`API \u8BF7\u6C42 (\u5C1D\u8BD5 ${s}/3): ${d}`);let p=await fetch(d,{...r,headers:{"Content-Type":"application/json",...r.headers}});if(!p.ok){let g=`HTTP ${p.status}: ${p.statusText}`;if(i.warn(`API \u8BF7\u6C42\u5931\u8D25 (\u5C1D\u8BD5 ${s}/3): ${g}`),a=U(g,A.NETWORK,`HTTP_${p.status}`,{url:d,status:p.status,statusText:p.statusText}),p.status>=500||p.status===429){let m=Math.pow(2,s-1)*1e3;i.info(`\u7B49\u5F85 ${m}ms \u540E\u91CD\u8BD5...`),await new Promise(T=>setTimeout(T,m));continue}throw a}let f=await p.json();if(f.errCode!==0){let g=f.errMsg;throw i.warn(`API \u9519\u8BEF (\u5C1D\u8BD5 ${s}/3): ${g}`),a=U(g,A.API,`ERR_${f.errCode}`,{errCode:f.errCode,errMsg:f.errMsg}),a}return i.info(`API \u8BF7\u6C42\u6210\u529F (\u5C1D\u8BD5 ${s}/3)`),f}catch(c){if(i.warn(`API \u8BF7\u6C42\u5F02\u5E38 (\u5C1D\u8BD5 ${s}/3): ${c instanceof Error?c.message:String(c)}`),a=c instanceof Error?c:new Error(String(c)),s<3){let l=Math.pow(2,s-1)*1e3;i.info(`\u7B49\u5F85 ${l}ms \u540E\u91CD\u8BD5...`),await new Promise(d=>setTimeout(d,l))}}throw a||new Error("API \u8BF7\u6C42\u5931\u8D25\uFF0C\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8BD5\u6B21\u6570")}},Mt=class extends te{async getStaffInfo(e,t){try{let r=`/v1/staffs/${encodeURIComponent(t)}/fetch`,o=await this.fetchApi(e,r);if(!o.data)throw U("\u672A\u8FD4\u56DE\u5458\u5DE5\u6570\u636E",A.API,"MISSING_DATA");return i.info(`\u6210\u529F\u83B7\u53D6\u5458\u5DE5\u4FE1\u606F: ${t}: ${o.data.name}`),o.data}catch(r){return i.error("\u83B7\u53D6\u5458\u5DE5\u4FE1\u606F\u5931\u8D25",{error:r,staffId:t}),null}}},Ct=class extends te{async sendPrivateMessage(e,t,r,o){try{let a=x.smartBot.privateMessage,s={userIdList:[t],msgType:r,msgData:o};i.info("\u53D1\u9001\u79C1\u804A\u6D88\u606F\u8BF7\u6C42:",{userId:t,msgType:r,requestBody:JSON.stringify(s)});let c=await this.fetchApi(e,a,{method:"POST",body:JSON.stringify(s)});return i.info(`\u79C1\u804A\u6D88\u606F\u53D1\u9001\u6210\u529F: ${c.data?.msgId}`),{ok:!0,messageId:c.data?.msgId}}catch(a){return i.error("\u53D1\u9001\u79C1\u804A\u6D88\u606F\u5931\u8D25",{error:a,userId:t}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async sendGroupMessage(e,t,r,o){try{let a=x.smartBot.groupMessage,s={groupId:t,msgType:r,msgData:o};i.debug("\u53D1\u9001\u7FA4\u6D88\u606F\u8BF7\u6C42:",{groupId:t,msgType:r,requestBody:JSON.stringify(s)});let c=await this.fetchApi(e,a,{method:"POST",body:JSON.stringify(s)});return i.info(`\u7FA4\u6D88\u606F\u53D1\u9001\u6210\u529F: ${c.data?.msgId}`),{ok:!0,messageId:c.data?.msgId}}catch(a){return i.error("\u53D1\u9001\u7FA4\u6D88\u606F\u5931\u8D25",{error:a,groupId:t}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}},Et=class extends te{async getGroups(e){try{let t=x.smartBot.groupsList,r=await this.fetchApi(e,t);return i.info(`\u6210\u529F\u83B7\u53D6 ${r.data?.groups?.length||0} \u4E2A\u7FA4\u7EC4`),r.data?.groups||[]}catch(t){return i.error("\u83B7\u53D6\u7FA4\u5217\u8868\u5931\u8D25",{error:t}),[]}}},Pt=class extends te{async uploadMedia(e,t,r,o){try{let a=await this.getAppToken(e),s=X(e),c=x.smartBot.uploadMedia,l="2";r==="video"?l="1":(r==="audio"||r==="file")&&(l="3");let d=`${s}${c}?type=${l}&app_token=${a}`;i.info("\u4E0A\u4F20\u5A92\u4F53\u6587\u4EF6"),i.info(`\u8BF7\u6C42 URL: ${d}`),i.info(`\u5A92\u4F53\u7C7B\u578B: ${r}, \u6587\u4EF6\u540D: ${o}`);let p=new FormData;o?t instanceof Buffer?p.append("media",new Je([t]),o):t instanceof Je?p.append("media",t,o):p.append("media",t):p.append("media",t);let f=await fetch(d,{method:"POST",body:p});if(!f.ok)throw U(`HTTP ${f.status}: ${f.statusText}`,A.NETWORK,`HTTP_${f.status}`,{url:d,status:f.status,statusText:f.statusText});let g=await f.json();if(g.errCode!==0)throw U(g.errMsg,A.API,`ERR_${g.errCode}`,{errCode:g.errCode,errMsg:g.errMsg});return i.info(`\u5A92\u4F53\u6587\u4EF6\u4E0A\u4F20\u6210\u529F: ${g.data?.mediaId}`),g.data?.mediaId||null}catch(a){return i.error("\u4E0A\u4F20\u5A92\u4F53\u6587\u4EF6\u5931\u8D25",{error:a}),null}}async getMediaUrl(e,t){try{let r=await this.getAppToken(e),o=X(e),a=`/v1/medias/${encodeURIComponent(t)}/path/fetch`,s=`${o}${a}?app_token=${r}`;i.info(`\u83B7\u53D6\u5A92\u4F53\u6587\u4EF6 URL: ${t}`),i.info(`\u8BF7\u6C42 URL: ${s}`);let c=await fetch(s,{method:"GET"});if(!c.ok)throw U(`HTTP ${c.status}: ${c.statusText}`,A.NETWORK,`HTTP_${c.status}`,{url:s,status:c.status,statusText:c.statusText});let l=await c.json();if(l.errCode!==0)throw U(l.errMsg,A.API,`ERR_${l.errCode}`,{errCode:l.errCode,errMsg:l.errMsg});return i.info(`\u5A92\u4F53\u6587\u4EF6 URL \u83B7\u53D6\u6210\u529F: ${l.data?.mediaPath}`),l.data?.mediaPath||null}catch(r){return i.error("\u83B7\u53D6\u5A92\u4F53\u6587\u4EF6 URL \u5931\u8D25",{error:r,mediaId:t}),null}}},Ut=class extends te{async getDepartmentInfo(e,t){try{let r=`/v1/depts/${encodeURIComponent(t)}/fetch`,o=await this.fetchApi(e,r);return i.info(`\u6210\u529F\u83B7\u53D6\u90E8\u95E8\u4FE1\u606F: ${t}`),o.data||null}catch(r){return i.error("\u83B7\u53D6\u90E8\u95E8\u4FE1\u606F\u5931\u8D25",{error:r,deptId:t}),null}}async getDepartmentList(e){try{let r=await this.fetchApi(e,"/v1/depts/list");return i.info(`\u6210\u529F\u83B7\u53D6 ${r.data?.depts?.length||0} \u4E2A\u90E8\u95E8`),r.data?.depts||[]}catch(t){return i.error("\u83B7\u53D6\u90E8\u95E8\u5217\u8868\u5931\u8D25",{error:t}),[]}}},Nt=class extends te{async createWebSocketEndpoint(e){try{let o=`${X(e)}/v1/ws/endpoint/create`;i.info(`\u521B\u5EFA WebSocket \u7AEF\u70B9: ${o}`);let a=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:e.appId,secret:e.appSecret})});if(!a.ok)throw U(`HTTP ${a.status}: ${a.statusText}`,A.NETWORK,`HTTP_${a.status}`,{url:o,status:a.status,statusText:a.statusText});let s=await a.json();if(s.errCode!==0)throw U(s.errMsg,A.API,`ERR_${s.errCode}`,{errCode:s.errCode,errMsg:s.errMsg});if(!s.data?.wsEndpoint)throw U("\u672A\u8FD4\u56DE WebSocket \u7AEF\u70B9",A.API,"MISSING_DATA");return i.info(`WebSocket \u7AEF\u70B9\u521B\u5EFA\u6210\u529F: ${s.data.wsEndpoint}`),i.info(`\u5FC3\u8DF3\u95F4\u9694: ${s.data.pingInterval} \u79D2`),s.data.wsEndpoint}catch(t){return i.error("\u521B\u5EFA WebSocket \u7AEF\u70B9\u5931\u8D25",{error:t}),null}}},Lt=class{staff;message;group;media;department;websocket;constructor(){this.staff=new Mt,this.message=new Ct,this.group=new Et,this.media=new Pt,this.department=new Ut,this.websocket=new Nt}async getAppToken(e){return await M.getAppToken(e)}async healthCheck(e){try{let t=await this.getAppToken(e),o=`${X(e)}/v1/app/status?app_token=${t}`;return(await fetch(o,{method:"GET",headers:{"Content-Type":"application/json"}})).ok}catch(t){return i.error("\u5065\u5EB7\u68C0\u67E5\u5931\u8D25",{error:t}),!1}}},E=new Lt});var Ke=w(()=>{u();$r()});import Gn from"ws";async function kr(n){let e=new Dt(n);await e.connect(!1);let t=()=>{e.close()},r=()=>{n.log.info(`[lanxin:${n.account.accountId}] Process exit, closing WS`),t()};return process.on("SIGINT",r),process.on("SIGTERM",r),process.on("exit",r),{client:e,stop:t}}var Dt,br=w(()=>{u();z();Ke();Dt=class{ws=null;reconnectTimer=null;heartbeatTimer=null;options;connected=!1;currentWsUrl=null;wsUrlExpiry=null;ticketValidityMs=2*60*60*1e3;baseReconnectDelayMs=3e3;maxReconnectDelayMs=3e4;reconnectAttempts=0;maxReconnectAttempts=10;heartbeatIntervalMs=3e4;connectTime=null;currentTicket=null;constructor(e){this.options=e}async getWebSocketUrl(){let{account:e,log:t}=this.options,{appId:r,appSecret:o}=e;if(t.debug?.(`[lanxin:${e.accountId}] Getting WebSocket URL for appId: ${r}`),this.currentWsUrl&&this.wsUrlExpiry&&Date.now()<this.wsUrlExpiry)return t.debug?.(`[lanxin:${e.accountId}] Using cached WebSocket URL: ${this.currentWsUrl}`),this.currentWsUrl;try{let c=await E.websocket.createWebSocketEndpoint(e.config);if(c){t.debug?.(`[lanxin:${e.accountId}] Got new WebSocket URL from API: ${c}`),this.currentWsUrl=c,this.wsUrlExpiry=Date.now()+this.ticketValidityMs;let l=new URLSearchParams(c.split("?")[1]);return this.currentTicket=l.get("ticket")||null,c}t.debug?.(`[lanxin:${e.accountId}] Failed to get WebSocket URL from API, falling back to config`)}catch(c){t.error(`[lanxin:${e.accountId}] Error getting WebSocket URL from API: ${c instanceof Error?c.message:String(c)}`)}let a=er(e.config);a.endsWith("/")||(a+="/");let s=`${a}open-apis/im/v1/ws/${r}`;return t.debug?.(`[lanxin:${e.accountId}] Using WebSocket URL from config: ${s}`),s}async connect(e=!1){try{let{account:t,log:r}=this.options;if(this.connected&&this.ws){r.debug?.(`[lanxin:${t.accountId}] WebSocket is already connected, skipping connect`);return}e&&(r.debug?.(`[lanxin:${t.accountId}] Forcing new WebSocket URL for connection`),this.currentWsUrl=null,this.wsUrlExpiry=null);let o=await this.getWebSocketUrl();r.info(`[lanxin:${t.accountId}] Connecting to WebSocket for appId: ${t.appId}`),r.info(`[lanxin:${t.accountId}] WebSocket URL: ${o}`),this.options.statusSink?.({connecting:!0,wsUrl:o,appId:t.appId}),this.ws=new Gn(o,{handshakeTimeout:15e3,perMessageDeflate:!1,protocolVersion:13});let a=setTimeout(()=>{!this.connected&&this.ws&&(r.error(`[lanxin:${t.accountId}] WebSocket connection timeout after 15 seconds`),this.options.statusSink?.({running:!1,connecting:!1,lastError:"WebSocket connection timeout"}),this.ws.close(408,"Connection timeout"))},15e3);this.ws.onopen=()=>{if(clearTimeout(a),this.connected=!0,this.reconnectAttempts=0,this.connectTime=Date.now(),r.info(`[lanxin:${t.accountId}] WebSocket connected for appId: ${t.appId}`),this.options.statusSink?.({running:!0,connecting:!1,lastStartAt:Date.now(),mode:"websocket",botType:t.config.botType??"smart",appId:t.appId}),this.ws&&this.ws._socket){let s=this.ws._socket;s.setKeepAlive(!0,3e4),s.setTimeout(0)}this.startHeartbeat(),this.options.onConnect?.()},this.ws.onmessage=s=>{r.debug?.(`[lanxin:${t.accountId}] WebSocket message received`);try{let c=JSON.parse(s.data);if(c.events&&c.events.length>0)for(let l of c.events)this.options.onMessage(l)}catch(c){r.error(`[lanxin:${t.accountId}] Error parsing WebSocket message: ${c instanceof Error?c.message:String(c)}`)}},this.ws.onerror=s=>{let c;s instanceof Error?c=s.message:c=String(s),r.error(`[lanxin:${t.accountId}] WebSocket error: ${c}`),this.options.statusSink?.({error:c}),this.options.onError?.(s)},this.ws.onclose=s=>{let c=Date.now(),l=this.connectTime?Math.round((c-this.connectTime)/1e3):0;r.error(`[lanxin:${t.accountId}] WebSocket disconnected: ${s.code} ${s.reason}`),r.info(`[lanxin:${t.accountId}] Connection duration: ${l}s`),this.connected=!1,this.stopHeartbeat(),this.ws=null,this.options.statusSink?.({running:!1,connecting:!1,lastStopAt:Date.now(),lastError:`WebSocket disconnected: ${s.code} ${s.reason}`}),this.options.onDisconnect?.(s.code,s.reason),this.attemptReconnect()}}catch(t){let{account:r,log:o}=this.options;o.error(`[lanxin:${r.accountId}] Error connecting to WebSocket: ${t instanceof Error?t.message:String(t)}`),this.options.statusSink?.({running:!1,connecting:!1,lastError:t instanceof Error?t.message:String(t)}),this.options.onError?.(t),this.attemptReconnect()}}attemptReconnect(){let{account:e,log:t}=this.options;if(this.reconnectTimer)return;if(this.reconnectAttempts>=this.maxReconnectAttempts){t.error(`[lanxin:${e.accountId}] Max reconnect attempts reached`),this.options.statusSink?.({running:!1,lastError:"Max reconnect attempts reached"});return}this.reconnectAttempts++;let r=Math.min(this.baseReconnectDelayMs*Math.pow(2,this.reconnectAttempts-1),this.maxReconnectDelayMs);t.debug?.(`[lanxin:${e.accountId}] Reconnect in ${r}ms (${this.reconnectAttempts}/${this.maxReconnectAttempts})`),this.options.statusSink?.({reconnecting:!0,reconnectAttempt:this.reconnectAttempts}),this.reconnectTimer=setTimeout(async()=>{this.reconnectTimer=null;try{await this.connect(!0),t.info(`[lanxin:${e.accountId}] Reconnected successfully`),this.options.statusSink?.({reconnecting:!1,lastReconnectSuccess:Date.now()})}catch{t.error(`[lanxin:${e.accountId}] Reconnect failed`),this.attemptReconnect()}},r)}send(e){this.ws&&this.connected&&this.ws.send(e)}startHeartbeat(){let{account:e,log:t}=this.options;this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{if(this.ws&&this.connected)try{this.ws.ping(),t.debug?.(`[lanxin:${e.accountId}] Heartbeat ping sent`)}catch{t.error(`[lanxin:${e.accountId}] Heartbeat error`)}},this.heartbeatIntervalMs),t.debug?.(`[lanxin:${e.accountId}] Standard heartbeat started (30s)`)}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}close(){let{account:e,log:t}=this.options;t.info(`[lanxin:${e.accountId}] Closing WebSocket`),this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.stopHeartbeat(),this.ws&&(this.ws.close(1e3,"Normal closure"),this.ws=null),this.connected=!1,this.options.statusSink?.({running:!1,lastStopAt:Date.now()})}isConnected(){return this.connected}}});var Sr=w(()=>{u();hr();br()});async function Ve(n,e,t,r="formatText",o=1){if(!e?.trim())return{ok:!1,error:"No userId provided"};try{i.info("Sending smart bot private message",{userId:e,msgType:r,formatType:o,text:t.slice(0,80)});let a=await M.getAppToken(n),s=F(n.apiGatewayUrl),c=x.smartBot.privateMessage,l=e.trim();if(!l)return i.warn("Invalid userId",{userId:e}),{ok:!1,error:"Invalid userId"};let d;r==="formatText"?d={formatText:{formatType:o,text:t}}:d={text:{content:t}};let p={userIdList:[l],msgType:r,msgData:d};i.info("Sending message to Lanxin API",{apiUrl:s,endpoint:c,userId:l,msgType:r,body:p});let f=await fetch(`${s}${c}?app_token=${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(p)});if(!f.ok){let m=`HTTP ${f.status}: ${f.statusText}`;return i.error(m,{url:`${s}${c}`,status:f.status}),{ok:!1,error:m}}let g=await f.json();return g.errCode!==0?(i.error("Lanxin API error",{errCode:g.errCode,errMsg:g.errMsg,apiUrl:s,endpoint:c}),{ok:!1,error:g.errMsg}):(i.info("Message sent successfully",{messageId:g.data?.msgId,userId:l,msgType:r}),{ok:!0,messageId:g.data?.msgId})}catch(a){return i.error("Error sending message",{error:a,userId:e,msgType:r}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function Pe(n,e,t,r=1){return await Ve(n,e,t,"formatText",r)}async function H(n,e,t,r,o){if(!t?.trim())return{ok:!1,error:"No recipient provided"};let a=o?.msgType||"text",s=o?.formatType||1;if(n==="smart")return o?.isGroup?await K(e,t,"formatText",{formatText:{formatType:1,text:r}}):await Ve(e,t,r,a,s);if(n==="webhook"){let c=o?.hookToken||e.hookToken;return c?await J(e,c,"text",{text:{content:r}}):{ok:!1,error:"No hookToken provided for webhook bot"}}return{ok:!1,error:`Unknown bot type: ${n}`}}var vr=w(()=>{u();Q();z();Z();be();W()});import Ar from"node:fs";async function Mr(n,e,t,r){try{i.debug("Uploading media file",{fileName:t,fileType:r});let o=await M.getAppToken(n),a=F(n.apiGatewayUrl),s=x.smartBot.uploadMedia,c;switch(r.toLowerCase()){case"video":c=1;break;case"image":c=2;break;case"audio":case"voice":c=3;break;case"file":c=3;break;default:c=3}let l;if(typeof process<"u"&&process.versions&&process.versions.node){let p="----WebKitFormBoundary"+Math.random().toString(36).substring(2),f=`\r
|
|
6
|
+
Timestamp: ${T.timestamp||new Date().toISOString()}`;i.info(`[lanxin:${e.account.accountId}] Sending message content: ${w}`);let S=await E.message.sendPrivateMessage(e.account.config,r,"text",{text:{content:w}});S.ok?i.info(`[lanxin:${e.account.accountId}] Staff info sent successfully: ${S.messageId}`):i.error(`[lanxin:${e.account.accountId}] Failed to send staff info: ${S.error}`)}return}}if(t?.type==="card_action"&&t?.data){let T=t.data,$=T.actionType,k=T.actionValue;if($==="link")try{let w=new Hn(k),S=w.searchParams.get("approvalId"),M=w.searchParams.get("action"),j=w.searchParams.get("userId"),_=w.searchParams.get("accountId");if(S&&M&&j&&_){i.info(`[lanxin:${e.account.accountId}] Card button clicked: ${M} for ${S} by ${j}`),await gr(S,M,j,_,e.account.config),await Le(e.account.config,j,`\u5BA1\u6279\u5DF2\u5904\u7406\uFF1A${M==="approve"?"\u540C\u610F":"\u62D2\u7EDD"}\u4E86\u64CD\u4F5C`,1);return}}catch(w){i.error(`[lanxin:${e.account.accountId}] Error parsing card action URL: ${w instanceof Error?w.message:String(w)}`)}}if(e.account.config.testMode?.enabled??!1){i.info(`[lanxin:${e.account.accountId}] Test mode enabled, skipping non-staff_info event`);return}let a=n,s=a.id||a.data?.id||a.data?.data?.id||`event_${Date.now()}`;if(Ar(s)){i.info(`[lanxin:${e.account.accountId}] Duplicate event detected, skipping: ${s}`);return}await vr.classifyAndProcess(n,e.account.accountId);let c=Sr.convertLanxinEventToOpenClawMessage(n,e.account.accountId);if(!c){i.info(`[lanxin:${e.account.accountId}] No message to process or unhandled event type`);return}let{chatId:l,messageId:d,messageType:p,text:f,chatType:g,senderId:m,mentions:I,attachments:v}=c;if(!l||!f)return;let b={message:{type:p,content:f},userId:m,chatId:l,accountId:e.account.accountId,config:e.account.config,response:void 0},D=!0;if(await At(b,async()=>{await Ct(b,async()=>{let{message:T,userId:$,accountId:k,config:w}=b,S=Te.getStaffId(k)||$;if(T.type==="text"){let M=T.content.trim();if(M==="/lanxin agent"){let _=se().getBotAgent(e.account.appId,e.account.config);b.response={type:"text",content:`\u5F53\u524D\u673A\u5668\u4EBA\u7ED1\u5B9A\u7684 Agent: ${_}`},D=!1}else M==="/lanxin agent-list"?(b.response={type:"text",content:"\u673A\u5668\u4EBA\u4E0E Agent \u7684\u7ED1\u5B9A\u5173\u7CFB\u5728 OpenClaw \u914D\u7F6E\u6587\u4EF6\u7684 bindings \u90E8\u5206\u5B9A\u4E49\n\u4F7F\u7528 `openclaw agents bindings` \u547D\u4EE4\u67E5\u770B\u6240\u6709\u7ED1\u5B9A\u5173\u7CFB"},D=!1):M.startsWith("/lanxin agent-set ")?(b.response={type:"text",content:"\u673A\u5668\u4EBA\u4E0E Agent \u7684\u7ED1\u5B9A\u5173\u7CFB\u5728 OpenClaw \u914D\u7F6E\u6587\u4EF6\u7684 bindings \u90E8\u5206\u5B9A\u4E49\n\u4F7F\u7528 `openclaw agents bind --agent <agentId> --bind lanxin:<accountId>` \u547D\u4EE4\u8BBE\u7F6E\u7ED1\u5B9A\u5173\u7CFB"},D=!1):D=!0}else D=!0})}),b.response){i.info(`[lanxin:${e.account.accountId}] Middleware handled message, sending response`);let $=Te.getStaffId(e.account.accountId)||l;if(Array.isArray(b.response))for(let k of b.response)k.type==="text"?await Le(e.account.config,$,k.content,1):k.type==="image"?await E.message.sendPrivateMessage(e.account.config,$,"image",{image:{content:k.content,filename:k.filename}}):k.type==="file"&&await E.message.sendPrivateMessage(e.account.config,$,"file",{file:{content:k.content,filename:k.filename}});else{let k=b.response;k.type==="text"?await Le(e.account.config,$,k.content,1):k.type==="image"?await E.message.sendPrivateMessage(e.account.config,$,"image",{image:{content:k.content,filename:k.filename}}):k.type==="file"?await E.message.sendPrivateMessage(e.account.config,$,"file",{file:{content:k.content,filename:k.filename}}):k.type==="linkCard"?await E.message.sendPrivateMessage(e.account.config,$,"linkCard",{linkCard:k.content}):k.type==="appCard"?await E.message.sendPrivateMessage(e.account.config,$,"appCard",{appCard:k.content}):k.type==="oacard"?await E.message.sendPrivateMessage(e.account.config,$,"oacard",{oacard:k.content}):k.type==="appArticles"?await E.message.sendPrivateMessage(e.account.config,$,"appArticles",{appArticles:k.content}):k.type==="system"&&await E.message.sendPrivateMessage(e.account.config,$,"system",k.content)}return}if(D){if(i.info(`[lanxin:${e.account.accountId}] Received message: ${f.slice(0,80)} from ${l}, type: ${p}`),g==="group"&&!Cr(f,I||[],e.botNames))return;e.statusSink?.({lastInboundAt:Date.now()});let T=f;if(v&&v.length>0){i.info(`[lanxin:${e.account.accountId}] Processing ${v.length} attachments`);for(let B of v)if(B.id)try{let q=await E.media.getMediaUrl(e.account.config,B.id);if(q){let pe=await Pe(q,m);i.info(`[lanxin:${e.account.accountId}] Downloaded media to: ${pe.path}`),T+=`
|
|
7
|
+
[\u6587\u4EF6] ${pe.path}`}else i.error(`[lanxin:${e.account.accountId}] Failed to get media URL for attachment: ${B.id}`)}catch(q){i.error(`[lanxin:${e.account.accountId}] Error processing attachment: ${q instanceof Error?q.message:String(q)}`)}}let $=wt(),k=$.channel;if(!k?.reply?.dispatchReplyWithBufferedBlockDispatcher){i.error(`[lanxin:${e.account.accountId}] dispatchReplyWithBufferedBlockDispatcher not available`);return}let S=se().getBotAgent(e.account.appId,e.account.config);i.info(`[lanxin:${e.account.accountId}] Using agent: ${S} for appId: ${e.account.appId}`);let M={Body:T,RawBody:T,CommandBody:T,From:m,To:m,SessionKey:`agent:${S}:lanxin:${g==="p2p"?m:l}`,AccountId:e.account.accountId,MessageSid:d||`msg_${Date.now()}`,ChatType:"direct",ConversationLabel:m,SenderId:m,CommandAuthorized:!0,Provider:"lanxin",Surface:"lanxin",OriginatingChannel:"lanxin",OriginatingTo:m,DeliveryContext:{channel:"lanxin",to:m,accountId:e.account.accountId,agentId:S}};i.info(`[lanxin:${e.account.accountId}] Dispatching message with context: ${JSON.stringify(M)}`);let j=!1,_=e.thinkingThresholdMs>0?setTimeout(async()=>{j||i.info(`[lanxin:${e.account.accountId}] Message processing taking too long, sending placeholder`)},e.thinkingThresholdMs):null;try{await k.reply.dispatchReplyWithBufferedBlockDispatcher({ctx:M,cfg:$.config?.loadConfig?.()??e.config,replyResolver:null,agentId:S,dispatcherOptions:{deliver:async B=>{j=!0,_&&clearTimeout(_),i.info(`[lanxin:${e.account.accountId}] Received OpenClaw reply: ${JSON.stringify(B)}`);let q=B,pe=typeof q=="string"?q:q?.text??q?.body??"";i.info(`[lanxin:${e.account.accountId}] Reply text: ${pe.slice(0,80)}`);let dt=(pe||"").trim();if(!dt||dt==="NO_REPLY"||dt.endsWith("NO_REPLY")){i.info(`[lanxin:${e.account.accountId}] Skipping empty or NO_REPLY message`);return}let pt=Te.getStaffId(e.account.accountId);if(pt){i.info(`[lanxin:${e.account.accountId}] Sending message to cached staffId: ${pt}`);let ut=await Le(e.account.config,pt,pe,1);ut.ok?i.info(`[lanxin:${e.account.accountId}] Message sent successfully: ${ut.messageId}`):i.error(`[lanxin:${e.account.accountId}] Failed to send message: ${ut.error}`)}else i.info(`[lanxin:${e.account.accountId}] No cached staffId found, using provided chatId: ${l}`),await dr(B,l,g||"p2p",e.account,e.config,i,e.statusSink)},onError:B=>{j=!0,_&&clearTimeout(_),i.error(`[lanxin:${e.account.accountId}] Dispatcher error: ${B.message}`)}}})}catch(B){j=!0,_&&clearTimeout(_),i.error(`[lanxin:${e.account.accountId}] Dispatch error: ${B instanceof Error?B.message:String(B)}`)}}}var le,we,xr=y(()=>{u();Tt();pr();Ge();$t();L();He();le={},we={}});var Je,re,Mt,Et,Pt,Lt,Ut,Nt,Rt,E,Mr=y(()=>{u();z();Z();G();Je=globalThis.Blob;if(!Je){let{Blob:n}=ee("buffer");Je=n}re=class{async getAppToken(e){return await C.getAppToken(e)}async fetchApi(e,t,r={}){let a=null;for(let s=1;s<=3;s++)try{let c=await this.getAppToken(e),d=`${Y(e)}${t}?app_token=${c}`;i.info(`API \u8BF7\u6C42 (\u5C1D\u8BD5 ${s}/3): ${d}`);let p=await fetch(d,{...r,headers:{"Content-Type":"application/json",...r.headers}});if(!p.ok){let g=`HTTP ${p.status}: ${p.statusText}`;if(i.warn(`API \u8BF7\u6C42\u5931\u8D25 (\u5C1D\u8BD5 ${s}/3): ${g}`),a=U(g,A.NETWORK,`HTTP_${p.status}`,{url:d,status:p.status,statusText:p.statusText}),p.status>=500||p.status===429){let m=Math.pow(2,s-1)*1e3;i.info(`\u7B49\u5F85 ${m}ms \u540E\u91CD\u8BD5...`),await new Promise(I=>setTimeout(I,m));continue}throw a}let f=await p.json();if(f.errCode!==0){let g=f.errMsg;throw i.warn(`API \u9519\u8BEF (\u5C1D\u8BD5 ${s}/3): ${g}`),a=U(g,A.API,`ERR_${f.errCode}`,{errCode:f.errCode,errMsg:f.errMsg}),a}return i.info(`API \u8BF7\u6C42\u6210\u529F (\u5C1D\u8BD5 ${s}/3)`),f}catch(c){if(i.warn(`API \u8BF7\u6C42\u5F02\u5E38 (\u5C1D\u8BD5 ${s}/3): ${c instanceof Error?c.message:String(c)}`),a=c instanceof Error?c:new Error(String(c)),s<3){let l=Math.pow(2,s-1)*1e3;i.info(`\u7B49\u5F85 ${l}ms \u540E\u91CD\u8BD5...`),await new Promise(d=>setTimeout(d,l))}}throw a||new Error("API \u8BF7\u6C42\u5931\u8D25\uFF0C\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8BD5\u6B21\u6570")}},Mt=class extends re{async getStaffInfo(e,t){try{let r=`/v1/staffs/${encodeURIComponent(t)}/fetch`,o=await this.fetchApi(e,r);if(!o.data)throw U("\u672A\u8FD4\u56DE\u5458\u5DE5\u6570\u636E",A.API,"MISSING_DATA");return i.info(`\u6210\u529F\u83B7\u53D6\u5458\u5DE5\u4FE1\u606F: ${t}: ${o.data.name}`),o.data}catch(r){return i.error("\u83B7\u53D6\u5458\u5DE5\u4FE1\u606F\u5931\u8D25",{error:r,staffId:t}),null}}},Et=class extends re{async sendPrivateMessage(e,t,r,o){try{let a=x.smartBot.privateMessage,s={userIdList:[t],msgType:r,msgData:o};i.info("\u53D1\u9001\u79C1\u804A\u6D88\u606F\u8BF7\u6C42:",{userId:t,msgType:r,requestBody:JSON.stringify(s)});let c=await this.fetchApi(e,a,{method:"POST",body:JSON.stringify(s)});return i.info(`\u79C1\u804A\u6D88\u606F\u53D1\u9001\u6210\u529F: ${c.data?.msgId}`),{ok:!0,messageId:c.data?.msgId}}catch(a){return i.error("\u53D1\u9001\u79C1\u804A\u6D88\u606F\u5931\u8D25",{error:a,userId:t}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async sendGroupMessage(e,t,r,o){try{let a=x.smartBot.groupMessage,s={groupId:t,msgType:r,msgData:o};i.debug("\u53D1\u9001\u7FA4\u6D88\u606F\u8BF7\u6C42:",{groupId:t,msgType:r,requestBody:JSON.stringify(s)});let c=await this.fetchApi(e,a,{method:"POST",body:JSON.stringify(s)});return i.info(`\u7FA4\u6D88\u606F\u53D1\u9001\u6210\u529F: ${c.data?.msgId}`),{ok:!0,messageId:c.data?.msgId}}catch(a){return i.error("\u53D1\u9001\u7FA4\u6D88\u606F\u5931\u8D25",{error:a,groupId:t}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}},Pt=class extends re{async getGroups(e){try{let t=x.smartBot.groupsList,r=await this.fetchApi(e,t);return i.info(`\u6210\u529F\u83B7\u53D6 ${r.data?.groups?.length||0} \u4E2A\u7FA4\u7EC4`),r.data?.groups||[]}catch(t){return i.error("\u83B7\u53D6\u7FA4\u5217\u8868\u5931\u8D25",{error:t}),[]}}},Lt=class extends re{async uploadMedia(e,t,r,o){try{let a=await this.getAppToken(e),s=Y(e),c=x.smartBot.uploadMedia,l="2";r==="video"?l="1":(r==="audio"||r==="file")&&(l="3");let d=`${s}${c}?type=${l}&app_token=${a}`;i.info("\u4E0A\u4F20\u5A92\u4F53\u6587\u4EF6"),i.info(`\u8BF7\u6C42 URL: ${d}`),i.info(`\u5A92\u4F53\u7C7B\u578B: ${r}, \u6587\u4EF6\u540D: ${o}`);let p=new FormData;o?t instanceof Buffer?p.append("media",new Je([t]),o):t instanceof Je?p.append("media",t,o):p.append("media",t):p.append("media",t);let f=await fetch(d,{method:"POST",body:p});if(!f.ok)throw U(`HTTP ${f.status}: ${f.statusText}`,A.NETWORK,`HTTP_${f.status}`,{url:d,status:f.status,statusText:f.statusText});let g=await f.json();if(g.errCode!==0)throw U(g.errMsg,A.API,`ERR_${g.errCode}`,{errCode:g.errCode,errMsg:g.errMsg});return i.info(`\u5A92\u4F53\u6587\u4EF6\u4E0A\u4F20\u6210\u529F: ${g.data?.mediaId}`),g.data?.mediaId||null}catch(a){return i.error("\u4E0A\u4F20\u5A92\u4F53\u6587\u4EF6\u5931\u8D25",{error:a}),null}}async getMediaUrl(e,t){try{let r=await this.getAppToken(e),o=Y(e),a=`/v1/medias/${encodeURIComponent(t)}/path/fetch`,s=`${o}${a}?app_token=${r}`;i.info(`\u83B7\u53D6\u5A92\u4F53\u6587\u4EF6 URL: ${t}`),i.info(`\u8BF7\u6C42 URL: ${s}`);let c=await fetch(s,{method:"GET"});if(!c.ok)throw U(`HTTP ${c.status}: ${c.statusText}`,A.NETWORK,`HTTP_${c.status}`,{url:s,status:c.status,statusText:c.statusText});let l=await c.json();if(l.errCode!==0)throw U(l.errMsg,A.API,`ERR_${l.errCode}`,{errCode:l.errCode,errMsg:l.errMsg});return i.info(`\u5A92\u4F53\u6587\u4EF6 URL \u83B7\u53D6\u6210\u529F: ${l.data?.mediaPath}`),l.data?.mediaPath||null}catch(r){return i.error("\u83B7\u53D6\u5A92\u4F53\u6587\u4EF6 URL \u5931\u8D25",{error:r,mediaId:t}),null}}},Ut=class extends re{async getDepartmentInfo(e,t){try{let r=`/v1/depts/${encodeURIComponent(t)}/fetch`,o=await this.fetchApi(e,r);return i.info(`\u6210\u529F\u83B7\u53D6\u90E8\u95E8\u4FE1\u606F: ${t}`),o.data||null}catch(r){return i.error("\u83B7\u53D6\u90E8\u95E8\u4FE1\u606F\u5931\u8D25",{error:r,deptId:t}),null}}async getDepartmentList(e){try{let r=await this.fetchApi(e,"/v1/depts/list");return i.info(`\u6210\u529F\u83B7\u53D6 ${r.data?.depts?.length||0} \u4E2A\u90E8\u95E8`),r.data?.depts||[]}catch(t){return i.error("\u83B7\u53D6\u90E8\u95E8\u5217\u8868\u5931\u8D25",{error:t}),[]}}},Nt=class extends re{async createWebSocketEndpoint(e){try{let o=`${Y(e)}/v1/ws/endpoint/create`;i.info(`\u521B\u5EFA WebSocket \u7AEF\u70B9: ${o}`);let a=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({appId:e.appId,secret:e.appSecret})});if(!a.ok)throw U(`HTTP ${a.status}: ${a.statusText}`,A.NETWORK,`HTTP_${a.status}`,{url:o,status:a.status,statusText:a.statusText});let s=await a.json();if(s.errCode!==0)throw U(s.errMsg,A.API,`ERR_${s.errCode}`,{errCode:s.errCode,errMsg:s.errMsg});if(!s.data?.wsEndpoint)throw U("\u672A\u8FD4\u56DE WebSocket \u7AEF\u70B9",A.API,"MISSING_DATA");return i.info(`WebSocket \u7AEF\u70B9\u521B\u5EFA\u6210\u529F: ${s.data.wsEndpoint}`),i.info(`\u5FC3\u8DF3\u95F4\u9694: ${s.data.pingInterval} \u79D2`),s.data.wsEndpoint}catch(t){return i.error("\u521B\u5EFA WebSocket \u7AEF\u70B9\u5931\u8D25",{error:t}),null}}},Rt=class{staff;message;group;media;department;websocket;constructor(){this.staff=new Mt,this.message=new Et,this.group=new Pt,this.media=new Lt,this.department=new Ut,this.websocket=new Nt}async getAppToken(e){return await C.getAppToken(e)}async healthCheck(e){try{let t=await this.getAppToken(e),o=`${Y(e)}/v1/app/status?app_token=${t}`;return(await fetch(o,{method:"GET",headers:{"Content-Type":"application/json"}})).ok}catch(t){return i.error("\u5065\u5EB7\u68C0\u67E5\u5931\u8D25",{error:t}),!1}}},E=new Rt});var Ke=y(()=>{u();Mr()});import Yn from"ws";async function br(n){let e=new Ot(n);await e.connect(!1);let t=()=>{e.close()},r=()=>{n.log.info(`[lanxin:${n.account.accountId}] Process exit, closing WS`),t()};return process.on("SIGINT",r),process.on("SIGTERM",r),process.on("exit",r),{client:e,stop:t}}var Ot,Er=y(()=>{u();z();Ke();Ot=class{ws=null;reconnectTimer=null;heartbeatTimer=null;options;connected=!1;currentWsUrl=null;wsUrlExpiry=null;ticketValidityMs=2*60*60*1e3;baseReconnectDelayMs=3e3;maxReconnectDelayMs=3e4;reconnectAttempts=0;maxReconnectAttempts=10;heartbeatIntervalMs=3e4;connectTime=null;currentTicket=null;constructor(e){this.options=e}async getWebSocketUrl(){let{account:e,log:t}=this.options,{appId:r,appSecret:o}=e;if(t.debug?.(`[lanxin:${e.accountId}] Getting WebSocket URL for appId: ${r}`),this.currentWsUrl&&this.wsUrlExpiry&&Date.now()<this.wsUrlExpiry)return t.debug?.(`[lanxin:${e.accountId}] Using cached WebSocket URL: ${this.currentWsUrl}`),this.currentWsUrl;try{let c=await E.websocket.createWebSocketEndpoint(e.config);if(c){t.debug?.(`[lanxin:${e.accountId}] Got new WebSocket URL from API: ${c}`),this.currentWsUrl=c,this.wsUrlExpiry=Date.now()+this.ticketValidityMs;let l=new URLSearchParams(c.split("?")[1]);return this.currentTicket=l.get("ticket")||null,c}t.debug?.(`[lanxin:${e.accountId}] Failed to get WebSocket URL from API, falling back to config`)}catch(c){t.error(`[lanxin:${e.accountId}] Error getting WebSocket URL from API: ${c instanceof Error?c.message:String(c)}`)}let a=sr(e.config);a.endsWith("/")||(a+="/");let s=`${a}open-apis/im/v1/ws/${r}`;return t.debug?.(`[lanxin:${e.accountId}] Using WebSocket URL from config: ${s}`),s}async connect(e=!1){try{let{account:t,log:r}=this.options;if(this.connected&&this.ws){r.debug?.(`[lanxin:${t.accountId}] WebSocket is already connected, skipping connect`);return}e&&(r.debug?.(`[lanxin:${t.accountId}] Forcing new WebSocket URL for connection`),this.currentWsUrl=null,this.wsUrlExpiry=null);let o=await this.getWebSocketUrl();r.info(`[lanxin:${t.accountId}] Connecting to WebSocket for appId: ${t.appId}`),r.info(`[lanxin:${t.accountId}] WebSocket URL: ${o}`),this.options.statusSink?.({connecting:!0,wsUrl:o,appId:t.appId}),this.ws=new Yn(o,{handshakeTimeout:15e3,perMessageDeflate:!1,protocolVersion:13});let a=setTimeout(()=>{!this.connected&&this.ws&&(r.error(`[lanxin:${t.accountId}] WebSocket connection timeout after 15 seconds`),this.options.statusSink?.({running:!1,connecting:!1,lastError:"WebSocket connection timeout"}),this.ws.close(408,"Connection timeout"))},15e3);this.ws.onopen=()=>{if(clearTimeout(a),this.connected=!0,this.reconnectAttempts=0,this.connectTime=Date.now(),r.info(`[lanxin:${t.accountId}] WebSocket connected for appId: ${t.appId}`),this.options.statusSink?.({running:!0,connecting:!1,lastStartAt:Date.now(),mode:"websocket",botType:t.config.botType??"smart",appId:t.appId}),this.ws&&this.ws._socket){let s=this.ws._socket;s.setKeepAlive(!0,3e4),s.setTimeout(0)}this.startHeartbeat(),this.options.onConnect?.()},this.ws.onmessage=s=>{r.debug?.(`[lanxin:${t.accountId}] WebSocket message received`);try{let c=JSON.parse(s.data);if(c.events&&c.events.length>0)for(let l of c.events)this.options.onMessage(l)}catch(c){r.error(`[lanxin:${t.accountId}] Error parsing WebSocket message: ${c instanceof Error?c.message:String(c)}`)}},this.ws.onerror=s=>{let c;s instanceof Error?c=s.message:c=String(s),r.error(`[lanxin:${t.accountId}] WebSocket error: ${c}`),this.options.statusSink?.({error:c}),this.options.onError?.(s)},this.ws.onclose=s=>{let c=Date.now(),l=this.connectTime?Math.round((c-this.connectTime)/1e3):0;r.error(`[lanxin:${t.accountId}] WebSocket disconnected: ${s.code} ${s.reason}`),r.info(`[lanxin:${t.accountId}] Connection duration: ${l}s`),this.connected=!1,this.stopHeartbeat(),this.ws=null,this.options.statusSink?.({running:!1,connecting:!1,lastStopAt:Date.now(),lastError:`WebSocket disconnected: ${s.code} ${s.reason}`}),this.options.onDisconnect?.(s.code,s.reason),this.attemptReconnect()}}catch(t){let{account:r,log:o}=this.options;o.error(`[lanxin:${r.accountId}] Error connecting to WebSocket: ${t instanceof Error?t.message:String(t)}`),this.options.statusSink?.({running:!1,connecting:!1,lastError:t instanceof Error?t.message:String(t)}),this.options.onError?.(t),this.attemptReconnect()}}attemptReconnect(){let{account:e,log:t}=this.options;if(this.reconnectTimer)return;if(this.reconnectAttempts>=this.maxReconnectAttempts){t.error(`[lanxin:${e.accountId}] Max reconnect attempts reached`),this.options.statusSink?.({running:!1,lastError:"Max reconnect attempts reached"});return}this.reconnectAttempts++;let r=Math.min(this.baseReconnectDelayMs*Math.pow(2,this.reconnectAttempts-1),this.maxReconnectDelayMs);t.debug?.(`[lanxin:${e.accountId}] Reconnect in ${r}ms (${this.reconnectAttempts}/${this.maxReconnectAttempts})`),this.options.statusSink?.({reconnecting:!0,reconnectAttempt:this.reconnectAttempts}),this.reconnectTimer=setTimeout(async()=>{this.reconnectTimer=null;try{await this.connect(!0),t.info(`[lanxin:${e.accountId}] Reconnected successfully`),this.options.statusSink?.({reconnecting:!1,lastReconnectSuccess:Date.now()})}catch{t.error(`[lanxin:${e.accountId}] Reconnect failed`),this.attemptReconnect()}},r)}send(e){this.ws&&this.connected&&this.ws.send(e)}startHeartbeat(){let{account:e,log:t}=this.options;this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{if(this.ws&&this.connected)try{this.ws.ping(),t.debug?.(`[lanxin:${e.accountId}] Heartbeat ping sent`)}catch{t.error(`[lanxin:${e.accountId}] Heartbeat error`)}},this.heartbeatIntervalMs),t.debug?.(`[lanxin:${e.accountId}] Standard heartbeat started (30s)`)}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}close(){let{account:e,log:t}=this.options;t.info(`[lanxin:${e.accountId}] Closing WebSocket`),this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.stopHeartbeat(),this.ws&&(this.ws.close(1e3,"Normal closure"),this.ws=null),this.connected=!1,this.options.statusSink?.({running:!1,lastStopAt:Date.now()})}isConnected(){return this.connected}}});var Pr=y(()=>{u();xr();Er()});async function Ve(n,e,t,r="formatText",o=1){if(!e?.trim())return{ok:!1,error:"No userId provided"};try{i.info("Sending smart bot private message",{userId:e,msgType:r,formatType:o,text:t.slice(0,80)});let a=await C.getAppToken(n),s=W(n.apiGatewayUrl),c=x.smartBot.privateMessage,l=e.trim();if(!l)return i.warn("Invalid userId",{userId:e}),{ok:!1,error:"Invalid userId"};let d;r==="formatText"?d={formatText:{formatType:o,text:t}}:d={text:{content:t}};let p={userIdList:[l],msgType:r,msgData:d};i.info("Sending message to Lanxin API",{apiUrl:s,endpoint:c,userId:l,msgType:r,body:p});let f=await fetch(`${s}${c}?app_token=${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(p)});if(!f.ok){let m=`HTTP ${f.status}: ${f.statusText}`;return i.error(m,{url:`${s}${c}`,status:f.status}),{ok:!1,error:m}}let g=await f.json();return g.errCode!==0?(i.error("Lanxin API error",{errCode:g.errCode,errMsg:g.errMsg,apiUrl:s,endpoint:c}),{ok:!1,error:g.errMsg}):(i.info("Message sent successfully",{messageId:g.data?.msgId,userId:l,msgType:r}),{ok:!0,messageId:g.data?.msgId})}catch(a){return i.error("Error sending message",{error:a,userId:e,msgType:r}),{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function Le(n,e,t,r=1){return await Ve(n,e,t,"formatText",r)}async function H(n,e,t,r,o){if(!t?.trim())return{ok:!1,error:"No recipient provided"};let a=o?.msgType||"text",s=o?.formatType||1;if(n==="smart")return o?.isGroup?await K(e,t,"formatText",{formatText:{formatType:1,text:r}}):await Ve(e,t,r,a,s);if(n==="webhook"){let c=o?.hookToken||e.hookToken;return c?await J(e,c,"text",{text:{content:r}}):{ok:!1,error:"No hookToken provided for webhook bot"}}return{ok:!1,error:`Unknown bot type: ${n}`}}var Lr=y(()=>{u();Q();z();Z();Se();G()});import Ur from"node:fs";async function Nr(n,e,t,r){try{i.debug("Uploading media file",{fileName:t,fileType:r});let o=await C.getAppToken(n),a=W(n.apiGatewayUrl),s=x.smartBot.uploadMedia,c;switch(r.toLowerCase()){case"video":c=1;break;case"image":c=2;break;case"audio":case"voice":c=3;break;case"file":c=3;break;default:c=3}let l;if(typeof process<"u"&&process.versions&&process.versions.node){let p="----WebKitFormBoundary"+Math.random().toString(36).substring(2),f=`\r
|
|
8
8
|
--${p}`,g=`\r
|
|
9
9
|
--${p}--`,m=[];m.push(`${f}\r
|
|
10
10
|
Content-Disposition: form-data; name="media"; filename="${t}"\r
|
|
11
11
|
Content-Type: application/octet-stream\r
|
|
12
12
|
\r
|
|
13
|
-
`),m.push(e instanceof Buffer?e:Buffer.from(await e.arrayBuffer())),m.push(g);let
|
|
13
|
+
`),m.push(e instanceof Buffer?e:Buffer.from(await e.arrayBuffer())),m.push(g);let I=Buffer.concat(m.map(v=>typeof v=="string"?Buffer.from(v):v));l=await fetch(`${a}${s}?app_token=${o}&type=${c}`,{method:"POST",headers:{"Content-Type":`multipart/form-data; boundary=${p}`,"Content-Length":I.length.toString()},body:I})}else{let p=new FormData;p.append("media",e,t),l=await fetch(`${a}${s}?app_token=${o}&type=${c}`,{method:"POST",body:p})}if(!l.ok){let p=`HTTP ${l.status}: ${l.statusText}`;return i.error(p,{url:`${a}${s}`,status:l.status,type:c}),{ok:!1,error:p}}let d=await l.json();if(d.errCode!==0)return i.error("Media upload failed",{errCode:d.errCode,errMsg:d.errMsg,type:c}),{ok:!1,error:d.errMsg};if(!d.data?.mediaId){let p="No mediaId returned";return i.error(p),{ok:!1,error:p}}return i.info("Media file uploaded successfully",{mediaId:d.data.mediaId,fileName:t,createdTime:d.data.createdTime}),{ok:!0,mediaId:d.data.mediaId}}catch(o){return{ok:!1,error:je(o,{operation:"uploadMediaFile"})}}}async function Rr(n,e,t,r,o,a){if(!t?.trim())return i.warn("No recipient provided"),{ok:!1,error:"No recipient provided"};if(!o?.trim())return i.warn("No mediaId provided"),{ok:!1,error:"No mediaId provided"};try{i.debug("Sending media message",{to:t,mediaType:r,isGroup:a?.isGroup});let s;switch(r.toLowerCase()){case"video":s=1;break;case"image":s=2;break;case"audio":case"voice":s=3;break;case"file":s=3;break;default:s=3}if(n==="smart")if(a?.isGroup){let c={text:{content:"\u8FD9\u662F\u4E00\u4E2A\u6D4B\u8BD5\u6587\u4EF6",mediaType:s,mediaIds:[o]}};return i.debug("Sending group media message data",c),await K(e,t,"text",c)}else{let c=await C.getAppToken(e),l=W(e.apiGatewayUrl),d=x.smartBot.privateMessage;i.debug("Sending message to Lanxin API",{apiUrl:l,endpoint:d,to:t,msgType:"text",mediaType:r,apiMediaType:s});let p={userIdList:[t],msgType:"text",msgData:{text:{content:"\u8FD9\u662F\u4E00\u4E2A\u6D4B\u8BD5\u6587\u4EF6",mediaType:s,mediaIds:[o]}}};i.debug("Sending media message data",p);let f=await fetch(`${l}${d}?app_token=${c}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(p)});if(!f.ok){let m=`HTTP ${f.status}: ${f.statusText}`;return i.error(m,{url:`${l}${d}`,status:f.status}),{ok:!1,error:m}}let g=await f.json();return g.errCode!==0?(i.error("Lanxin API error",{errCode:g.errCode,errMsg:g.errMsg}),{ok:!1,error:g.errMsg}):(i.info("Media message sent successfully",{messageId:g.data?.msgId,to:t,mediaType:r}),{ok:!0,messageId:g.data?.msgId})}else if(n==="webhook"){let c=a?.hookToken||e.hookToken;if(!c)return i.warn("No hookToken provided for webhook bot"),{ok:!1,error:"No hookToken provided for webhook bot"};let l={text:{content:"\u8FD9\u662F\u4E00\u4E2A\u6D4B\u8BD5\u6587\u4EF6",mediaType:s,mediaIds:[o]}};return i.debug("Sending webhook media message data",l),await J(e,c,"text",l)}return i.warn(`Unknown bot type: ${n}`),{ok:!1,error:`Unknown bot type: ${n}`}}catch(s){return i.error("Error sending media message",{error:s,to:t,mediaType:r,mediaId:o}),{ok:!1,error:s instanceof Error?s.message:String(s)}}}async function Ye(n,e,t,r){try{let o=Ur.readFileSync(r),a=r.split("/").pop()||"image.png",s=await Nr(e,o,a,"image");return!s.ok||!s.mediaId?{ok:!1,error:s.error||"Failed to upload image"}:await Rr(n,e,t,"image",s.mediaId)}catch(o){return i.error("Error sending image message",{error:o,to:t,imagePath:r}),{ok:!1,error:o instanceof Error?o.message:String(o)}}}async function Ie(n,e,t,r){try{let o=Ur.readFileSync(r),a=r.split("/").pop()||"file.txt",s=await Nr(e,o,a,"file");return!s.ok||!s.mediaId?{ok:!1,error:s.error||"Failed to upload file"}:await Rr(n,e,t,"file",s.mediaId)}catch(o){return i.error("Error sending file message",{error:o,to:t,filePath:r}),{ok:!1,error:o instanceof Error?o.message:String(o)}}}var Or=y(()=>{u();Q();z();Z();G();Se()});function Zn(n){let e=[],t,r=new RegExp(Xn.source,"gi");for(;(t=r.exec(n))!==null;){let a=t[1]?.trim();a&&e.push({index:t.index,length:t[0].length,kind:"image",path:a})}let o=new RegExp(Qn.source,"gi");for(;(t=o.exec(n))!==null;){let a=t[1]?.trim();a&&e.push({index:t.index,length:t[0].length,kind:"file",path:a})}return e.sort((a,s)=>a.index-s.index),e}function Dr(n){let e=Zn(n);if(e.length===0)return null;let t=[],r=0;for(let a of e){let s=n.slice(r,a.index).replace(/\n{3,}/g,`
|
|
14
14
|
|
|
15
15
|
`).trim();s&&t.push({type:"text",content:s}),a.kind==="image"?t.push({type:"image",path:a.path}):t.push({type:"file",path:a.path}),r=a.index+a.length}let o=n.slice(r).replace(/\n{3,}/g,`
|
|
16
16
|
|
|
17
|
-
`).trim();return o&&t.push({type:"text",content:o}),t}var Wn,jn,Ur=w(()=>{u();Wn=/<lximg>([^<>]+)<\/(?:lximg|img)>/gi,jn=/<lxfile>([^<>]+)<\/(?:lxfile|file)>/gi});import Nr from"fs/promises";import Ye from"path";function Lr(n){let e=Ye.extname(n).toLowerCase();return Hn[e]||"application/octet-stream"}async function zn(n,e,t,r){try{i.debug("Uploading media file",{fileName:t,fileType:r});let o="image";r.startsWith("video/")?o="video":r.startsWith("audio/")?o="audio":r.startsWith("image/")?Ye.extname(t).toLowerCase()===".svg"&&(o="file"):o="file",i.debug(`Determined media type: ${o}`);let a=await E.media.uploadMedia(n,e,o,t);if(!a){let s="No mediaId returned";return i.error(s),{ok:!1,error:s}}return i.info("Media file uploaded successfully",{mediaId:a,fileName:t,mediaType:o}),{ok:!0,mediaId:a}}catch(o){let a=je(o,{operation:"uploadMediaFile"});return i.error(`Upload failed: ${a}`,{fileName:t,fileType:r}),{ok:!1,error:a}}}async function Jn(n,e,t,r,o,a){if(!t?.trim())return{ok:!1,error:"No recipient provided"};if(!o?.trim())return{ok:!1,error:"No mediaId provided"};let s;switch(r.toLowerCase()){case"video":s=1;break;case"image":s=2;break;case"audio":case"voice":s=3;break;case"file":s=3;break;default:s=3}if(n==="smart"){if(a?.isGroup)return await Dr(e,t,"text",{text:{content:"",mediaType:s,mediaIds:[o]}});{let c=await M.getAppToken(e),l=F(e.apiGatewayUrl),d=x.smartBot.privateMessage,p=await fetch(`${l}${d}?app_token=${c}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userIdList:[t],msgType:"text",msgData:{text:{content:"",mediaType:s,mediaIds:[o]}}})});if(!p.ok)return{ok:!1,error:`HTTP ${p.status}: ${p.statusText}`};let f=await p.json();return f.errCode!==0?{ok:!1,error:f.errMsg}:{ok:!0,messageId:f.data?.msgId}}}else if(n==="webhook"){let c=a?.hookToken||e.hookToken;return c?await Or(e,c,"text",{text:{content:"",mediaType:s,mediaIds:[o]}}):{ok:!1,error:"No hookToken provided for webhook bot"}}return{ok:!1,error:`Unknown bot type: ${n}`}}async function Kn(n,e,t,r){if(!e?.trim())return{ok:!1,error:"No userId provided"};try{let o=e.trim();if(!o)return{ok:!1,error:"Invalid userId"};let a=r?.msgType!=="text",s=r?.formatType||1;return await E.message.sendPrivateMessage(n,o,a?"formatText":"text",a?{formatText:{formatType:s,text:t}}:{text:{content:t}})}catch(o){return{ok:!1,error:o instanceof Error?o.message:String(o)}}}async function Dr(n,e,t,r,o){if(!e?.trim())return{ok:!1,error:"No groupId provided"};try{return await E.message.sendGroupMessage(n,e,t,r)}catch(a){return{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function Vn(n,e,t,r){let o=r?.msgType!=="text";return await Dr(n,e,o?"formatText":"text",o?{formatText:{formatType:r?.formatType||1,text:t}}:{text:{content:t}},r)}async function Or(n,e,t,r){if(!e?.trim())return{ok:!1,error:"No hookToken provided"};try{let o=await M.getAppToken(n),a=qe(n.apiGatewayUrl),s=x.webhookBot.message,c=new URLSearchParams;o&&c.append("app_token",o),c.append("hook_token",e);let l=await fetch(`${a}${s}?${c.toString()}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({msgType:t,msgData:r})});if(!l.ok)return{ok:!1,error:`HTTP ${l.status}: ${l.statusText}`};let d=await l.json();return d.errCode!==0?{ok:!1,error:d.errMsg}:{ok:!0,messageId:d.data?.msgId}}catch(o){return{ok:!1,error:o instanceof Error?o.message:String(o)}}}async function re(n,e,t,r,o){if(!t?.trim())return{ok:!1,error:"No recipient provided"};if(n==="smart")return o?.isGroup?await Vn(e,t,r,{...o}):await Kn(e,t,r,{msgType:o?.msgType,formatType:o?.formatType});if(n==="webhook"){let a=o?.hookToken||e.hookToken;if(!a)return{ok:!1,error:"No hookToken provided for webhook bot"};let s=o?.msgType!=="text";return await Or(e,a,s?"formatText":"text",s?{formatText:{formatType:o?.formatType||1,text:r}}:{text:{content:r}})}return{ok:!1,error:`Unknown bot type: ${n}`}}async function Xn(n,e="unknown"){try{if(n.startsWith("http://")||n.startsWith("https://")){let{path:t}=await Ee(n,e),r=await Nr.readFile(t),o=Lr(t),a=t.split("/").pop()||"downloaded-file";return{buffer:r,contentType:o,fileName:a}}else{let t=Ye.resolve(n),r=await Nr.readFile(t),o=Lr(t),a=Ye.basename(t);return{buffer:r,contentType:o,fileName:a}}}catch(t){throw new Error(`Failed to load file: ${t instanceof Error?t.message:String(t)}`)}}async function Ue(n,e,t,r,o){if(!t?.trim())return{ok:!1,error:"No recipient provided"};if(!r?.trim())return{ok:!1,error:"No message text provided"};let a=Pr(r);if(!a)return await re(n,e,t,r,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1});try{for(let s of a)if(s.type==="text"){let c=await re(n,e,t,s.content,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1});if(!c.ok)return i.error(`Failed to send text message: ${c.error}`),c}else if(s.type==="image"||s.type==="file"){if(i.info(`Processing ${s.type} tag with path: ${s.path}`),!s.path||!s.path.trim()){let c=`Invalid ${s.type} path: empty or whitespace`;return i.error(c),await re(n,e,t,`\u274C \u9519\u8BEF\uFF1A${c}`,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1}),{ok:!1,error:c}}try{i.debug(`Downloading or reading file: ${s.path}`);let{buffer:c,contentType:l,fileName:d}=await Xn(s.path,o?.userId||"unknown");i.info(`File loaded successfully: ${d}, size: ${c.length} bytes, type: ${l}`);let p=s.type==="image"?"image":"file";l.startsWith("image/")&&!d.toLowerCase().endsWith(".svg")?p="image":l.startsWith("video/")?p="video":l.startsWith("audio/")&&(p="voice"),i.info(`Determined actual media type: ${p}`);let f=2*1024*1024;if(c.length>f){let T=`\u6587\u4EF6\u5927\u5C0F\u8D85\u8FC7\u9650\u5236\uFF1A${(c.length/1048576).toFixed(2)}MB\uFF0C\u6700\u5927\u652F\u6301 2MB`;return i.error(T),await re(n,e,t,`\u274C \u9519\u8BEF\uFF1A${T}`,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1}),{ok:!1,error:T}}i.debug(`Uploading media file: ${d}, type: ${l}`);let g=await zn(e,c,d,l);if(!g.ok)return i.error(`Failed to upload ${p} file: ${g.error}`),await re(n,e,t,`\u274C \u9519\u8BEF\uFF1A\u4E0A\u4F20\u6587\u4EF6\u5931\u8D25 - ${g.error}`,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1}),{ok:!1,error:g.error};i.info(`Media file uploaded successfully: ${g.mediaId}`),i.debug(`Sending ${p} message with mediaId: ${g.mediaId}`);let m=await Jn(n,e,t,p,g.mediaId,o);if(!m.ok)return i.error(`Failed to send ${p} message: ${m.error}`),await re(n,e,t,`\u274C \u9519\u8BEF\uFF1A\u53D1\u9001\u6D88\u606F\u5931\u8D25 - ${m.error}`,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1}),m;i.info(`${p} message sent successfully`)}catch(c){let l=`Error processing ${s.type} tag: ${c instanceof Error?c.message:String(c)}`;return i.error(l),await re(n,e,t,`\u274C \u9519\u8BEF\uFF1A${l}`,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1}),{ok:!1,error:l}}}return i.info("All media tags processed successfully"),{ok:!0,messageId:""}}catch(s){let c=`Error processing media tags: ${s instanceof Error?s.message:String(s)}`;return i.error(c),await re(n,e,t,`\u274C \u9519\u8BEF\uFF1A${c}`,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1}),{ok:!1,error:c}}}var Hn,Rr=w(()=>{u();Q();z();Z();W();Ke();Ur();He();Hn={".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".txt":"text/plain",".html":"text/html",".css":"text/css",".js":"text/javascript",".json":"application/json",".mp3":"audio/mpeg",".mp4":"video/mp4",".zip":"application/zip",".rar":"application/x-rar-compressed",".7z":"application/x-7z-compressed"}});var Br=w(()=>{u();vr();xt();be();Er();Rr()});var Ne,_r=w(()=>{u();G();Ne=class{account=null;initialize(e){this.account=e}shutdown(){this.account=null}async createEvent(e){if(!this.account)return{ok:!1,error:"Calendar skill not initialized"};try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/calendar/events/create?app_token=${this.account.appId}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok)return{ok:!1,error:`HTTP ${r.status}: ${r.statusText}`};let o=await r.json();return o.errCode!==0?{ok:!1,error:o.errMsg}:{ok:!0,eventId:o.data?.eventId}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}async getEvent(e){if(!this.account)throw new Error("Calendar skill not initialized");try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/calendar/events/${e}?app_token=${this.account.appId}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!r.ok)throw new Error(`HTTP ${r.status}: ${r.statusText}`);let o=await r.json();if(o.errCode!==0)throw new Error(o.errMsg);if(!o.data)throw new Error("No event data returned");return o.data}catch(t){throw t}}async updateEvent(e,t){if(!this.account)return{ok:!1,error:"Calendar skill not initialized"};try{let r=N(this.account.config.apiGatewayUrl),o=await fetch(`${r}/v1/calendar/events/${e}?app_token=${this.account.appId}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!o.ok)return{ok:!1,error:`HTTP ${o.status}: ${o.statusText}`};let a=await o.json();return a.errCode!==0?{ok:!1,error:a.errMsg}:{ok:!0,eventId:e}}catch(r){return{ok:!1,error:r instanceof Error?r.message:String(r)}}}async deleteEvent(e){if(!this.account)return{ok:!1,error:"Calendar skill not initialized"};try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/calendar/events/${e}?app_token=${this.account.appId}`,{method:"DELETE",headers:{"Content-Type":"application/json"}});if(!r.ok)return{ok:!1,error:`HTTP ${r.status}: ${r.statusText}`};let o=await r.json();return o.errCode!==0?{ok:!1,error:o.errMsg}:{ok:!0}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}async listEvents(e){if(!this.account)throw new Error("Calendar skill not initialized");try{let t=N(this.account.config.apiGatewayUrl),r=new URLSearchParams;r.append("app_token",this.account.appId),e?.startTime&&r.append("start_time",e.startTime),e?.endTime&&r.append("end_time",e.endTime),e?.maxResults&&r.append("max_results",e.maxResults.toString()),e?.pageToken&&r.append("page_token",e.pageToken);let o=await fetch(`${t}/v1/calendar/events/list?${r.toString()}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);let a=await o.json();if(a.errCode!==0)throw new Error(a.errMsg);return a.data?.events||[]}catch(t){throw t}}}});var Le,Fr=w(()=>{u();G();Le=class{account=null;initialize(e){this.account=e}shutdown(){this.account=null}async sendTextMessage(e,t,r){if(!this.account)return{ok:!1,error:"Message skill not initialized"};let o=this.account.config.botType??"smart",a=r?.isGroup??e.startsWith("oc_");return await H(o,this.account.config,e,t,{hookToken:this.account.config.hookToken,isGroup:a})}async sendSmartBotPrivateMessage(e,t){return this.account?await Ve(this.account.config,e,t):{ok:!1,error:"Message skill not initialized"}}async sendSmartBotGroupMessage(e,t){return this.account?await ir(this.account.config,e,t):{ok:!1,error:"Message skill not initialized"}}async sendWebhookBotMessage(e,t){if(!this.account)return{ok:!1,error:"Message skill not initialized"};let r=this.account.config.hookToken;return r?await J(this.account.config,r,e,t):{ok:!1,error:"No hookToken provided for webhook bot"}}}});var De,Gr=w(()=>{u();G();De=class{account=null;initialize(e){this.account=e}shutdown(){this.account=null}async createMeeting(e){if(!this.account)return{ok:!1,error:"Meeting skill not initialized"};try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/meetings/create?app_token=${this.account.appId}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok)return{ok:!1,error:`HTTP ${r.status}: ${r.statusText}`};let o=await r.json();return o.errCode!==0?{ok:!1,error:o.errMsg}:{ok:!0,meetingId:o.data?.meetingId,joinUrl:o.data?.joinUrl}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}async getMeeting(e){if(!this.account)throw new Error("Meeting skill not initialized");try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/meetings/${e}?app_token=${this.account.appId}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!r.ok)throw new Error(`HTTP ${r.status}: ${r.statusText}`);let o=await r.json();if(o.errCode!==0)throw new Error(o.errMsg);if(!o.data)throw new Error("No meeting data returned");return o.data}catch(t){throw t}}async updateMeeting(e,t){if(!this.account)return{ok:!1,error:"Meeting skill not initialized"};try{let r=N(this.account.config.apiGatewayUrl),o=await fetch(`${r}/v1/meetings/${e}?app_token=${this.account.appId}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!o.ok)return{ok:!1,error:`HTTP ${o.status}: ${o.statusText}`};let a=await o.json();return a.errCode!==0?{ok:!1,error:a.errMsg}:{ok:!0,meetingId:e}}catch(r){return{ok:!1,error:r instanceof Error?r.message:String(r)}}}async deleteMeeting(e){if(!this.account)return{ok:!1,error:"Meeting skill not initialized"};try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/meetings/${e}?app_token=${this.account.appId}`,{method:"DELETE",headers:{"Content-Type":"application/json"}});if(!r.ok)return{ok:!1,error:`HTTP ${r.status}: ${r.statusText}`};let o=await r.json();return o.errCode!==0?{ok:!1,error:o.errMsg}:{ok:!0}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}async listMeetings(e){if(!this.account)throw new Error("Meeting skill not initialized");try{let t=N(this.account.config.apiGatewayUrl),r=new URLSearchParams;r.append("app_token",this.account.appId),e?.startTime&&r.append("start_time",e.startTime),e?.endTime&&r.append("end_time",e.endTime),e?.maxResults&&r.append("max_results",e.maxResults.toString()),e?.pageToken&&r.append("page_token",e.pageToken),e?.status&&r.append("status",e.status);let o=await fetch(`${t}/v1/meetings/list?${r.toString()}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);let a=await o.json();if(a.errCode!==0)throw new Error(a.errMsg);return a.data?.meetings||[]}catch(t){throw t}}async startMeeting(e){if(!this.account)return{ok:!1,error:"Meeting skill not initialized"};try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/meetings/${e}/start?app_token=${this.account.appId}`,{method:"POST",headers:{"Content-Type":"application/json"}});if(!r.ok)return{ok:!1,error:`HTTP ${r.status}: ${r.statusText}`};let o=await r.json();return o.errCode!==0?{ok:!1,error:o.errMsg}:{ok:!0,meetingId:e,joinUrl:o.data?.joinUrl}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}async endMeeting(e){if(!this.account)return{ok:!1,error:"Meeting skill not initialized"};try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/meetings/${e}/end?app_token=${this.account.appId}`,{method:"POST",headers:{"Content-Type":"application/json"}});if(!r.ok)return{ok:!1,error:`HTTP ${r.status}: ${r.statusText}`};let o=await r.json();return o.errCode!==0?{ok:!1,error:o.errMsg}:{ok:!0,meetingId:e}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}}});var Qe,Wr=w(()=>{u();_r();Fr();Gr();Qe=class{skills=new Map;registerSkill(e,t){this.skills.set(e,t)}getSkill(e){return this.skills.get(e)}initializeSkills(e){for(let t of this.skills.values())t.initialize&&t.initialize(e)}shutdownSkills(){for(let e of this.skills.values())e.shutdown&&e.shutdown()}}});import*as jr from"crypto";function Yn(n,e,t){try{let r=Buffer.from(n,"base64");if(r.length<16)return t?.error("Decoded data is too short"),"";let o=Buffer.from(e+"=","base64"),a=jr.createDecipheriv("aes-256-cbc",o,o.subarray(0,16));return Buffer.concat([a.update(r),a.final()]).toString("utf8")}catch(r){return r instanceof Error&&(r.message.includes("Invalid key length")||r.message.includes("Unsupported state"))?(t?.error(`Decryption error: ${r.message}`),""):(t?.error(`Decryption error: ${r}`),"")}}function yr(n,e,t){let r,o=n?.dataEncrypt;if(o&&(o=Yn(o,e,t),t?.info(`webhook: Decrypted message: ${o}`)),o)try{r=JSON.parse(o)}catch(a){return t?.error(`Failed to parse decrypted message: ${a}`),[]}else r=n;return!r?.events||r.events.length===0?(t?.error("No valid events found"),[]):r.events}var qr=w(()=>{u()});async function he(n,e,t,r){if(!e?.trim())return{ok:!1,error:"No recipient provided"};let o=L(n),a={hookToken:n.hookToken,isGroup:r};try{if(typeof t=="string")return t?.trim()?await Ue(o,n,e,t,{...a,msgType:"formatText",formatType:1}):{ok:!1,error:"No message text provided"};let s=t;if(s.text||s.body){let c=s.text||s.body;return c?.trim()?await Ue(o,n,e,c,{...a,msgType:"formatText",formatType:1}):{ok:!1,error:"No message text provided"}}if(s.mediaUrl||s.mediaUrls){let c=s.mediaUrl||s.mediaUrls?.[0];if(!c)return{ok:!1,error:"No media URL provided"};let l=`Media: ${c}`;return await H(o,n,e,l,a)}if(s.images){let c=s.images||[s.images];if(!c||c.length===0)return{ok:!1,error:"No images provided"};let l=c[0];return await Xe(o,n,e,l)}if(s.files){let c=s.files||[s.files];if(!c||c.length===0)return{ok:!1,error:"No files provided"};let l=c[0];return await Te(o,n,e,l)}if(s.voice){let c=s.voice;return c?await Te(o,n,e,c):{ok:!1,error:"No voice provided"}}if(s.video){let c=s.video;return c?await Te(o,n,e,c):{ok:!1,error:"No video provided"}}if(s.linkCard)return await Se(o,n,e,s.linkCard,a);if(s.appCard)return await se(o,n,e,s.appCard,a);if(s.oaCard||s.oacard){let c=s.oaCard||s.oacard;return await ve(o,n,e,c,a)}if(s.appArticles)return await Ae(o,n,e,s.appArticles,a);if(s.systemMessage)return await Me(o,n,e,s.systemMessage,a);if(s.toString){let c=s.toString();if(c)return await Ue(o,n,e,c,{...a,msgType:"formatText",formatType:1})}return{ok:!1,error:"No valid message content found"}}catch(s){return i.error("Error processing message",{error:s,payload:t}),{ok:!1,error:s instanceof Error?s.message:String(s)}}}var Hr=w(()=>{u();G()});var Ot,wr,zr=w(()=>{u();W();Ot=class{convertLanxinEventToOpenClawMessage(e,t){try{let r=e.eventType||e.type;switch(!r&&e.data&&(r=e.data.eventType||e.data.type),r){case"account_message":case"bot_private_message":return this.convertPrivateMessage(e,t);case"bot_group_message":return this.convertGroupMessage(e,t);case"staff_info":return null;default:return i.debug(`Unhandled event type: ${r}`),null}}catch(r){return i.error("Error converting Lanxin event to OpenClaw message",{error:r,event:e}),null}}convertPrivateMessage(e,t){i.debug("Converting private message event to OpenClaw message",{event:e});let r=e.data?.data||e.data,o=r.msgType||"formatText",a=r.from,s="",c=[];switch(o){case"text":s=r.msgData?.text?.content||"";break;case"image":s="[\u56FE\u7247]",c=(r.msgData?.image?.mediaIds||[]).map(l=>({type:"image",id:l}));break;case"video":s="[\u89C6\u9891]",c=(r.msgData?.video?.mediaIds||[]).map(l=>({type:"video",id:l}));break;case"file":s="[\u6587\u4EF6]",c=(r.msgData?.file?.mediaIds||[]).map(l=>({type:"file",id:l}));break;case"voice":s="[\u8BED\u97F3]",c=(r.msgData?.voice?.mediaIds||[]).map(l=>({type:"voice",id:l}));break;case"position":s=`[\u4F4D\u7F6E] ${r.msgData?.position?.name||"\u672A\u77E5\u4F4D\u7F6E"}`;break;case"card":s="[\u540D\u7247]";break;case"sticker":s="[\u8868\u60C5]";break;default:s=`[${o}]`;break}return{chatId:`lanxin_chat_${a}`,senderId:a,text:s,messageId:e.id||r.id,chatType:"p2p",messageType:o,attachments:c.length>0?c:void 0,timestamp:this.extractTimestamp(r)}}convertGroupMessage(e,t){let r=e.data?.data||e.data,o=r.msgType||"formatText",a=r.from,s=r.groupId,c="",l=[];switch(o){case"text":c=r.msgData?.text?.content||"";break;case"image":c="[\u56FE\u7247]",l=(r.msgData?.image?.mediaIds||[]).map(d=>({type:"image",id:d}));break;case"video":c="[\u89C6\u9891]",l=(r.msgData?.video?.mediaIds||[]).map(d=>({type:"video",id:d}));break;case"file":c="[\u6587\u4EF6]",l=(r.msgData?.file?.mediaIds||[]).map(d=>({type:"file",id:d}));break;case"voice":c="[\u8BED\u97F3]",l=(r.msgData?.voice?.mediaIds||[]).map(d=>({type:"voice",id:d}));break;case"position":c=`[\u4F4D\u7F6E] ${r.msgData?.position?.name||"\u672A\u77E5\u4F4D\u7F6E"}`;break;case"card":c="[\u540D\u7247]";break;case"sticker":c="[\u8868\u60C5]";break;default:c=`[${o}]`;break}return{chatId:s,senderId:a,text:c,messageId:e.id||r.id,chatType:"group",messageType:o,attachments:l.length>0?l:void 0,timestamp:this.extractTimestamp(r)}}extractTimestamp(e){if(e.msgData){let t=e.msgData;if(t.text?.sendTime)return t.text.sendTime;if(t.image?.sendTime)return t.image.sendTime;if(t.video?.sendTime)return t.video.sendTime;if(t.file?.sendTime)return t.file.sendTime;if(t.voice?.sendTime)return t.voice.sendTime;if(t.position?.sendTime)return t.position.sendTime;if(t.card?.sendTime)return t.card.sendTime;if(t.sticker?.sendTime)return t.sticker.sendTime}}convertOpenClawMessageToLanxinMessage(e){try{let{text:t,messageType:r,attachments:o}=e,a={};switch(r){case"text":a={text:{content:t}};break;case"image":a={image:{mediaIds:o?.filter(s=>s.type==="image").map(s=>s.id).filter(Boolean)||[]}};break;case"video":a={video:{mediaIds:o?.filter(s=>s.type==="video").map(s=>s.id).filter(Boolean)||[]}};break;case"file":a={file:{mediaIds:o?.filter(s=>s.type==="file").map(s=>s.id).filter(Boolean)||[]}};break;case"voice":a={voice:{mediaIds:o?.filter(s=>s.type==="voice").map(s=>s.id).filter(Boolean)||[]}};break;default:a={text:{content:t}};break}return{msgType:r,msgData:a}}catch(t){return i.error("Error converting OpenClaw message to Lanxin message",{error:t,message:e}),{msgType:"text",msgData:{text:{content:e.text}}}}}},wr=new Ot});var Rt,Ir,Jr=w(()=>{u();W();Rt=class{handlers=new Map;registerHandler(e,t){this.handlers.has(e)||this.handlers.set(e,[]),this.handlers.get(e)?.push(t)}async classifyAndProcess(e,t){try{let r=e.eventType||e.type;!r&&e.data&&(r=e.data.eventType||e.data.type),i.info(`Classifying event type: ${r}`);let o=this.handlers.get(r);return o&&o.length>0?await Promise.all(o.map(s=>s.handle(e,t))):(i.debug(`No handlers registered for event type: ${r}`),null)}catch(r){return i.error("Error classifying and processing event",{error:r,event:e}),null}}getRegisteredEventTypes(){return Array.from(this.handlers.keys())}getHandlers(e){return this.handlers.get(e)||[]}},Ir=new Rt});var Kr=w(()=>{u();qr();Hr();zr();Jr()});import*as Y from"fs";var Ze,Qn,Vr=w(()=>{u();Ze=class{static create(){return async(e,t)=>{let{openclawMessage:r,userId:o}=e;if(r){if(r.type==="text")e.lanxinMessage={type:"text",content:r.content,to:o,timestamp:r.timestamp};else if(r.type==="image"){let a=r.content;if(Y.existsSync(a)){let s=Y.readFileSync(a,"base64");e.lanxinMessage={type:"image",content:s,filename:r.filename||"image.jpg",to:o,timestamp:r.timestamp}}}else if(r.type==="file"){let a=r.content;if(Y.existsSync(a)){let s=Y.readFileSync(a,"base64");e.lanxinMessage={type:"file",content:s,filename:r.filename||"file.txt",to:o,timestamp:r.timestamp}}}else if(r.type==="audio"){let a=r.content;if(Y.existsSync(a)){let s=Y.readFileSync(a,"base64");e.lanxinMessage={type:"audio",content:s,filename:r.filename||"audio.mp3",duration:r.duration||0,to:o,timestamp:r.timestamp}}}else if(r.type==="video"){let a=r.content;if(Y.existsSync(a)){let s=Y.readFileSync(a,"base64");e.lanxinMessage={type:"video",content:s,filename:r.filename||"video.mp4",duration:r.duration||0,to:o,timestamp:r.timestamp}}}}await t()}}},Qn=Ze.create()});import*as ne from"fs";import*as le from"path";import*as Xr from"https";import{fileURLToPath as Zn}from"url";var eo,to,et,ro,Yr=w(()=>{u();eo=Zn(import.meta.url),to=le.dirname(eo),et=class{static processedMessages=new Set;static create(){return async(e,t)=>{let{message:r,userId:o}=e;if(r.eventType==="message"){let a=r.messageId;if(this.processedMessages.has(a))return;if(this.processedMessages.add(a),r.messageType==="text")e.openclawMessage={type:"text",content:r.content,from:o,timestamp:r.timestamp};else if(r.messageType==="image"){let s=await this.downloadMedia(r.content,"images");e.openclawMessage={type:"image",content:s,filename:r.filename||"image.jpg",from:o,timestamp:r.timestamp}}else if(r.messageType==="file"){let s=await this.downloadMedia(r.content,"files");e.openclawMessage={type:"file",content:s,filename:r.filename||"file.txt",from:o,timestamp:r.timestamp}}else if(r.messageType==="audio"){let s=await this.downloadMedia(r.content,"audio");e.openclawMessage={type:"audio",content:s,filename:r.filename||"audio.mp3",duration:r.duration||0,from:o,timestamp:r.timestamp}}else if(r.messageType==="video"){let s=await this.downloadMedia(r.content,"video");e.openclawMessage={type:"video",content:s,filename:r.filename||"video.mp4",duration:r.duration||0,from:o,timestamp:r.timestamp}}}await t()}}static async downloadMedia(e,t){let r=le.join(to,"../../../media",t);ne.existsSync(r)||ne.mkdirSync(r,{recursive:!0});let o=le.basename(e)||`${Date.now()}.bin`,a=le.join(r,o);return new Promise((s,c)=>{let l=ne.createWriteStream(a);Xr.get(e,d=>{d.pipe(l),l.on("finish",()=>{l.close(),s(a)})}).on("error",d=>{ne.unlink(a,()=>{}),c(d)})})}},ro=et.create()});var tt,vt,Qr=w(()=>{u();tt=class{static create(){return async(e,t)=>{await t()}}},vt=tt.create()});import rt from"node:fs";import _t from"node:path";import{fileURLToPath as no}from"node:url";var oo,Ft,ao,Bt,nt,At,Zr=w(()=>{u();G();oo=no(import.meta.url),Ft=_t.dirname(oo),ao=Ft.includes("dist"),Bt=n=>ao?_t.join(Ft,n):_t.join(Ft,"../../../",n),nt=class{static commands={help:async e=>{e.response={type:"text",content:`\u84DD\u4FE1 OpenClaw \u63D2\u4EF6\u652F\u6301\u4EE5\u4E0B\u547D\u4EE4\uFF1A
|
|
17
|
+
`).trim();return o&&t.push({type:"text",content:o}),t}var Xn,Qn,_r=y(()=>{u();Xn=/<lximg>([^<>]+)<\/(?:lximg|img)>/gi,Qn=/<lxfile>([^<>]+)<\/(?:lxfile|file)>/gi});import Br from"fs/promises";import Xe from"path";function Fr(n){let e=Xe.extname(n).toLowerCase();return eo[e]||"application/octet-stream"}async function to(n,e,t,r){try{i.debug("Uploading media file",{fileName:t,fileType:r});let o="image";r.startsWith("video/")?o="video":r.startsWith("audio/")?o="audio":r.startsWith("image/")?Xe.extname(t).toLowerCase()===".svg"&&(o="file"):o="file",i.debug(`Determined media type: ${o}`);let a=await E.media.uploadMedia(n,e,o,t);if(!a){let s="No mediaId returned";return i.error(s),{ok:!1,error:s}}return i.info("Media file uploaded successfully",{mediaId:a,fileName:t,mediaType:o}),{ok:!0,mediaId:a}}catch(o){let a=je(o,{operation:"uploadMediaFile"});return i.error(`Upload failed: ${a}`,{fileName:t,fileType:r}),{ok:!1,error:a}}}async function ro(n,e,t,r,o,a){if(!t?.trim())return{ok:!1,error:"No recipient provided"};if(!o?.trim())return{ok:!1,error:"No mediaId provided"};let s;switch(r.toLowerCase()){case"video":s=1;break;case"image":s=2;break;case"audio":case"voice":s=3;break;case"file":s=3;break;default:s=3}if(n==="smart"){if(a?.isGroup)return await Gr(e,t,"text",{text:{content:"",mediaType:s,mediaIds:[o]}});{let c=await C.getAppToken(e),l=W(e.apiGatewayUrl),d=x.smartBot.privateMessage,p=await fetch(`${l}${d}?app_token=${c}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userIdList:[t],msgType:"text",msgData:{text:{content:"",mediaType:s,mediaIds:[o]}}})});if(!p.ok)return{ok:!1,error:`HTTP ${p.status}: ${p.statusText}`};let f=await p.json();return f.errCode!==0?{ok:!1,error:f.errMsg}:{ok:!0,messageId:f.data?.msgId}}}else if(n==="webhook"){let c=a?.hookToken||e.hookToken;return c?await Wr(e,c,"text",{text:{content:"",mediaType:s,mediaIds:[o]}}):{ok:!1,error:"No hookToken provided for webhook bot"}}return{ok:!1,error:`Unknown bot type: ${n}`}}async function no(n,e,t,r){if(!e?.trim())return{ok:!1,error:"No userId provided"};try{let o=e.trim();if(!o)return{ok:!1,error:"Invalid userId"};let a=r?.msgType!=="text",s=r?.formatType||1;return await E.message.sendPrivateMessage(n,o,a?"formatText":"text",a?{formatText:{formatType:s,text:t}}:{text:{content:t}})}catch(o){return{ok:!1,error:o instanceof Error?o.message:String(o)}}}async function Gr(n,e,t,r,o){if(!e?.trim())return{ok:!1,error:"No groupId provided"};try{return await E.message.sendGroupMessage(n,e,t,r)}catch(a){return{ok:!1,error:a instanceof Error?a.message:String(a)}}}async function oo(n,e,t,r){let o=r?.msgType!=="text";return await Gr(n,e,o?"formatText":"text",o?{formatText:{formatType:r?.formatType||1,text:t}}:{text:{content:t}},r)}async function Wr(n,e,t,r){if(!e?.trim())return{ok:!1,error:"No hookToken provided"};try{let o=await C.getAppToken(n),a=qe(n.apiGatewayUrl),s=x.webhookBot.message,c=new URLSearchParams;o&&c.append("app_token",o),c.append("hook_token",e);let l=await fetch(`${a}${s}?${c.toString()}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({msgType:t,msgData:r})});if(!l.ok)return{ok:!1,error:`HTTP ${l.status}: ${l.statusText}`};let d=await l.json();return d.errCode!==0?{ok:!1,error:d.errMsg}:{ok:!0,messageId:d.data?.msgId}}catch(o){return{ok:!1,error:o instanceof Error?o.message:String(o)}}}async function ne(n,e,t,r,o){if(!t?.trim())return{ok:!1,error:"No recipient provided"};if(n==="smart")return o?.isGroup?await oo(e,t,r,{...o}):await no(e,t,r,{msgType:o?.msgType,formatType:o?.formatType});if(n==="webhook"){let a=o?.hookToken||e.hookToken;if(!a)return{ok:!1,error:"No hookToken provided for webhook bot"};let s=o?.msgType!=="text";return await Wr(e,a,s?"formatText":"text",s?{formatText:{formatType:o?.formatType||1,text:r}}:{text:{content:r}})}return{ok:!1,error:`Unknown bot type: ${n}`}}async function ao(n,e="unknown"){try{if(n.startsWith("http://")||n.startsWith("https://")){let{path:t}=await Pe(n,e),r=await Br.readFile(t),o=Fr(t),a=t.split("/").pop()||"downloaded-file";return{buffer:r,contentType:o,fileName:a}}else{let t=Xe.resolve(n),r=await Br.readFile(t),o=Fr(t),a=Xe.basename(t);return{buffer:r,contentType:o,fileName:a}}}catch(t){throw new Error(`Failed to load file: ${t instanceof Error?t.message:String(t)}`)}}async function Ue(n,e,t,r,o){if(!t?.trim())return{ok:!1,error:"No recipient provided"};if(!r?.trim())return{ok:!1,error:"No message text provided"};let a=Dr(r);if(!a)return await ne(n,e,t,r,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1});try{for(let s of a)if(s.type==="text"){let c=await ne(n,e,t,s.content,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1});if(!c.ok)return i.error(`Failed to send text message: ${c.error}`),c}else if(s.type==="image"||s.type==="file"){if(i.info(`Processing ${s.type} tag with path: ${s.path}`),!s.path||!s.path.trim()){let c=`Invalid ${s.type} path: empty or whitespace`;return i.error(c),await ne(n,e,t,`\u274C \u9519\u8BEF\uFF1A${c}`,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1}),{ok:!1,error:c}}try{i.debug(`Downloading or reading file: ${s.path}`);let{buffer:c,contentType:l,fileName:d}=await ao(s.path,o?.userId||"unknown");i.info(`File loaded successfully: ${d}, size: ${c.length} bytes, type: ${l}`);let p=s.type==="image"?"image":"file";l.startsWith("image/")&&!d.toLowerCase().endsWith(".svg")?p="image":l.startsWith("video/")?p="video":l.startsWith("audio/")&&(p="voice"),i.info(`Determined actual media type: ${p}`);let f=2*1024*1024;if(c.length>f){let I=`\u6587\u4EF6\u5927\u5C0F\u8D85\u8FC7\u9650\u5236\uFF1A${(c.length/1048576).toFixed(2)}MB\uFF0C\u6700\u5927\u652F\u6301 2MB`;return i.error(I),await ne(n,e,t,`\u274C \u9519\u8BEF\uFF1A${I}`,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1}),{ok:!1,error:I}}i.debug(`Uploading media file: ${d}, type: ${l}`);let g=await to(e,c,d,l);if(!g.ok)return i.error(`Failed to upload ${p} file: ${g.error}`),await ne(n,e,t,`\u274C \u9519\u8BEF\uFF1A\u4E0A\u4F20\u6587\u4EF6\u5931\u8D25 - ${g.error}`,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1}),{ok:!1,error:g.error};i.info(`Media file uploaded successfully: ${g.mediaId}`),i.debug(`Sending ${p} message with mediaId: ${g.mediaId}`);let m=await ro(n,e,t,p,g.mediaId,o);if(!m.ok)return i.error(`Failed to send ${p} message: ${m.error}`),await ne(n,e,t,`\u274C \u9519\u8BEF\uFF1A\u53D1\u9001\u6D88\u606F\u5931\u8D25 - ${m.error}`,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1}),m;i.info(`${p} message sent successfully`)}catch(c){let l=`Error processing ${s.type} tag: ${c instanceof Error?c.message:String(c)}`;return i.error(l),await ne(n,e,t,`\u274C \u9519\u8BEF\uFF1A${l}`,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1}),{ok:!1,error:l}}}return i.info("All media tags processed successfully"),{ok:!0,messageId:""}}catch(s){let c=`Error processing media tags: ${s instanceof Error?s.message:String(s)}`;return i.error(c),await ne(n,e,t,`\u274C \u9519\u8BEF\uFF1A${c}`,{...o,msgType:o?.msgType||"formatText",formatType:o?.formatType||1}),{ok:!1,error:c}}}var eo,jr=y(()=>{u();Q();z();Z();G();Ke();_r();He();eo={".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png",".gif":"image/gif",".webp":"image/webp",".svg":"image/svg+xml",".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".txt":"text/plain",".html":"text/html",".css":"text/css",".js":"text/javascript",".json":"application/json",".mp3":"audio/mpeg",".mp4":"video/mp4",".zip":"application/zip",".rar":"application/x-rar-compressed",".7z":"application/x-7z-compressed"}});var qr=y(()=>{u();Lr();bt();Se();Or();jr()});var Ne,Hr=y(()=>{u();L();Ne=class{account=null;initialize(e){this.account=e}shutdown(){this.account=null}async createEvent(e){if(!this.account)return{ok:!1,error:"Calendar skill not initialized"};try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/calendar/events/create?app_token=${this.account.appId}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok)return{ok:!1,error:`HTTP ${r.status}: ${r.statusText}`};let o=await r.json();return o.errCode!==0?{ok:!1,error:o.errMsg}:{ok:!0,eventId:o.data?.eventId}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}async getEvent(e){if(!this.account)throw new Error("Calendar skill not initialized");try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/calendar/events/${e}?app_token=${this.account.appId}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!r.ok)throw new Error(`HTTP ${r.status}: ${r.statusText}`);let o=await r.json();if(o.errCode!==0)throw new Error(o.errMsg);if(!o.data)throw new Error("No event data returned");return o.data}catch(t){throw t}}async updateEvent(e,t){if(!this.account)return{ok:!1,error:"Calendar skill not initialized"};try{let r=N(this.account.config.apiGatewayUrl),o=await fetch(`${r}/v1/calendar/events/${e}?app_token=${this.account.appId}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!o.ok)return{ok:!1,error:`HTTP ${o.status}: ${o.statusText}`};let a=await o.json();return a.errCode!==0?{ok:!1,error:a.errMsg}:{ok:!0,eventId:e}}catch(r){return{ok:!1,error:r instanceof Error?r.message:String(r)}}}async deleteEvent(e){if(!this.account)return{ok:!1,error:"Calendar skill not initialized"};try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/calendar/events/${e}?app_token=${this.account.appId}`,{method:"DELETE",headers:{"Content-Type":"application/json"}});if(!r.ok)return{ok:!1,error:`HTTP ${r.status}: ${r.statusText}`};let o=await r.json();return o.errCode!==0?{ok:!1,error:o.errMsg}:{ok:!0}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}async listEvents(e){if(!this.account)throw new Error("Calendar skill not initialized");try{let t=N(this.account.config.apiGatewayUrl),r=new URLSearchParams;r.append("app_token",this.account.appId),e?.startTime&&r.append("start_time",e.startTime),e?.endTime&&r.append("end_time",e.endTime),e?.maxResults&&r.append("max_results",e.maxResults.toString()),e?.pageToken&&r.append("page_token",e.pageToken);let o=await fetch(`${t}/v1/calendar/events/list?${r.toString()}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);let a=await o.json();if(a.errCode!==0)throw new Error(a.errMsg);return a.data?.events||[]}catch(t){throw t}}}});var Re,zr=y(()=>{u();L();Re=class{account=null;initialize(e){this.account=e}shutdown(){this.account=null}async sendTextMessage(e,t,r){if(!this.account)return{ok:!1,error:"Message skill not initialized"};let o=this.account.config.botType??"smart",a=r?.isGroup??e.startsWith("oc_");return await H(o,this.account.config,e,t,{hookToken:this.account.config.hookToken,isGroup:a})}async sendSmartBotPrivateMessage(e,t){return this.account?await Ve(this.account.config,e,t):{ok:!1,error:"Message skill not initialized"}}async sendSmartBotGroupMessage(e,t){return this.account?await fr(this.account.config,e,t):{ok:!1,error:"Message skill not initialized"}}async sendWebhookBotMessage(e,t){if(!this.account)return{ok:!1,error:"Message skill not initialized"};let r=this.account.config.hookToken;return r?await J(this.account.config,r,e,t):{ok:!1,error:"No hookToken provided for webhook bot"}}}});var Oe,Jr=y(()=>{u();L();Oe=class{account=null;initialize(e){this.account=e}shutdown(){this.account=null}async createMeeting(e){if(!this.account)return{ok:!1,error:"Meeting skill not initialized"};try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/meetings/create?app_token=${this.account.appId}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!r.ok)return{ok:!1,error:`HTTP ${r.status}: ${r.statusText}`};let o=await r.json();return o.errCode!==0?{ok:!1,error:o.errMsg}:{ok:!0,meetingId:o.data?.meetingId,joinUrl:o.data?.joinUrl}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}async getMeeting(e){if(!this.account)throw new Error("Meeting skill not initialized");try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/meetings/${e}?app_token=${this.account.appId}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!r.ok)throw new Error(`HTTP ${r.status}: ${r.statusText}`);let o=await r.json();if(o.errCode!==0)throw new Error(o.errMsg);if(!o.data)throw new Error("No meeting data returned");return o.data}catch(t){throw t}}async updateMeeting(e,t){if(!this.account)return{ok:!1,error:"Meeting skill not initialized"};try{let r=N(this.account.config.apiGatewayUrl),o=await fetch(`${r}/v1/meetings/${e}?app_token=${this.account.appId}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!o.ok)return{ok:!1,error:`HTTP ${o.status}: ${o.statusText}`};let a=await o.json();return a.errCode!==0?{ok:!1,error:a.errMsg}:{ok:!0,meetingId:e}}catch(r){return{ok:!1,error:r instanceof Error?r.message:String(r)}}}async deleteMeeting(e){if(!this.account)return{ok:!1,error:"Meeting skill not initialized"};try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/meetings/${e}?app_token=${this.account.appId}`,{method:"DELETE",headers:{"Content-Type":"application/json"}});if(!r.ok)return{ok:!1,error:`HTTP ${r.status}: ${r.statusText}`};let o=await r.json();return o.errCode!==0?{ok:!1,error:o.errMsg}:{ok:!0}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}async listMeetings(e){if(!this.account)throw new Error("Meeting skill not initialized");try{let t=N(this.account.config.apiGatewayUrl),r=new URLSearchParams;r.append("app_token",this.account.appId),e?.startTime&&r.append("start_time",e.startTime),e?.endTime&&r.append("end_time",e.endTime),e?.maxResults&&r.append("max_results",e.maxResults.toString()),e?.pageToken&&r.append("page_token",e.pageToken),e?.status&&r.append("status",e.status);let o=await fetch(`${t}/v1/meetings/list?${r.toString()}`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);let a=await o.json();if(a.errCode!==0)throw new Error(a.errMsg);return a.data?.meetings||[]}catch(t){throw t}}async startMeeting(e){if(!this.account)return{ok:!1,error:"Meeting skill not initialized"};try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/meetings/${e}/start?app_token=${this.account.appId}`,{method:"POST",headers:{"Content-Type":"application/json"}});if(!r.ok)return{ok:!1,error:`HTTP ${r.status}: ${r.statusText}`};let o=await r.json();return o.errCode!==0?{ok:!1,error:o.errMsg}:{ok:!0,meetingId:e,joinUrl:o.data?.joinUrl}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}async endMeeting(e){if(!this.account)return{ok:!1,error:"Meeting skill not initialized"};try{let t=N(this.account.config.apiGatewayUrl),r=await fetch(`${t}/v1/meetings/${e}/end?app_token=${this.account.appId}`,{method:"POST",headers:{"Content-Type":"application/json"}});if(!r.ok)return{ok:!1,error:`HTTP ${r.status}: ${r.statusText}`};let o=await r.json();return o.errCode!==0?{ok:!1,error:o.errMsg}:{ok:!0,meetingId:e}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}}}});var Qe,Kr=y(()=>{u();Hr();zr();Jr();Qe=class{skills=new Map;registerSkill(e,t){this.skills.set(e,t)}getSkill(e){return this.skills.get(e)}initializeSkills(e){for(let t of this.skills.values())t.initialize&&t.initialize(e)}shutdownSkills(){for(let e of this.skills.values())e.shutdown&&e.shutdown()}}});import*as Vr from"crypto";function so(n,e,t){try{let r=Buffer.from(n,"base64");if(r.length<16)return t?.error("Decoded data is too short"),"";let o=Buffer.from(e+"=","base64"),a=Vr.createDecipheriv("aes-256-cbc",o,o.subarray(0,16));return Buffer.concat([a.update(r),a.final()]).toString("utf8")}catch(r){return r instanceof Error&&(r.message.includes("Invalid key length")||r.message.includes("Unsupported state"))?(t?.error(`Decryption error: ${r.message}`),""):(t?.error(`Decryption error: ${r}`),"")}}function $r(n,e,t){let r,o=n?.dataEncrypt;if(o&&(o=so(o,e,t),t?.info(`webhook: Decrypted message: ${o}`)),o)try{r=JSON.parse(o)}catch(a){return t?.error(`Failed to parse decrypted message: ${a}`),[]}else r=n;return!r?.events||r.events.length===0?(t?.error("No valid events found"),[]):r.events}var Yr=y(()=>{u()});var Dt=y(()=>{u();L()});async function he(n,e,t,r){if(!e?.trim())return{ok:!1,error:"No recipient provided"};let o=R(n),a={hookToken:n.hookToken,isGroup:r};try{if(typeof t=="string")return t?.trim()?await Ue(o,n,e,t,{...a,msgType:"formatText",formatType:1}):{ok:!1,error:"No message text provided"};let s=t;if(s.text||s.body){let c=s.text||s.body;return c?.trim()?await Ue(o,n,e,c,{...a,msgType:"formatText",formatType:1}):{ok:!1,error:"No message text provided"}}if(s.mediaUrl||s.mediaUrls){let c=s.mediaUrl||s.mediaUrls?.[0];if(!c)return{ok:!1,error:"No media URL provided"};let l=`Media: ${c}`;return await H(o,n,e,l,a)}if(s.images){let c=s.images||[s.images];if(!c||c.length===0)return{ok:!1,error:"No images provided"};let l=c[0];return await Ye(o,n,e,l)}if(s.files){let c=s.files||[s.files];if(!c||c.length===0)return{ok:!1,error:"No files provided"};let l=c[0];return await Ie(o,n,e,l)}if(s.voice){let c=s.voice;return c?await Ie(o,n,e,c):{ok:!1,error:"No voice provided"}}if(s.video){let c=s.video;return c?await Ie(o,n,e,c):{ok:!1,error:"No video provided"}}if(s.linkCard)return await ve(o,n,e,s.linkCard,a);if(s.appCard)return await ie(o,n,e,s.appCard,a);if(s.oaCard||s.oacard){let c=s.oaCard||s.oacard;return await Ae(o,n,e,c,a)}if(s.appArticles)return await Ce(o,n,e,s.appArticles,a);if(s.systemMessage)return await Me(o,n,e,s.systemMessage,a);if(s.toString){let c=s.toString();if(c)return await Ue(o,n,e,c,{...a,msgType:"formatText",formatType:1})}return{ok:!1,error:"No valid message content found"}}catch(s){return i.error("Error processing message",{error:s,payload:t}),{ok:!1,error:s instanceof Error?s.message:String(s)}}}var Xr=y(()=>{u();L();Dt()});var _t,Sr,Qr=y(()=>{u();G();_t=class{convertLanxinEventToOpenClawMessage(e,t){try{let r=e.eventType||e.type;switch(!r&&e.data&&(r=e.data.eventType||e.data.type),r){case"account_message":case"bot_private_message":return this.convertPrivateMessage(e,t);case"bot_group_message":return this.convertGroupMessage(e,t);case"staff_info":return null;default:return i.debug(`Unhandled event type: ${r}`),null}}catch(r){return i.error("Error converting Lanxin event to OpenClaw message",{error:r,event:e}),null}}convertPrivateMessage(e,t){i.debug("Converting private message event to OpenClaw message",{event:e});let r=e.data?.data||e.data,o=r.msgType||"formatText",a=r.from,s="",c=[];switch(o){case"text":s=r.msgData?.text?.content||"";break;case"image":s="[\u56FE\u7247]",c=(r.msgData?.image?.mediaIds||[]).map(l=>({type:"image",id:l}));break;case"video":s="[\u89C6\u9891]",c=(r.msgData?.video?.mediaIds||[]).map(l=>({type:"video",id:l}));break;case"file":s="[\u6587\u4EF6]",c=(r.msgData?.file?.mediaIds||[]).map(l=>({type:"file",id:l}));break;case"voice":s="[\u8BED\u97F3]",c=(r.msgData?.voice?.mediaIds||[]).map(l=>({type:"voice",id:l}));break;case"position":s=`[\u4F4D\u7F6E] ${r.msgData?.position?.name||"\u672A\u77E5\u4F4D\u7F6E"}`;break;case"card":s="[\u540D\u7247]";break;case"sticker":s="[\u8868\u60C5]";break;default:s=`[${o}]`;break}return{chatId:`lanxin_chat_${a}`,senderId:a,text:s,messageId:e.id||r.id,chatType:"p2p",messageType:o,attachments:c.length>0?c:void 0,timestamp:this.extractTimestamp(r)}}convertGroupMessage(e,t){let r=e.data?.data||e.data,o=r.msgType||"formatText",a=r.from,s=r.groupId,c="",l=[];switch(o){case"text":c=r.msgData?.text?.content||"";break;case"image":c="[\u56FE\u7247]",l=(r.msgData?.image?.mediaIds||[]).map(d=>({type:"image",id:d}));break;case"video":c="[\u89C6\u9891]",l=(r.msgData?.video?.mediaIds||[]).map(d=>({type:"video",id:d}));break;case"file":c="[\u6587\u4EF6]",l=(r.msgData?.file?.mediaIds||[]).map(d=>({type:"file",id:d}));break;case"voice":c="[\u8BED\u97F3]",l=(r.msgData?.voice?.mediaIds||[]).map(d=>({type:"voice",id:d}));break;case"position":c=`[\u4F4D\u7F6E] ${r.msgData?.position?.name||"\u672A\u77E5\u4F4D\u7F6E"}`;break;case"card":c="[\u540D\u7247]";break;case"sticker":c="[\u8868\u60C5]";break;default:c=`[${o}]`;break}return{chatId:s,senderId:a,text:c,messageId:e.id||r.id,chatType:"group",messageType:o,attachments:l.length>0?l:void 0,timestamp:this.extractTimestamp(r)}}extractTimestamp(e){if(e.msgData){let t=e.msgData;if(t.text?.sendTime)return t.text.sendTime;if(t.image?.sendTime)return t.image.sendTime;if(t.video?.sendTime)return t.video.sendTime;if(t.file?.sendTime)return t.file.sendTime;if(t.voice?.sendTime)return t.voice.sendTime;if(t.position?.sendTime)return t.position.sendTime;if(t.card?.sendTime)return t.card.sendTime;if(t.sticker?.sendTime)return t.sticker.sendTime}}convertOpenClawMessageToLanxinMessage(e){try{let{text:t,messageType:r,attachments:o}=e,a={};switch(r){case"text":a={text:{content:t}};break;case"image":a={image:{mediaIds:o?.filter(s=>s.type==="image").map(s=>s.id).filter(Boolean)||[]}};break;case"video":a={video:{mediaIds:o?.filter(s=>s.type==="video").map(s=>s.id).filter(Boolean)||[]}};break;case"file":a={file:{mediaIds:o?.filter(s=>s.type==="file").map(s=>s.id).filter(Boolean)||[]}};break;case"voice":a={voice:{mediaIds:o?.filter(s=>s.type==="voice").map(s=>s.id).filter(Boolean)||[]}};break;default:a={text:{content:t}};break}return{msgType:r,msgData:a}}catch(t){return i.error("Error converting OpenClaw message to Lanxin message",{error:t,message:e}),{msgType:"text",msgData:{text:{content:e.text}}}}}},Sr=new _t});var Bt,vr,Zr=y(()=>{u();G();Bt=class{handlers=new Map;registerHandler(e,t){this.handlers.has(e)||this.handlers.set(e,[]),this.handlers.get(e)?.push(t)}async classifyAndProcess(e,t){try{let r=e.eventType||e.type;!r&&e.data&&(r=e.data.eventType||e.data.type),i.info(`Classifying event type: ${r}`);let o=this.handlers.get(r);return o&&o.length>0?await Promise.all(o.map(s=>s.handle(e,t))):(i.debug(`No handlers registered for event type: ${r}`),null)}catch(r){return i.error("Error classifying and processing event",{error:r,event:e}),null}}getRegisteredEventTypes(){return Array.from(this.handlers.keys())}getHandlers(e){return this.handlers.get(e)||[]}},vr=new Bt});var en=y(()=>{u();Yr();Xr();Qr();Zr();Dt()});import*as X from"fs";var Ze,io,tn=y(()=>{u();Ze=class{static create(){return async(e,t)=>{let{openclawMessage:r,userId:o}=e;if(r){if(r.type==="text")e.lanxinMessage={type:"text",content:r.content,to:o,timestamp:r.timestamp};else if(r.type==="image"){let a=r.content;if(X.existsSync(a)){let s=X.readFileSync(a,"base64");e.lanxinMessage={type:"image",content:s,filename:r.filename||"image.jpg",to:o,timestamp:r.timestamp}}}else if(r.type==="file"){let a=r.content;if(X.existsSync(a)){let s=X.readFileSync(a,"base64");e.lanxinMessage={type:"file",content:s,filename:r.filename||"file.txt",to:o,timestamp:r.timestamp}}}else if(r.type==="audio"){let a=r.content;if(X.existsSync(a)){let s=X.readFileSync(a,"base64");e.lanxinMessage={type:"audio",content:s,filename:r.filename||"audio.mp3",duration:r.duration||0,to:o,timestamp:r.timestamp}}}else if(r.type==="video"){let a=r.content;if(X.existsSync(a)){let s=X.readFileSync(a,"base64");e.lanxinMessage={type:"video",content:s,filename:r.filename||"video.mp4",duration:r.duration||0,to:o,timestamp:r.timestamp}}}}await t()}}},io=Ze.create()});import*as oe from"fs";import*as de from"path";import*as rn from"https";import{fileURLToPath as co}from"url";var lo,po,et,uo,nn=y(()=>{u();lo=co(import.meta.url),po=de.dirname(lo),et=class{static processedMessages=new Set;static create(){return async(e,t)=>{let{message:r,userId:o}=e;if(r.eventType==="message"){let a=r.messageId;if(this.processedMessages.has(a))return;if(this.processedMessages.add(a),r.messageType==="text")e.openclawMessage={type:"text",content:r.content,from:o,timestamp:r.timestamp};else if(r.messageType==="image"){let s=await this.downloadMedia(r.content,"images");e.openclawMessage={type:"image",content:s,filename:r.filename||"image.jpg",from:o,timestamp:r.timestamp}}else if(r.messageType==="file"){let s=await this.downloadMedia(r.content,"files");e.openclawMessage={type:"file",content:s,filename:r.filename||"file.txt",from:o,timestamp:r.timestamp}}else if(r.messageType==="audio"){let s=await this.downloadMedia(r.content,"audio");e.openclawMessage={type:"audio",content:s,filename:r.filename||"audio.mp3",duration:r.duration||0,from:o,timestamp:r.timestamp}}else if(r.messageType==="video"){let s=await this.downloadMedia(r.content,"video");e.openclawMessage={type:"video",content:s,filename:r.filename||"video.mp4",duration:r.duration||0,from:o,timestamp:r.timestamp}}}await t()}}static async downloadMedia(e,t){let r=de.join(po,"../../../media",t);oe.existsSync(r)||oe.mkdirSync(r,{recursive:!0});let o=de.basename(e)||`${Date.now()}.bin`,a=de.join(r,o);return new Promise((s,c)=>{let l=oe.createWriteStream(a);rn.get(e,d=>{d.pipe(l),l.on("finish",()=>{l.close(),s(a)})}).on("error",d=>{oe.unlink(a,()=>{}),c(d)})})}},uo=et.create()});var tt,At,on=y(()=>{u();tt=class{static create(){return async(e,t)=>{await t()}}},At=tt.create()});import rt from"node:fs";import Gt from"node:path";import{fileURLToPath as fo}from"node:url";var go,Wt,mo,Ft,nt,Ct,an=y(()=>{u();L();go=fo(import.meta.url),Wt=Gt.dirname(go),mo=Wt.includes("dist"),Ft=n=>mo?Gt.join(Wt,n):Gt.join(Wt,"../../../",n),nt=class{static commands={help:async e=>{e.response={type:"text",content:`\u84DD\u4FE1 OpenClaw \u63D2\u4EF6\u652F\u6301\u4EE5\u4E0B\u547D\u4EE4\uFF1A
|
|
18
18
|
/lanxin send-all-message-types - \u53D1\u9001\u6240\u6709\u652F\u6301\u7684\u6D88\u606F\u7C7B\u578B
|
|
19
19
|
/lanxin test-text - \u6D4B\u8BD5\u6587\u672C\u6D88\u606F
|
|
20
20
|
/lanxin test-image - \u6D4B\u8BD5\u56FE\u7247\u6D88\u606F
|
|
@@ -29,9 +29,22 @@ Content-Type: application/octet-stream\r
|
|
|
29
29
|
/lanxin agent-list - \u67E5\u770B\u6240\u6709\u673A\u5668\u4EBA\u4E0E Agent \u7684\u7ED1\u5B9A\u5173\u7CFB
|
|
30
30
|
/lanxin help - \u663E\u793A\u6B64\u5E2E\u52A9\u4FE1\u606F
|
|
31
31
|
|
|
32
|
-
\u66F4\u591A\u547D\u4EE4\u5C06\u5728\u540E\u7EED\u7248\u672C\u4E2D\u6DFB\u52A0\u3002`}},"send-all-message-types":async e=>{let{userId:t,config:r}=e,o=
|
|
32
|
+
\u66F4\u591A\u547D\u4EE4\u5C06\u5728\u540E\u7EED\u7248\u672C\u4E2D\u6DFB\u52A0\u3002`}},"send-all-message-types":async e=>{let{userId:t,config:r}=e,o=R(r);await H(o,r,t,"\u8FD9\u662F\u6587\u672C\u6D88\u606F"),await ve(o,r,t,{title:"\u6D4B\u8BD5\u94FE\u63A5\u5361\u7247",description:"\u8FD9\u662F\u4E00\u6761\u6D4B\u8BD5\u94FE\u63A5\u5361\u7247",link:"https://example.com",iconLink:"https://example.com/icon.png"}),await ie(o,r,t,{bodyTitle:"\u6D4B\u8BD5\u5E94\u7528\u5361\u7247",bodyContent:"\u8FD9\u662F\u4E00\u6761\u6D4B\u8BD5\u5E94\u7528\u5361\u7247",links:[{title:"\u67E5\u770B\u8BE6\u60C5",url:"https://example.com"}]}),await Ae(o,r,t,{title:"\u6D4B\u8BD5OA\u5361\u7247",subTitle:"\u526F\u6807\u9898",fields:[{key:"\u5B57\u6BB51",value:"\u503C1"},{key:"\u5B57\u6BB52",value:"\u503C2"}],link:"https://example.com"}),await Ce(o,r,t,[{title:"\u6D4B\u8BD5\u56FE\u6587\u6D88\u606F",description:"\u8FD9\u662F\u4E00\u6761\u6D4B\u8BD5\u56FE\u6587\u6D88\u606F",imageUrl:"https://example.com/article-image.jpg",url:"https://example.com"}]),await Me(o,r,t,{content:"\u8FD9\u662F\u4E00\u6761\u6D4B\u8BD5\u7CFB\u7EDF\u6D88\u606F"}),e.response={type:"text",content:"\u5DF2\u53D1\u9001\u6240\u6709\u652F\u6301\u7684\u6D88\u606F\u7C7B\u578B"}},"test-text":async e=>{let{userId:t,config:r}=e,o=R(r);await H(o,r,t,"\u8FD9\u662F\u4E00\u6761\u6D4B\u8BD5\u6587\u672C\u6D88\u606F"),e.response={type:"text",content:"\u5DF2\u53D1\u9001\u6D4B\u8BD5\u6587\u672C\u6D88\u606F"}},"test-image":async e=>{let{userId:t,config:r}=e,o=R(r),a=Ft("assets/logo.png");rt.existsSync(a)?(await Ye(o,r,t,a),e.response={type:"text",content:"\u5DF2\u53D1\u9001\u6D4B\u8BD5\u56FE\u7247\u6D88\u606F"}):(await H(o,r,t,"\u56FE\u7247\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A"+a),e.response={type:"text",content:"\u56FE\u7247\u6587\u4EF6\u4E0D\u5B58\u5728"})},"test-file":async e=>{let{userId:t,config:r}=e,o=R(r),a=Ft("README.md");rt.existsSync(a)?(await Ie(o,r,t,a),e.response={type:"text",content:"\u5DF2\u53D1\u9001\u6D4B\u8BD5\u6587\u4EF6\u6D88\u606F"}):(await H(o,r,t,"\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A"+a),e.response={type:"text",content:"\u6587\u4EF6\u4E0D\u5B58\u5728"})},"test-md":async e=>{let{userId:t,config:r}=e,o=R(r),a=Ft("README.md");if(rt.existsSync(a)){let s=rt.readFileSync(a,"utf8");await H(o,r,t,s,{hookToken:r.hookToken,isGroup:t.startsWith("oc_"),msgType:"formatText"}),e.response={type:"text",content:"\u5DF2\u53D1\u9001\u6D4B\u8BD5Markdown\u6D88\u606F"}}else await H(o,r,t,"README.md\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A"+a),e.response={type:"text",content:"README.md\u6587\u4EF6\u4E0D\u5B58\u5728"}},"test-link-card":async e=>{let{userId:t,config:r}=e,o=R(r);await ve(o,r,t,{title:"\u6D4B\u8BD5\u94FE\u63A5\u5361\u7247",description:"\u8FD9\u662F\u4E00\u6761\u6D4B\u8BD5\u94FE\u63A5\u5361\u7247",link:"https://example.com",iconLink:"https://example.com/icon.png"}),e.response={type:"text",content:"\u5DF2\u53D1\u9001\u6D4B\u8BD5\u94FE\u63A5\u5361\u7247"}},"test-app-card":async e=>{let{userId:t,config:r,accountId:o}=e,a=R(r),s=`approval_${Date.now()}_${Math.floor(Math.random()*1e3)}`,c=`https://example.com/api/approval?approvalId=${s}&action={{action}}&userId=${t}&accountId=${o}`;await ie(a,r,t,{headTitle:"\u5BA1\u6279\u4EFB\u52A1",isDynamic:!0,headStatusInfo:{description:'<div style="color:#FFB116">\u5F85\u5BA1\u6279</div>',colour:"#FFB116"},bodyTitle:'<div style="color:#000000;font-size:17pt;text-align:left">\u7CFB\u7EDF\u7EF4\u62A4\u64CD\u4F5C\u5BA1\u6279</div>',bodySubTitle:'<div style="color:#242E3E;font-size:13pt;text-align:left">\u8FD0\u7EF4\u90E8\u95E8 [2026] 001\u53F7</div>',bodyContent:'<div style="color: #000000;font-size: 15pt;text-align: left;text-indent: 2em">\u8FD0\u7EF4\u90E8\u95E8\u7533\u8BF7\u6267\u884C\u7CFB\u7EDF\u7EF4\u62A4\u64CD\u4F5C\uFF0C\u9700\u8981\u60A8\u7684\u5BA1\u6279\u3002</div><div style="color: #000000;font-size: 15pt;text-align: left;margin-top: 10px;"><strong>\u6267\u884C\u547D\u4EE4\uFF1A</strong></div><div style="color: #FF4757;font-size: 14pt;text-align: left;background-color: #F5F5F5;padding: 10px;border-left: 3px solid #FF4757;margin: 5px 0;">rm -rf /test</div><div style="color: #000000;font-size: 15pt;text-align: left;margin-top: 10px;"><strong>\u64CD\u4F5C\u8BF4\u660E\uFF1A</strong></div><div style="color: #000000;font-size: 14pt;text-align: left;margin: 5px 0;">\u5220\u9664\u6D4B\u8BD5\u76EE\u5F55\uFF0C\u6E05\u7406\u7CFB\u7EDF\u7A7A\u95F4</div>',fields:[{key:'<div style="color: #242E3E">\u7533\u8BF7\u4EBA\uFF1A</div>',value:'<div style="color: #000000">\u8FD0\u7EF4\u5DE5\u7A0B\u5E08</div>'},{key:'<div style="color: #242E3E">\u7533\u8BF7\u65F6\u95F4\uFF1A</div>',value:'<div style="color: #000000">2026-04-14 10:00</div>'},{key:'<div style="color: #242E3E">\u64CD\u4F5C\u7C7B\u578B\uFF1A</div>',value:'<div style="color: #000000">\u7CFB\u7EDF\u7EF4\u62A4</div>'},{key:'<div style="color: #242E3E">\u5BA1\u6279ID\uFF1A</div>',value:`<div style="color: #000000">${s}</div>`}],links:[{title:'<div style="color: #52C41A;text-align: center">\u540C\u610F</div>',url:c.replace("{{action}}","approve")},{title:'<div style="color: #FF4757;text-align: center">\u62D2\u7EDD</div>',url:c.replace("{{action}}","reject")}]}),e.response={type:"text",content:`\u5DF2\u53D1\u9001\u6D4B\u8BD5\u5E94\u7528\u5361\u7247\uFF08\u5BA1\u6279\u6837\u5F0F\uFF09\uFF0C\u5BA1\u6279ID\uFF1A${s}`}},"test-oa-card":async e=>{let{userId:t,config:r}=e,o=R(r);await Ae(o,r,t,{title:"\u6D4B\u8BD5OA\u5361\u7247",subTitle:"\u526F\u6807\u9898",fields:[{key:"\u5B57\u6BB51",value:"\u503C1"},{key:"\u5B57\u6BB52",value:"\u503C2"}],link:"https://example.com"}),e.response={type:"text",content:"\u5DF2\u53D1\u9001\u6D4B\u8BD5OA\u5361\u7247"}},"test-app-articles":async e=>{let{userId:t,config:r}=e,o=R(r);await Ce(o,r,t,[{title:"\u6D4B\u8BD5\u56FE\u6587\u6D88\u606F",description:"\u8FD9\u662F\u4E00\u6761\u6D4B\u8BD5\u56FE\u6587\u6D88\u606F",imageUrl:"https://example.com/article-image.jpg",url:"https://example.com"}]),e.response={type:"text",content:"\u5DF2\u53D1\u9001\u6D4B\u8BD5\u56FE\u6587\u6D88\u606F"}},"test-system":async e=>{let{userId:t,config:r}=e,o=R(r);await Me(o,r,t,{content:"\u8FD9\u662F\u4E00\u6761\u6D4B\u8BD5\u7CFB\u7EDF\u6D88\u606F"}),e.response={type:"text",content:"\u5DF2\u53D1\u9001\u6D4B\u8BD5\u7CFB\u7EDF\u6D88\u606F"}},agent:async e=>{let{config:t}=e,r=se().getBotAgent(t.appId);e.response={type:"text",content:`\u5F53\u524D\u673A\u5668\u4EBA\u7ED1\u5B9A\u7684 Agent: ${r}`}},"agent-list":async e=>{let t=se().getAllBindings();if(t.length===0)e.response={type:"text",content:"\u6682\u65E0\u673A\u5668\u4EBA\u4E0E Agent \u7684\u7ED1\u5B9A\u5173\u7CFB"};else{let r=t.map(o=>`${o.botId} -> ${o.agentId}`).join(`
|
|
33
33
|
`);e.response={type:"text",content:`\u673A\u5668\u4EBA\u4E0E Agent \u7ED1\u5B9A\u5173\u7CFB:
|
|
34
34
|
${r}`}}}};static create(){return async(e,t)=>{let{message:r}=e;if(r.type==="text"&&r.content.startsWith("/lanxin ")){let o=r.content.substring(7).trim(),a={\u5E2E\u52A9:"help",\u53D1\u9001\u6240\u6709\u7C7B\u578B:"send-all-message-types",\u6D4B\u8BD5\u6D88\u606F:"test-text",\u6D4B\u8BD5\u6587\u672C:"test-text",\u6D4B\u8BD5\u56FE\u7247:"test-image",\u6D4B\u8BD5\u6587\u4EF6:"test-file",\u6D4B\u8BD5\u94FE\u63A5\u5361\u7247:"test-link-card",\u6D4B\u8BD5\u5E94\u7528\u5361\u7247:"test-app-card",\u6D4B\u8BD5OA\u5361\u7247:"test-oa-card",\u6D4B\u8BD5\u56FE\u6587\u6D88\u606F:"test-app-articles",\u6D4B\u8BD5\u7CFB\u7EDF\u6D88\u606F:"test-system"};if(a[o]&&(o=a[o]),o==="\u914D\u5BF9"){await t();return}else if(o.startsWith("\u914D\u5BF9 ")){await t();return}let s=this.commands[o];s?await s(e):e.response={type:"text",content:`\u672A\u77E5\u547D\u4EE4\uFF1A${o}
|
|
35
|
-
\u8BF7\u4F7F\u7528 /lanxin help \u67E5\u770B\u53EF\u7528\u547D\u4EE4\u3002`}}else await t()}}},At=nt.create()});var en=w(()=>{u();Vr();Yr();Qr();Zr()});function ot(n){return new Gt}var Gt,tn=w(()=>{u();W();Gt=class{pairingData;constructor(){this.pairingData={pairingRequests:{},approvedUsers:[],lastUpdated:new Date().toISOString()},i.debug("Initialized PairingManager with in-memory storage")}generatePairingCode(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",t="";for(let r=0;r<8;r++)t+=e.charAt(Math.floor(Math.random()*e.length));return i.debug("Generated new pairing code",{code:t}),t}getExistingPairingCode(e){i.debug("Checking for existing pairing code",{identifier:e});for(let t in this.pairingData.pairingRequests){let r=this.pairingData.pairingRequests[t];if(r.staffId===e||r.userId===e){let o=new Date(r.createdAt),s=(new Date().getTime()-o.getTime())/(1e3*60*60);if(s<=1)return i.debug("Found existing valid pairing code",{identifier:e,code:t,diffInHours:s}),t;i.debug("Found existing but expired pairing code",{identifier:e,code:t,diffInHours:s}),delete this.pairingData.pairingRequests[t],this.pairingData.lastUpdated=new Date().toISOString()}}return i.debug("No existing valid pairing code found",{identifier:e}),null}storePairingRequest(e,t,r){i.info("Storing pairing request",{code:e,userId:t,staffId:r}),i.info("Current pairingRequests before storing:",Object.keys(this.pairingData.pairingRequests)),this.pairingData.pairingRequests[e]={code:e,userId:t,staffId:r,createdAt:new Date().toISOString()},this.pairingData.lastUpdated=new Date().toISOString(),i.info("Pairing request stored in memory:",this.pairingData.pairingRequests[e]),i.info("Pairing request stored successfully",{code:e,userId:t,staffId:r})}getPairingRequest(e){i.debug("Getting pairing request",{code:e});let t=this.pairingData.pairingRequests[e];if(!t)return i.debug("No pairing request found",{code:e}),null;let r=new Date(t.createdAt),a=(new Date().getTime()-r.getTime())/(1e3*60*60);return a>1?(i.debug("Pairing request expired",{code:e,diffInHours:a}),delete this.pairingData.pairingRequests[e],this.pairingData.lastUpdated=new Date().toISOString(),null):(i.debug("Found valid pairing request",{code:e,staffId:t.staffId}),t)}approveUser(e){i.debug("Approving user",{staffId:e}),this.pairingData.approvedUsers.includes(e)?i.debug("User already in approved list",{staffId:e}):(i.debug("Adding user to approved list",{staffId:e}),this.pairingData.approvedUsers.push(e),this.pairingData.lastUpdated=new Date().toISOString(),i.debug("User added to approved list successfully",{staffId:e,approvedUsers:this.pairingData.approvedUsers}))}isUserApproved(e){try{i.debug("Checking if user is approved",{staffId:e});let t=this.pairingData.approvedUsers.includes(e);return i.debug("User approval status",{staffId:e,isApproved:t,approvedUsers:this.pairingData.approvedUsers}),t}catch(t){return i.error("Error checking if user is approved",{error:t,staffId:e}),!1}}removePairingRequest(e){delete this.pairingData.pairingRequests[e],this.pairingData.lastUpdated=new Date().toISOString()}approvePairingRequest(e){i.debug("Approving pairing request",{code:e});let t=this.getPairingRequest(e);return t?(i.debug("Pairing request found, approving user",{code:e,staffId:t.staffId}),this.approveUser(t.staffId),this.removePairingRequest(e),i.debug("Pairing request approved successfully",{code:e,staffId:t.staffId}),!0):(i.debug("Pairing request not found or expired",{code:e}),!1)}getSessionByCode(e){i.debug("Getting session by code",{code:e});let t=this.getPairingRequest(e);return t?(i.debug("Found session for code",{code:e,staffId:t.staffId}),{staffId:t.staffId}):(i.debug("No session found for code",{code:e}),null)}}});function Tr(n){let e=Date.now();for(let[t,r]of at)e-r>6e5&&at.delete(t);return n?at.has(n)?!0:(at.set(n,e),!1):!1}var at,rn=w(()=>{u();at=new Map});function xr(n,e,t){if(e.length>0)return!0;let r=n.toLowerCase();if(/[??]$/.test(n)||/\b(why|how|what|when|where|who|help)\b/.test(r)||["\u5E2E","\u9EBB\u70E6","\u8BF7","\u80FD\u5426","\u53EF\u4EE5","\u89E3\u91CA","\u770B\u770B","\u6392\u67E5","\u5206\u6790","\u603B\u7ED3","\u5199","\u6539","\u4FEE","\u67E5","\u5BF9\u6BD4","\u7FFB\u8BD1"].some(c=>n.includes(c)))return!0;let a=t?.length?t:so;return!!new RegExp(`^(${a.map(io).join("|")})[\\s,:\uFF0C\uFF1A]`,"i").test(n)}function io(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var so,nn=w(()=>{u();so=["clawdbot","moltbot","bot","\u52A9\u624B","\u667A\u80FD\u4F53"]});var Wt,Ie,on=w(()=>{u();Wt=class{staffIdCache=new Map;staffInfoCache=new Map;setStaffId(e,t){this.staffIdCache.set(e,t)}getStaffId(e){return this.staffIdCache.get(e)}setStaffInfo(e,t){this.staffInfoCache.set(e,t)}getStaffInfo(e){return this.staffInfoCache.get(e)}clearStaffId(e){this.staffIdCache.delete(e),this.staffInfoCache.delete(e)}clearAll(){this.staffIdCache.clear(),this.staffInfoCache.clear()}},Ie=new Wt});async function st(n,e,t=5e3,r){if(!n?.trim()||!e?.trim())return i.warn("Missing appId or appSecret for Lanxin probe"),{ok:!1,error:"Missing appId or appSecret",elapsedMs:0};let o=Date.now(),a=new AbortController,s=setTimeout(()=>a.abort(),t),c=N(r);try{let l=x.auth.appToken,d=new URLSearchParams({grant_type:"client_credential",appid:n.trim(),secret:e.trim()}),p=await fetch(`${c}${l}?${d.toString()}`,{method:"GET",headers:{"Content-Type":"application/json"},signal:a.signal});clearTimeout(s);let f=Date.now()-o;if(!p.ok){let m=`HTTP ${p.status}: ${p.statusText}`;return i.error(m,{url:`${c}${l}`,status:p.status}),{ok:!1,error:m,elapsedMs:f}}let g=await p.json();if(g.errCode!==0){let m=g.errMsg||`API error code: ${g.errCode}`;return i.error("Lanxin API probe error",{errCode:g.errCode,errMsg:m}),{ok:!1,error:m,elapsedMs:f}}if(!g.data?.appToken){let m="No appToken returned";return i.error("Lanxin API probe error",{errMsg:m}),{ok:!1,error:m,elapsedMs:f}}return{ok:!0,elapsedMs:f}}catch(l){clearTimeout(s);let d=Date.now()-o;if(l instanceof Error){if(l.name==="AbortError"){let f=`Request timed out after ${t}ms`;return i.warn(f),{ok:!1,error:f,elapsedMs:d}}return i.error("Error probing Lanxin API",{error:l.message}),{ok:!1,error:l.message,elapsedMs:d}}let p=String(l);return i.error("Error probing Lanxin API",{error:p}),{ok:!1,error:p,elapsedMs:d}}}async function it(n,e=5e3,t){if(!n?.trim())return i.warn("Missing hookToken for webhook bot probe"),{ok:!1,error:"Missing hookToken",elapsedMs:0};let r=Date.now(),o=new AbortController,a=setTimeout(()=>o.abort(),e);try{if(i.debug("Probing webhook bot",{hookToken:n.slice(0,10)+"..."}),n.length<10)return i.warn("Invalid hookToken format",{length:n.length}),{ok:!1,error:"Invalid hookToken format",elapsedMs:Date.now()-r};clearTimeout(a);let s=Date.now()-r;return i.info("Webhook bot probe successful",{elapsedMs:s}),{ok:!0,elapsedMs:s}}catch(s){clearTimeout(a);let c=Date.now()-r;if(s instanceof Error){if(s.name==="AbortError"){let d=`Request timed out after ${e}ms`;return i.warn(d),{ok:!1,error:d,elapsedMs:c}}return i.error("Error probing webhook bot",{error:s.message}),{ok:!1,error:s.message,elapsedMs:c}}let l=String(s);return i.error("Error probing webhook bot",{error:l}),{ok:!1,error:l,elapsedMs:c}}}var an=w(()=>{u();Q();z();W()});var sn=w(()=>{u();Z();Q();W()});var jt,cc,cn=w(()=>{u();jt=class{sessions=new Map;staffIdToCode=new Map;constructor(){}generateCode(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",t="";for(let r=0;r<6;r++)t+=e.charAt(Math.floor(Math.random()*e.length));return t}createSession(e,t){let r=this.generateCode(),o={code:r,staffId:t,createdAt:Date.now(),accountId:e};return this.sessions.set(r,o),this.staffIdToCode.set(`${e}:${t}`,r),o}getSessionByCode(e){return this.sessions.get(e)}getSessionByStaffId(e,t){let r=this.staffIdToCode.get(`${e}:${t}`);if(r)return this.sessions.get(r)}deleteSession(e){let t=this.sessions.get(e);t&&(this.staffIdToCode.delete(`${t.accountId}:${t.staffId}`),this.sessions.delete(e))}clearSessions(e){for(let[t,r]of this.sessions.entries())r.accountId===e&&(this.staffIdToCode.delete(`${e}:${r.staffId}`),this.sessions.delete(t))}clearAllSessions(){this.sessions.clear(),this.staffIdToCode.clear()}},cc=new jt});var ln=w(()=>{u();W();rn();nn();He();on();Z();an();sn();cn()});var G=w(()=>{u();z();Sr();Br();Wr();Q();Kr();en();tn();Ke();Ge();$t();ln()});u();gt();ge();u();ge();u();ge();function An(n){let e=n.channels?.Lansenger?.accounts;return!e||typeof e!="object"?[]:Object.keys(e).filter(Boolean)}function ee(n){let e=An(n);return e.length===0?[_]:e.sort((t,r)=>t.localeCompare(r))}function Be(n){let e=n.channels?.Lansenger;if(e?.defaultAccount?.trim())return e.defaultAccount.trim();let t=ee(n);return t.includes(_)?_:t[0]??_}function Mn(n,e){let t=n.channels?.Lansenger?.accounts;if(!(!t||typeof t!="object"))return t[e]}function Cn(n,e){let t=n.channels?.Lansenger??{},{accounts:r,defaultAccount:o,...a}=t,s=Mn(n,e)??{};return{...a,...s}}function En(n,e){if(e.credentials?.appId?.trim()&&e.credentials?.appSecret?.trim())return{appId:e.credentials.appId.trim(),appSecret:e.credentials.appSecret.trim(),source:"config"};if(e.appId?.trim()&&e.appSecret?.trim())return{appId:e.appId.trim(),appSecret:e.appSecret.trim(),source:"config"};let r=n.plugins?.entries?.Lansenger?.config;return r?.appId?.trim()&&r?.appSecret?.trim()?{appId:r.appId.trim(),appSecret:r.appSecret.trim(),source:"plugin"}:{appId:"",appSecret:"",source:"none"}}function P(n){let e=fe(n.accountId),t=n.cfg.channels?.Lansenger?.enabled!==!1,r=Cn(n.cfg,e),o=r.enabled!==!1,a=t&&o,s=En(n.cfg,r);return{accountId:e,name:r.name?.trim()||void 0,enabled:a,appId:s.appId,appSecret:s.appSecret,tokenSource:s.source,config:r,agentId:r.agentId||"default"}}u();G();ge();function co(n,e){let t=n.channels?.lanxin??{};i.info("Setting DM policy",{dmPolicy:e});let r=Array.isArray(t.allowFrom)?t.allowFrom:[],o=e==="open"?Zt(r):void 0,a={...n,channels:{...n.channels??{},lanxin:{...t,dmPolicy:e,...o?{allowFrom:o}:{}}}};return i.info("Updated DM policy",{clawdbotCfg:a}),a}async function dn(n){await n.note(["1) Go to https://open.lanxin.cn/app \u2192 Create self-built app","2) Add Bot capability to the app","3) Enable permissions: im:message, im:message.group_at_msg, im:message.p2p_msg",'4) Events: add im.message.receive_v1, set delivery to "WebSocket long-connection"',"5) Publish the app (create version \u2192 request approval)","6) Note the App ID (cli_xxx) and App Secret","","Docs: https://open.lanxin.cn/document/home/index"].join(`
|
|
36
|
-
`),"Lanxin Bot Setup")}async function
|
|
37
|
-
`),s=o.lastIndexOf(" "),c=a>0?a:s;c<=0&&(c=e);let d=r.slice(0,c).trimEnd();d.length>0&&t.push(d);let p=c<r.length&&/\s/.test(r[c]),f=Math.min(r.length,c+(p?1:0));r=r.slice(f).trimStart()}return r.length&&t.push(r),t}async function kn({to:n,text:e,accountId:t,cfg:r}){i.info(`[lanxin] sendText method called with parameters: to=${n}, accountId=${t}, text=${e.slice(0,80)}`);let o;if(t)o=P({accountId:t??void 0,cfg:r});else{let s=Ht(r,n);if(!s)return i.error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E"),{channel:"lanxin",ok:!1,messageId:"",error:new Error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E")};o=s}if(!o.appId)return i.error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E"),{channel:"lanxin",ok:!1,messageId:"",error:new Error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E")};i.info(`[lanxin] Using account ${o.accountId} (appId: ${o.appId.slice(0,8)}...) for staffId ${n}`);let a=await he(o.config,n,e,n.startsWith("oc_"));return{channel:"lanxin",ok:a.ok,messageId:a.messageId??"",error:a.error?new Error(a.error):void 0}}async function yn({to:n,text:e,mediaUrl:t,accountId:r,cfg:o}){i.debug(`[lanxin] sendMedia method called with parameters: to=${n}, accountId=${r}, text=${e.slice(0,80)}`);let a;if(r)a=P({accountId:r??void 0,cfg:o});else{let l=Ht(o,n);if(!l)return i.error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E"),{channel:"lanxin",ok:!1,messageId:"",error:new Error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E")};a=l}if(!a.appId)return i.error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E"),{channel:"lanxin",ok:!1,messageId:"",error:new Error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E")};i.info(`[lanxin] Using account ${a.accountId} (appId: ${a.appId.slice(0,8)}...) for staffId ${n}`);let s={text:e||"",mediaUrl:t},c=await he(a.config,n,s,n.startsWith("oc_"));return{channel:"lanxin",ok:c.ok,messageId:c.messageId??"",error:c.error?new Error(c.error):void 0}}async function wn({to:n,text:e,accountId:t,cfg:r,log:o}){i.debug(`[lanxin] Push method called with parameters: to=${n}, accountId=${t}, text=${e.slice(0,80)}`);try{let a;if(t)a=P({accountId:t??void 0,cfg:r});else{let d=Ht(r,n);if(!d)return i.error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E"),{channel:"lanxin",ok:!1,messageId:"",error:new Error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E")};a=d}if(i.debug(`[lanxin] Resolved account: ${a.accountId}, appId: ${a.appId?.slice(0,8)}...`),!a.appId)return i.error(`[lanxin] No appId found for account ${a.accountId}`),{channel:"lanxin",ok:!1,messageId:"",error:new Error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E")};i.info(`[lanxin] Using account ${a.accountId} (appId: ${a.appId.slice(0,8)}...) for staffId ${n}`),(o||{info:d=>i.info(`[lanxin:${a.accountId}] ${d}`),error:d=>i.error(`[lanxin:${a.accountId}] ${d}`),debug:d=>i.debug(`[lanxin:${a.accountId}] ${d}`)}).info(`[lanxin:${a.accountId}] Received OpenClaw push notification: to=${n}, text=${e.slice(0,80)}`),i.debug(`[lanxin:${a.accountId}] Calling processAndSendMessage`);let l=await he(a.config,n,e,n.startsWith("oc_"));return i.debug(`[lanxin:${a.accountId}] processAndSendMessage result: ok=${l.ok}, messageId=${l.messageId}, error=${l.error}`),{channel:"lanxin",ok:l.ok,messageId:l.messageId??"",error:l.error?new Error(l.error):void 0}}catch(a){return i.error(`[lanxin] Error in push method: ${a instanceof Error?a.message:String(a)}`),{channel:"lanxin",ok:!1,messageId:"",error:new Error(a instanceof Error?a.message:String(a))}}}u();G();var In={accountId:"default",running:!1,lastStartAt:null,lastStopAt:null,lastError:null};function Tn({snapshot:n}){return{configured:n.configured??!1,tokenSource:n.tokenSource??"none",running:n.running??!1,mode:n.mode??"websocket",lastStartAt:n.lastStartAt??null,lastStopAt:n.lastStopAt??null,lastError:n.lastError??null,probe:n.probe,lastProbeAt:n.lastProbeAt??null}}async function xn({account:n,timeoutMs:e}){return xe(n)==="webhook"?it(n.config.hookToken||"",e,n.config.apiGatewayUrl):st(n.appId,n.appSecret,e,n.config.apiGatewayUrl)}function $n({account:n,runtime:e}){let t=xe(n),r=t==="webhook"?!!n.config.hookToken?.trim():!!(n.appId?.trim()&&n.appSecret?.trim());return{accountId:n.accountId,name:n.name,enabled:n.enabled,configured:r,tokenSource:n.tokenSource,running:e?.running??!1,lastStartAt:e?.lastStartAt??null,lastStopAt:e?.lastStopAt??null,lastError:e?.lastError??null,mode:"websocket",botType:t,lastInboundAt:e?.lastInboundAt??null,lastOutboundAt:e?.lastOutboundAt??null,dmPolicy:"pairing",appId:n.appId?`${n.appId.slice(0,8)}...`:void 0}}G();var go={id:"Lansenger",label:"Lansenger",selectionLabel:"Lansenger (\u84DD\u4FE1)",docsPath:"/channels/Lansenger",docsLabel:"Lansenger",blurb:"\u84DD\u4FE1\u6D88\u606F\u5E73\u53F0\uFF0C\u652F\u6301Bot API\u3002",aliases:[],order:85,quickstartAllowFrom:!0},bn={id:"Lansenger",capabilities:{chatTypes:["direct","group"],media:!0,blockStreaming:!0},outbound:{textChunkLimit:4e3},config:{resolveAllowFrom:({cfg:n,accountId:e})=>(P({cfg:n,accountId:e}).config.allowFrom??[]).map(t=>String(t)),formatAllowFrom:({allowFrom:n})=>n.map(e=>String(e).trim()).filter(Boolean).map(e=>e.replace(/^(Lansenger|lark|fs):/i,"")).map(e=>e.toLowerCase())},groups:{resolveRequireMention:()=>!0},threading:{resolveReplyToMode:()=>"off"}},Oe=new Qe;Oe.registerSkill("message",new Le);Oe.registerSkill("calendar",new Ne);Oe.registerSkill("meeting",new De);var ct={id:"Lansenger",meta:go,allowOrphanedConfig:!0,onboarding:un,capabilities:{chatTypes:["direct","group"],media:!0,reactions:!1,threads:!1,polls:!1,nativeCommands:!1,blockStreaming:!0},reload:{configPrefixes:["channels.Lansenger"]},configSchema:{schema:{type:"object",properties:{enabled:{type:"boolean",default:!0},credentials:{type:"object",properties:{name:{type:"string"},appId:{type:"string"},appSecret:{type:"string"},apiGatewayUrl:{type:"string"}}},conversation:{type:"object",properties:{allowFrom:{type:"array",items:{type:"string"}},requireMention:{type:"boolean",default:!0},requirePrefix:{type:"string"},isolateContextPerUserInGroup:{type:"boolean",default:!1}}},reply:{type:"object",properties:{replyMode:{type:"string",enum:["text","markdown"],default:"markdown"},maxChars:{type:"number",default:4e3}}},connection:{type:"object",properties:{apiBase:{type:"string"},apiGatewayUrl:{type:"string"},apiGatewayWssUrl:{type:"string"}}},testMode:{type:"object",properties:{enabled:{type:"boolean",default:!1}}}},additionalProperties:!0},uiHints:{enabled:{label:"\u542F\u7528\u84DD\u4FE1\u6E20\u9053",help:"\u603B\u5F00\u5173\u3002\u5173\u95ED\u540E\u8BE5\u8D26\u53F7\u4E0D\u63A5\u6536\u6D88\u606F\u4E5F\u4E0D\u53D1\u9001\u56DE\u590D\u3002",order:10},credentials:{label:"1. \u63A5\u5165\u51ED\u636E",help:"\u5148\u5B8C\u6210\u673A\u5668\u4EBA\u51ED\u636E\u914D\u7F6E\uFF0C\u518D\u7EE7\u7EED\u914D\u7F6E\u6D88\u606F\u884C\u4E3A\u3002",order:20},"credentials.name":{label:"\u8D26\u53F7\u663E\u793A\u540D\u79F0",help:"\u7528\u4E8E\u591A\u8D26\u53F7\u573A\u666F\u4E0B\u7684\u8BC6\u522B\u540D\u79F0\uFF08\u53EF\u9009\uFF09\u3002",order:10},"credentials.appId":{label:"App ID",help:"\u84DD\u4FE1\u5E94\u7528\u7684 App ID\u3002\u53EF\u5728\u5F00\u53D1\u8005\u540E\u53F0\u67E5\u770B\u3002",placeholder:"3417088-3744000",order:20},"credentials.appSecret":{label:"App Secret",help:"\u84DD\u4FE1\u5E94\u7528\u5BC6\u94A5\u3002",sensitive:!0,order:30},"credentials.apiGatewayUrl":{label:"API \u7F51\u5173\u5730\u5740",help:"\u84DD\u4FE1\u5F00\u653E\u5E73\u53F0 API \u7F51\u5173\u5730\u5740\u3002",advanced:!0,order:40},conversation:{label:"2. \u4F1A\u8BDD\u89E6\u53D1\u4E0E\u6743\u9650",help:"\u63A7\u5236\u54EA\u4E9B\u6D88\u606F\u4F1A\u89E6\u53D1\u673A\u5668\u4EBA\u3002",order:30},"conversation.allowFrom":{label:"\u5141\u8BB8\u53D1\u9001\u8005\u5217\u8868",help:"\u4EC5\u5141\u8BB8\u5217\u8868\u5185\u7528\u6237\u89E6\u53D1\uFF08\u7559\u7A7A\u8868\u793A\u5141\u8BB8\u6240\u6709\u7528\u6237\uFF09\u3002",advanced:!0,order:10},"conversation.requireMention":{label:"\u7FA4\u804A\u8981\u6C42 @\u673A\u5668\u4EBA",help:"\u5F00\u542F\u540E\uFF0C\u7FA4\u804A\u91CC\u9700\u8981 @ \u673A\u5668\u4EBA\u624D\u4F1A\u54CD\u5E94\u3002",advanced:!0,order:20},"conversation.requirePrefix":{label:"\u7FA4\u804A\u89E6\u53D1\u524D\u7F00",help:"\u8BBE\u7F6E\u540E\u4EC5\u54CD\u5E94\u4EE5\u6B64\u524D\u7F00\u5F00\u5934\u7684\u6D88\u606F\u3002",advanced:!0,order:30},"conversation.isolateContextPerUserInGroup":{label:"\u7FA4\u804A\u6309\u7528\u6237\u9694\u79BB\u4E0A\u4E0B\u6587",help:"\u5F00\u542F\u540E\u540C\u4E00\u7FA4\u5185\u6BCF\u4E2A\u7528\u6237\u62E5\u6709\u72EC\u7ACB\u4F1A\u8BDD\u4E0A\u4E0B\u6587\u3002",advanced:!0,order:40},reply:{label:"3. \u56DE\u590D\u7B56\u7565",help:"\u8BBE\u7F6E\u56DE\u590D\u683C\u5F0F\u3001\u6587\u672C\u957F\u5EA6\u9650\u5236\u3002",order:40},"reply.replyMode":{label:"\u56DE\u590D\u6A21\u5F0F",help:"text \u7EAF\u6587\u672C / markdown \u5BCC\u6587\u672C",order:10},"reply.maxChars":{label:"\u5355\u6761\u6D88\u606F\u6700\u5927\u957F\u5EA6",help:"\u8D85\u8FC7\u81EA\u52A8\u62C6\u5206",order:20},connection:{label:"4. \u8FDE\u63A5\u4E0E\u7F51\u5173",help:"\u9AD8\u7EA7\u8FDE\u63A5\u53C2\u6570\uFF0C\u9ED8\u8BA4\u5373\u53EF\u3002",order:50},"connection.apiBase":{label:"API \u57FA\u7840\u5730\u5740",advanced:!0,order:10},"connection.apiGatewayUrl":{label:"API \u7F51\u5173\u5730\u5740",help:"\u84DD\u4FE1\u5F00\u653E\u5E73\u53F0 API \u7F51\u5173\u5730\u5740\u3002",advanced:!0,order:20},"connection.apiGatewayWssUrl":{label:"API WebSocket \u7F51\u5173\u5730\u5740",help:"\u84DD\u4FE1\u5F00\u653E\u5E73\u53F0 WebSocket \u7F51\u5173\u5730\u5740\uFF0C\u4F18\u5148\u4F7F\u7528\uFF0C\u672A\u914D\u7F6E\u5219\u4F7F\u7528 API \u7F51\u5173\u5730\u5740\u7684 wss \u534F\u8BAE\u3002",advanced:!0,order:30},testMode:{label:"5. \u6D4B\u8BD5\u6A21\u5F0F",help:"\u5F00\u542F\u540E\uFF0C\u63A5\u6536\u5230\u7684\u6D88\u606F\u5C06\u76F4\u63A5\u53D1\u9001\u5230 staffId \u7684\u79C1\u804A\uFF0C\u7528\u4E8E\u6D4B\u8BD5\u6D88\u606F\u63A5\u6536\u529F\u80FD\u3002",order:60},"testMode.enabled":{label:"\u542F\u7528\u6D4B\u8BD5\u6A21\u5F0F",help:"\u5F00\u542F\u540E\uFF0C\u63A5\u6536\u5230\u7684\u6D88\u606F\u5C06\u76F4\u63A5\u53D1\u9001\u5230 staffId \u7684\u79C1\u804A\uFF0C\u8DF3\u8FC7 OpenClaw \u5904\u7406\u3002",advanced:!0,order:10}}},config:{listAccountIds:n=>ee(n),resolveAccount:(n,e)=>P({cfg:n,accountId:e}),defaultAccountId:n=>Be(n),setAccountEnabled:({cfg:n,accountId:e,enabled:t})=>Vt({cfg:n,sectionKey:"Lansenger",accountId:e,enabled:t,allowTopLevel:!0}),deleteAccount:({cfg:n,accountId:e})=>Kt({cfg:n,sectionKey:"Lansenger",accountId:e,clearBaseFields:["appId","appSecret","name"]}),isConfigured:n=>!!(n.appId?.trim()&&n.appSecret?.trim()),describeAccount:n=>({accountId:n.accountId,name:n.name,enabled:n.enabled,configured:!!(n.appId?.trim()&&n.appSecret?.trim()),tokenSource:n.tokenSource}),resolveAllowFrom:({cfg:n,accountId:e})=>(P({cfg:n,accountId:e}).config.allowFrom??[]).map(t=>String(t)),formatAllowFrom:({allowFrom:n})=>n.map(e=>String(e).trim()).filter(Boolean).map(e=>e.replace(/^(Lansenger|lark|fs):/i,"")).map(e=>e.toLowerCase()),updateConfig:({cfg:n,updates:e})=>e?.openStaffId&&e?.accountId?ye({cfg:n,accountId:e.accountId,staffId:e.openStaffId}):n},security:{resolveDmPolicy:({cfg:n,accountId:e,account:t})=>{i.info("Resolving DM policy",{accountId:e,account:t});let r=e??t.accountId??_,a=!!n.channels?.Lansenger?.accounts?.[r]?`channels.Lansenger.accounts.${r}.`:"channels.Lansenger.",s={policy:t.config.dmPolicy??"pairing",allowFrom:t.config.allowFrom??[],policyPath:`${a}dmPolicy`,allowFromPath:a,approveHint:Yt("Lansenger"),normalizeEntry:c=>c.replace(/^(Lansenger|lark|fs):/i,"")};return i.info("Resolved DM policy",{dmPolicy:s}),s}},groups:{resolveRequireMention:()=>!0},threading:{resolveReplyToMode:()=>"off"},messaging:{normalizeTarget:gn,targetResolver:{looksLikeId:n=>{let e=n.trim();return e?/^(oc|ou|on)_[a-f0-9]+$/i.test(e)||/^[a-f0-9]{20,}$/i.test(e):!1},hint:"<chatId>"}},directory:{self:async()=>null,listPeers:async({cfg:n,accountId:e,query:t,limit:r})=>{let o=P({cfg:n,accountId:e}),a=t?.trim().toLowerCase()||"";return Array.from(new Set((o.config.allowFrom??[]).map(c=>String(c).trim()).filter(c=>!!c&&c!=="*").map(c=>c.replace(/^(Lansenger|lark|fs):/i,"")))).filter(c=>a?c.toLowerCase().includes(a):!0).slice(0,r&&r>0?r:void 0).map(c=>({kind:"user",id:c}))},listGroups:async()=>[]},setup:{resolveAccountId:({accountId:n})=>fe(n),applyAccountName:({cfg:n,accountId:e,name:t})=>Re({cfg:n,channelKey:"Lansenger",accountId:e,name:t}),validateInput:({accountId:n,input:e})=>null,applyAccountConfig:({cfg:n,accountId:e,input:t})=>St({cfg:n,accountId:e,input:t})},pairing:{idLabel:"LansengerUserId",normalizeAllowEntry:n=>n.replace(/^(Lansenger|lark|fs):/i,""),getSessionByCode:async n=>{try{return ot().getSessionByCode(n)}catch(e){i.error("Error getting session by code:",e);return}},notifyApproval:async({cfg:n,id:e})=>{i.info(`[Lansenger] notifyApproval method called with parameters: id=${e}`);let t=P({cfg:n});if(!t.appId||!t.appSecret)throw new Error("Lansenger credentials not configured");let r=xe(t);await H(r,t.config,e,Qt,{hookToken:t.config.hookToken,isGroup:e.startsWith("oc_")})}},outbound:{deliveryMode:"direct",chunker:(n,e)=>(i.debug(`[Lansenger] chunker method called with parameters: text=${n.slice(0,80)}, limit=${e}`),hn(n,e)),chunkerMode:"text",textChunkLimit:4e3,sendText:async({to:n,text:e,accountId:t,cfg:r})=>kn({to:n,text:e,accountId:t,cfg:r}),sendMedia:async({to:n,text:e,mediaUrl:t,accountId:r,cfg:o})=>yn({to:n,text:e,mediaUrl:t,accountId:r,cfg:o}),push:async({to:n,text:e,accountId:t,cfg:r,log:o})=>wn({to:n,text:e,accountId:t,cfg:r,log:o})},status:{defaultRuntime:In,collectStatusIssues:fn,buildChannelSummary:Tn,probeAccount:xn,buildAccountSnapshot:$n},gateway:{startAccount:async n=>{let e=n.account,t="";n.log&&i.setOpenClawLog({info:a=>n.log?.info(a),error:a=>n.log?.error(a),debug:a=>n.log?.debug?.(a)});try{let a=xe(e),s;a==="webhook"?s=await it(e.config.hookToken||"",3e3,e.config.apiGatewayUrl):s=await st(e.appId,e.appSecret,3e3,e.config.apiGatewayUrl),s.ok&&(t=` (${a} bot)`),n.setStatus({accountId:e.accountId,bot:{name:`${a} bot`}})}catch{}Oe.initializeSkills(e);let o=(await gr({account:e,config:n.cfg,log:{info:a=>n.log?.info(a),error:a=>n.log?.error(a),debug:a=>n.log?.debug?.(a)},abortSignal:n.abortSignal,statusSink:a=>n.setStatus({accountId:n.accountId,...a})})).stop;return{stop:()=>{o(),Oe.shutdownSkills(),n.log?.info(`[${e.accountId}] Shutdown skills`)}}}}};wt();var mo={id:"openclaw-channel-lansenger",name:"Lansenger",description:"Lansenger (\u84DD\u4FE1) channel plugin \u2014 WebSocket long-connection bot",configSchema:Jt(),register(n){ue.init(n.runtime),_e(n.runtime),ue.isUsingNewSdk()?n.registerChannel(ct):n.registerChannel({plugin:ct,dock:bn})},plugin:ct,setRuntime:_e},ho=ue.createPluginEntry(mo),ml=ho;export{ml as default};
|
|
35
|
+
\u8BF7\u4F7F\u7528 /lanxin help \u67E5\u770B\u53EF\u7528\u547D\u4EE4\u3002`}}else await t()}}},Ct=nt.create()});var sn=y(()=>{u();tn();nn();on();an()});function ot(n){return new jt}var jt,cn=y(()=>{u();G();jt=class{pairingData;constructor(){this.pairingData={pairingRequests:{},approvedUsers:[],lastUpdated:new Date().toISOString()},i.debug("Initialized PairingManager with in-memory storage")}generatePairingCode(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",t="";for(let r=0;r<8;r++)t+=e.charAt(Math.floor(Math.random()*e.length));return i.debug("Generated new pairing code",{code:t}),t}getExistingPairingCode(e){i.debug("Checking for existing pairing code",{identifier:e});for(let t in this.pairingData.pairingRequests){let r=this.pairingData.pairingRequests[t];if(r.staffId===e||r.userId===e){let o=new Date(r.createdAt),s=(new Date().getTime()-o.getTime())/(1e3*60*60);if(s<=1)return i.debug("Found existing valid pairing code",{identifier:e,code:t,diffInHours:s}),t;i.debug("Found existing but expired pairing code",{identifier:e,code:t,diffInHours:s}),delete this.pairingData.pairingRequests[t],this.pairingData.lastUpdated=new Date().toISOString()}}return i.debug("No existing valid pairing code found",{identifier:e}),null}storePairingRequest(e,t,r){i.info("Storing pairing request",{code:e,userId:t,staffId:r}),i.info("Current pairingRequests before storing:",Object.keys(this.pairingData.pairingRequests)),this.pairingData.pairingRequests[e]={code:e,userId:t,staffId:r,createdAt:new Date().toISOString()},this.pairingData.lastUpdated=new Date().toISOString(),i.info("Pairing request stored in memory:",this.pairingData.pairingRequests[e]),i.info("Pairing request stored successfully",{code:e,userId:t,staffId:r})}getPairingRequest(e){i.debug("Getting pairing request",{code:e});let t=this.pairingData.pairingRequests[e];if(!t)return i.debug("No pairing request found",{code:e}),null;let r=new Date(t.createdAt),a=(new Date().getTime()-r.getTime())/(1e3*60*60);return a>1?(i.debug("Pairing request expired",{code:e,diffInHours:a}),delete this.pairingData.pairingRequests[e],this.pairingData.lastUpdated=new Date().toISOString(),null):(i.debug("Found valid pairing request",{code:e,staffId:t.staffId}),t)}approveUser(e){i.debug("Approving user",{staffId:e}),this.pairingData.approvedUsers.includes(e)?i.debug("User already in approved list",{staffId:e}):(i.debug("Adding user to approved list",{staffId:e}),this.pairingData.approvedUsers.push(e),this.pairingData.lastUpdated=new Date().toISOString(),i.debug("User added to approved list successfully",{staffId:e,approvedUsers:this.pairingData.approvedUsers}))}isUserApproved(e){try{i.debug("Checking if user is approved",{staffId:e});let t=this.pairingData.approvedUsers.includes(e);return i.debug("User approval status",{staffId:e,isApproved:t,approvedUsers:this.pairingData.approvedUsers}),t}catch(t){return i.error("Error checking if user is approved",{error:t,staffId:e}),!1}}removePairingRequest(e){delete this.pairingData.pairingRequests[e],this.pairingData.lastUpdated=new Date().toISOString()}approvePairingRequest(e){i.debug("Approving pairing request",{code:e});let t=this.getPairingRequest(e);return t?(i.debug("Pairing request found, approving user",{code:e,staffId:t.staffId}),this.approveUser(t.staffId),this.removePairingRequest(e),i.debug("Pairing request approved successfully",{code:e,staffId:t.staffId}),!0):(i.debug("Pairing request not found or expired",{code:e}),!1)}getSessionByCode(e){i.debug("Getting session by code",{code:e});let t=this.getPairingRequest(e);return t?(i.debug("Found session for code",{code:e,staffId:t.staffId}),{staffId:t.staffId}):(i.debug("No session found for code",{code:e}),null)}}});function Ar(n){let e=Date.now();for(let[t,r]of at)e-r>6e5&&at.delete(t);return n?at.has(n)?!0:(at.set(n,e),!1):!1}var at,ln=y(()=>{u();at=new Map});function Cr(n,e,t){if(e.length>0)return!0;let r=n.toLowerCase();if(/[??]$/.test(n)||/\b(why|how|what|when|where|who|help)\b/.test(r)||["\u5E2E","\u9EBB\u70E6","\u8BF7","\u80FD\u5426","\u53EF\u4EE5","\u89E3\u91CA","\u770B\u770B","\u6392\u67E5","\u5206\u6790","\u603B\u7ED3","\u5199","\u6539","\u4FEE","\u67E5","\u5BF9\u6BD4","\u7FFB\u8BD1"].some(c=>n.includes(c)))return!0;let a=t?.length?t:ho;return!!new RegExp(`^(${a.map(ko).join("|")})[\\s,:\uFF0C\uFF1A]`,"i").test(n)}function ko(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var ho,dn=y(()=>{u();ho=["clawdbot","moltbot","bot","\u52A9\u624B","\u667A\u80FD\u4F53"]});var qt,Te,pn=y(()=>{u();qt=class{staffIdCache=new Map;staffInfoCache=new Map;setStaffId(e,t){this.staffIdCache.set(e,t)}getStaffId(e){return this.staffIdCache.get(e)}setStaffInfo(e,t){this.staffInfoCache.set(e,t)}getStaffInfo(e){return this.staffInfoCache.get(e)}clearStaffId(e){this.staffIdCache.delete(e),this.staffInfoCache.delete(e)}clearAll(){this.staffIdCache.clear(),this.staffInfoCache.clear()}},Te=new qt});async function st(n,e,t=5e3,r){if(!n?.trim()||!e?.trim())return i.warn("Missing appId or appSecret for Lanxin probe"),{ok:!1,error:"Missing appId or appSecret",elapsedMs:0};let o=Date.now(),a=new AbortController,s=setTimeout(()=>a.abort(),t),c=N(r);try{let l=x.auth.appToken,d=new URLSearchParams({grant_type:"client_credential",appid:n.trim(),secret:e.trim()}),p=await fetch(`${c}${l}?${d.toString()}`,{method:"GET",headers:{"Content-Type":"application/json"},signal:a.signal});clearTimeout(s);let f=Date.now()-o;if(!p.ok){let m=`HTTP ${p.status}: ${p.statusText}`;return i.error(m,{url:`${c}${l}`,status:p.status}),{ok:!1,error:m,elapsedMs:f}}let g=await p.json();if(g.errCode!==0){let m=g.errMsg||`API error code: ${g.errCode}`;return i.error("Lanxin API probe error",{errCode:g.errCode,errMsg:m}),{ok:!1,error:m,elapsedMs:f}}if(!g.data?.appToken){let m="No appToken returned";return i.error("Lanxin API probe error",{errMsg:m}),{ok:!1,error:m,elapsedMs:f}}return{ok:!0,elapsedMs:f}}catch(l){clearTimeout(s);let d=Date.now()-o;if(l instanceof Error){if(l.name==="AbortError"){let f=`Request timed out after ${t}ms`;return i.warn(f),{ok:!1,error:f,elapsedMs:d}}return i.error("Error probing Lanxin API",{error:l.message}),{ok:!1,error:l.message,elapsedMs:d}}let p=String(l);return i.error("Error probing Lanxin API",{error:p}),{ok:!1,error:p,elapsedMs:d}}}async function it(n,e=5e3,t){if(!n?.trim())return i.warn("Missing hookToken for webhook bot probe"),{ok:!1,error:"Missing hookToken",elapsedMs:0};let r=Date.now(),o=new AbortController,a=setTimeout(()=>o.abort(),e);try{if(i.debug("Probing webhook bot",{hookToken:n.slice(0,10)+"..."}),n.length<10)return i.warn("Invalid hookToken format",{length:n.length}),{ok:!1,error:"Invalid hookToken format",elapsedMs:Date.now()-r};clearTimeout(a);let s=Date.now()-r;return i.info("Webhook bot probe successful",{elapsedMs:s}),{ok:!0,elapsedMs:s}}catch(s){clearTimeout(a);let c=Date.now()-r;if(s instanceof Error){if(s.name==="AbortError"){let d=`Request timed out after ${e}ms`;return i.warn(d),{ok:!1,error:d,elapsedMs:c}}return i.error("Error probing webhook bot",{error:s.message}),{ok:!1,error:s.message,elapsedMs:c}}let l=String(s);return i.error("Error probing webhook bot",{error:l}),{ok:!1,error:l,elapsedMs:c}}}var un=y(()=>{u();Q();z();G()});var fn=y(()=>{u();Z();Q();G()});var Ht,Ac,gn=y(()=>{u();Ht=class{sessions=new Map;staffIdToCode=new Map;constructor(){}generateCode(){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",t="";for(let r=0;r<6;r++)t+=e.charAt(Math.floor(Math.random()*e.length));return t}createSession(e,t){let r=this.generateCode(),o={code:r,staffId:t,createdAt:Date.now(),accountId:e};return this.sessions.set(r,o),this.staffIdToCode.set(`${e}:${t}`,r),o}getSessionByCode(e){return this.sessions.get(e)}getSessionByStaffId(e,t){let r=this.staffIdToCode.get(`${e}:${t}`);if(r)return this.sessions.get(r)}deleteSession(e){let t=this.sessions.get(e);t&&(this.staffIdToCode.delete(`${t.accountId}:${t.staffId}`),this.sessions.delete(e))}clearSessions(e){for(let[t,r]of this.sessions.entries())r.accountId===e&&(this.staffIdToCode.delete(`${e}:${r.staffId}`),this.sessions.delete(t))}clearAllSessions(){this.sessions.clear(),this.staffIdToCode.clear()}},Ac=new Ht});var mn=y(()=>{u();G();ln();dn();He();pn();Z();un();fn();gn()});var L=y(()=>{u();z();Pr();qr();Kr();Q();en();sn();cn();Ke();Ge();$t();mn()});u();mt();ge();u();ge();u();ge();function On(n){let e=n.channels?.Lansenger?.accounts;return!e||typeof e!="object"?[]:Object.keys(e).filter(Boolean)}function te(n){let e=On(n);return e.length===0?[F]:e.sort((t,r)=>t.localeCompare(r))}function Be(n){let e=n.channels?.Lansenger;if(e?.defaultAccount?.trim())return e.defaultAccount.trim();let t=te(n);return t.includes(F)?F:t[0]??F}function Dn(n,e){let t=n.channels?.Lansenger?.accounts;if(!(!t||typeof t!="object"))return t[e]}function _n(n,e){let t=n.channels?.Lansenger??{},{accounts:r,defaultAccount:o,...a}=t,s=Dn(n,e)??{};return{...a,...s}}function Bn(n,e){if(e.credentials?.appId?.trim()&&e.credentials?.appSecret?.trim())return{appId:e.credentials.appId.trim(),appSecret:e.credentials.appSecret.trim(),source:"config"};if(e.appId?.trim()&&e.appSecret?.trim())return{appId:e.appId.trim(),appSecret:e.appSecret.trim(),source:"config"};let r=n.plugins?.entries?.Lansenger?.config;return r?.appId?.trim()&&r?.appSecret?.trim()?{appId:r.appId.trim(),appSecret:r.appSecret.trim(),source:"plugin"}:{appId:"",appSecret:"",source:"none"}}function P(n){let e=fe(n.accountId),t=n.cfg.channels?.Lansenger?.enabled!==!1,r=_n(n.cfg,e),o=r.enabled!==!1,a=t&&o,s=Bn(n.cfg,r);return{accountId:e,name:r.name?.trim()||void 0,enabled:a,appId:s.appId,appSecret:s.appSecret,tokenSource:s.source,config:r,agentId:r.agentId||"default"}}u();L();ge();function yo(n,e){let t=n.channels?.lanxin??{};i.info("Setting DM policy",{dmPolicy:e});let r=Array.isArray(t.allowFrom)?t.allowFrom:[],o=e==="open"?ar(r):void 0,a={...n,channels:{...n.channels??{},lanxin:{...t,dmPolicy:e,...o?{allowFrom:o}:{}}}};return i.info("Updated DM policy",{clawdbotCfg:a}),a}async function hn(n){await n.note(["1) Go to https://open.lanxin.cn/app \u2192 Create self-built app","2) Add Bot capability to the app","3) Enable permissions: im:message, im:message.group_at_msg, im:message.p2p_msg",'4) Events: add im.message.receive_v1, set delivery to "WebSocket long-connection"',"5) Publish the app (create version \u2192 request approval)","6) Note the App ID (cli_xxx) and App Secret","","Docs: https://open.lanxin.cn/document/home/index"].join(`
|
|
36
|
+
`),"Lanxin Bot Setup")}async function kn(n){let{cfg:e,prompter:t,accountId:r}=n,a=P({cfg:e,accountId:r}).config.allowFrom??[],s=await t.text({message:"Lanxin allowFrom (open_id or union_id)",placeholder:"ou_xxxxxxxxxx",initialValue:a[0]?String(a[0]):void 0,validate:m=>{if(!String(m??"").trim())return"Required"}}),c=String(s).trim(),l=[...a.map(m=>String(m).trim()).filter(Boolean),c],d=[...new Set(l)],p=e.channels?.lanxin??{},f=p.accounts??{};if(r===F)return{...e,channels:{...e.channels??{},lanxin:{...p,enabled:!0,dmPolicy:"allowlist",allowFrom:d}}};let g=f[r]??{};return{...e,channels:{...e.channels??{},lanxin:{...p,enabled:!0,accounts:{...f,[r]:{...g,enabled:g.enabled??!0,dmPolicy:"allowlist",allowFrom:d}}}}}}var yn={configuredCheck:n=>te(n).some(e=>!!P({cfg:n,accountId:e}).appId),setDmPolicy:(n,e)=>yo(n,e),promptAllowFrom:async n=>kn(n),noteSetupHelp:async n=>hn(n),runSetupWizard:async n=>{let{cfg:e,prompter:t,accountOverrides:r,shouldPromptAccountIds:o,forceAllowFrom:a,token:s,dmAllowlist:c}=n,l=(k,w)=>{if(/[<>"'&]/.test(k))throw new Error(`Invalid ${w}: Special characters are not allowed`)};s&&l(s,"token"),c&&l(c,"dmAllowlist");let d=r?.lanxin?.trim();d&&l(d,"accountId"),i.info("Running setup wizard",{cfg:e,accountOverrides:r,shouldPromptAccountIds:o,forceAllowFrom:a,token:s,dmAllowlist:c});let p=Be(e),f=d?fe(d):p;if(i.info("Selected Lanxin account",{lanxinAccountId:f}),o&&!d){let w=te(e).map(S=>({value:S,label:S}));f=await t.select({message:"Select Lanxin account",options:w,initialValue:f})}let g=e,m=P({cfg:g,accountId:f});!!m.appId||await hn(t);let v=!!(m.config.appId&&m.config.appSecret),b=null,D=null;if(s){let[k,w]=s.split(":");k&&w&&(b=k.trim(),D=w.trim())}else v&&t.confirm?await t.confirm({message:"Lanxin credentials already configured. Keep them?",initialValue:!0})||(b=String(await t.text({message:"Enter Lanxin App ID (cli_xxx)",validate:w=>String(w??"").trim()?void 0:"Required"})).trim(),D=String(await t.text({message:"Enter Lanxin App Secret",validate:w=>String(w??"").trim()?void 0:"Required"})).trim()):v||(b=String(await t.text({message:"Enter Lanxin App ID (cli_xxx)",validate:k=>String(k??"").trim()?void 0:"Required"})).trim(),D=String(await t.text({message:"Enter Lanxin App Secret",validate:k=>String(k??"").trim()?void 0:"Required"})).trim());if(c){i.info(`[lanxin] Processing dm-allowlist: ${c}`);let k=ot(f),w=k.getPairingRequest(c);if(w){if(i.info(`[lanxin] Found pairing request for code: ${c}, staffId: ${w.staffId}`),k.approvePairingRequest(c)){i.info(`[lanxin] Successfully approved pairing request for staffId: ${w.staffId}`);let M=g.channels?.lanxin??{},j=M.accounts??{};if(f===F){let B=[...Array.isArray(M.allowFrom)?M.allowFrom:[],w.staffId];g={...g,channels:{...g.channels??{},lanxin:{...M,allowFrom:B}}}}else{let _=j[f]??{},q=[...Array.isArray(_.allowFrom)?_.allowFrom:[],w.staffId];g={...g,channels:{...g.channels??{},lanxin:{...M,accounts:{...j,[f]:{..._,allowFrom:q}}}}}}}}else i.error(`[lanxin] No pairing request found for code: ${c}`)}let T=g.channels?.lanxin??{},$=T.accounts??{};if(b&&D)if(f===F)g={...g,channels:{...g.channels??{},lanxin:{...T,enabled:!0,appId:b,appSecret:D,approval:{enabled:!0,highRiskTools:"write,delete,trash,rm"}}}};else{let k=$[f]??{};g={...g,channels:{...g.channels??{},lanxin:{...T,enabled:!0,accounts:{...$,[f]:{...k,enabled:!0,appId:b,appSecret:D,approval:{enabled:!0,highRiskTools:"write,delete,trash,rm"}}}}}}}return a&&(g=await kn({cfg:g,prompter:t,accountId:f})),g}};u();var wo=n=>!!(n&&typeof n=="object"),To=n=>typeof n=="string"?n:typeof n=="number"?String(n):void 0;function Io(n){return wo(n)?{accountId:n.accountId,enabled:n.enabled,configured:n.configured,dmPolicy:n.dmPolicy,appId:n.appId}:null}function wn(n){let e=[];for(let t of n){let r=Io(t);if(!r)continue;let o=To(r.accountId)??"default",a=r.enabled!==!1,s=r.configured===!0;a&&!s&&e.push({channel:"lanxin",accountId:o,level:"warning",message:"Lanxin account is enabled but not configured (missing appId or appSecret).",action:"Set channels.lanxin.appId and channels.lanxin.appSecret in clawdbot.json."}),a&&s&&r.dmPolicy==="open"&&e.push({channel:"lanxin",accountId:o,level:"warning",message:'Lanxin dmPolicy is "open", allowing any user to message the bot without pairing.',action:'Set channels.lanxin.dmPolicy to "pairing" or "allowlist" to restrict access.'})}return e}ze();u();function Tn(n){let e=n?.trim();if(e)return e.replace(/^(lanxin):/i,"")}function xe(n){return n.config.botType??"smart"}u();L();ze();var In=new Map;function zt(n,e){In.set(n,e),i.info(`[lanxin] Set staffId ${n} to accountId ${e} mapping`)}function xo(n){return In.get(n)}function Jt(n,e){let t=xo(e);if(t){let a=P({cfg:n,accountId:t});if(a.appId)return a}let r=te(n);for(let a of r){let s=P({cfg:n,accountId:a});if(s.appId&&s.config.openStaffId===e)return zt(e,a),s}for(let a of r){let s=P({cfg:n,accountId:a});if(s.appId)return zt(e,a),ye({cfg:n,accountId:a,staffId:e}),s}let o=P({cfg:n});return o.appId?(zt(e,o.accountId),ye({cfg:n,accountId:o.accountId,staffId:e}),o):null}function xn(n,e){if(!n)return[];if(e<=0||n.length<=e)return[n];let t=[],r=n;for(;r.length>e;){let o=r.slice(0,e),a=o.lastIndexOf(`
|
|
37
|
+
`),s=o.lastIndexOf(" "),c=a>0?a:s;c<=0&&(c=e);let d=r.slice(0,c).trimEnd();d.length>0&&t.push(d);let p=c<r.length&&/\s/.test(r[c]),f=Math.min(r.length,c+(p?1:0));r=r.slice(f).trimStart()}return r.length&&t.push(r),t}async function bn({to:n,text:e,accountId:t,cfg:r}){i.info(`[lanxin] sendText method called with parameters: to=${n}, accountId=${t}, text=${e.slice(0,80)}`);let o;if(t)o=P({accountId:t??void 0,cfg:r});else{let s=Jt(r,n);if(!s)return i.error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E"),{channel:"lanxin",ok:!1,messageId:"",error:new Error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E")};o=s}if(!o.appId)return i.error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E"),{channel:"lanxin",ok:!1,messageId:"",error:new Error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E")};i.info(`[lanxin] Using account ${o.accountId} (appId: ${o.appId.slice(0,8)}...) for staffId ${n}`);let a=await he(o.config,n,e,n.startsWith("oc_"));return{channel:"lanxin",ok:a.ok,messageId:a.messageId??"",error:a.error?new Error(a.error):void 0}}async function $n({to:n,text:e,mediaUrl:t,accountId:r,cfg:o}){i.debug(`[lanxin] sendMedia method called with parameters: to=${n}, accountId=${r}, text=${e.slice(0,80)}`);let a;if(r)a=P({accountId:r??void 0,cfg:o});else{let l=Jt(o,n);if(!l)return i.error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E"),{channel:"lanxin",ok:!1,messageId:"",error:new Error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E")};a=l}if(!a.appId)return i.error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E"),{channel:"lanxin",ok:!1,messageId:"",error:new Error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E")};i.info(`[lanxin] Using account ${a.accountId} (appId: ${a.appId.slice(0,8)}...) for staffId ${n}`);let s={text:e||"",mediaUrl:t},c=await he(a.config,n,s,n.startsWith("oc_"));return{channel:"lanxin",ok:c.ok,messageId:c.messageId??"",error:c.error?new Error(c.error):void 0}}async function Sn({to:n,text:e,accountId:t,cfg:r,log:o}){i.debug(`[lanxin] Push method called with parameters: to=${n}, accountId=${t}, text=${e.slice(0,80)}`);try{let a;if(t)a=P({accountId:t??void 0,cfg:r});else{let d=Jt(r,n);if(!d)return i.error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E"),{channel:"lanxin",ok:!1,messageId:"",error:new Error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E")};a=d}if(i.debug(`[lanxin] Resolved account: ${a.accountId}, appId: ${a.appId?.slice(0,8)}...`),!a.appId)return i.error(`[lanxin] No appId found for account ${a.accountId}`),{channel:"lanxin",ok:!1,messageId:"",error:new Error("\u84DD\u4FE1\u51ED\u636E\u672A\u914D\u7F6E")};i.info(`[lanxin] Using account ${a.accountId} (appId: ${a.appId.slice(0,8)}...) for staffId ${n}`),(o||{info:d=>i.info(`[lanxin:${a.accountId}] ${d}`),error:d=>i.error(`[lanxin:${a.accountId}] ${d}`),debug:d=>i.debug(`[lanxin:${a.accountId}] ${d}`)}).info(`[lanxin:${a.accountId}] Received OpenClaw push notification: to=${n}, text=${e.slice(0,80)}`),i.debug(`[lanxin:${a.accountId}] Calling processAndSendMessage`);let l=await he(a.config,n,e,n.startsWith("oc_"));return i.debug(`[lanxin:${a.accountId}] processAndSendMessage result: ok=${l.ok}, messageId=${l.messageId}, error=${l.error}`),{channel:"lanxin",ok:l.ok,messageId:l.messageId??"",error:l.error?new Error(l.error):void 0}}catch(a){return i.error(`[lanxin] Error in push method: ${a instanceof Error?a.message:String(a)}`),{channel:"lanxin",ok:!1,messageId:"",error:new Error(a instanceof Error?a.message:String(a))}}}u();L();var vn={accountId:"default",running:!1,lastStartAt:null,lastStopAt:null,lastError:null};function An({snapshot:n}){return{configured:n.configured??!1,tokenSource:n.tokenSource??"none",running:n.running??!1,mode:n.mode??"websocket",lastStartAt:n.lastStartAt??null,lastStopAt:n.lastStopAt??null,lastError:n.lastError??null,probe:n.probe,lastProbeAt:n.lastProbeAt??null}}async function Cn({account:n,timeoutMs:e}){return xe(n)==="webhook"?it(n.config.hookToken||"",e,n.config.apiGatewayUrl):st(n.appId,n.appSecret,e,n.config.apiGatewayUrl)}function Mn({account:n,runtime:e}){let t=xe(n),r=t==="webhook"?!!n.config.hookToken?.trim():!!(n.appId?.trim()&&n.appSecret?.trim());return{accountId:n.accountId,name:n.name,enabled:n.enabled,configured:r,tokenSource:n.tokenSource,running:e?.running??!1,lastStartAt:e?.lastStartAt??null,lastStopAt:e?.lastStopAt??null,lastError:e?.lastError??null,mode:"websocket",botType:t,lastInboundAt:e?.lastInboundAt??null,lastOutboundAt:e?.lastOutboundAt??null,dmPolicy:"pairing",appId:n.appId?`${n.appId.slice(0,8)}...`:void 0}}L();var bo={id:"Lansenger",label:"Lansenger",selectionLabel:"Lansenger (\u84DD\u4FE1)",docsPath:"/channels/Lansenger",docsLabel:"Lansenger",blurb:"\u84DD\u4FE1\u6D88\u606F\u5E73\u53F0\uFF0C\u652F\u6301Bot API\u3002",aliases:[],order:85,quickstartAllowFrom:!0},En={id:"Lansenger",capabilities:{chatTypes:["direct","group"],media:!0,blockStreaming:!0},outbound:{textChunkLimit:4e3},config:{resolveAllowFrom:({cfg:n,accountId:e})=>(P({cfg:n,accountId:e}).config.allowFrom??[]).map(t=>String(t)),formatAllowFrom:({allowFrom:n})=>n.map(e=>String(e).trim()).filter(Boolean).map(e=>e.replace(/^(Lansenger|lark|fs):/i,"")).map(e=>e.toLowerCase())},groups:{resolveRequireMention:()=>!0},threading:{resolveReplyToMode:()=>"off"}},De=new Qe;De.registerSkill("message",new Re);De.registerSkill("calendar",new Ne);De.registerSkill("meeting",new Oe);var ct={id:"Lansenger",meta:bo,allowOrphanedConfig:!0,onboarding:yn,capabilities:{chatTypes:["direct","group"],media:!0,reactions:!1,threads:!1,polls:!1,nativeCommands:!1,blockStreaming:!0},reload:{configPrefixes:["channels.Lansenger"]},configSchema:{schema:{type:"object",properties:{enabled:{type:"boolean",default:!0},credentials:{type:"object",properties:{name:{type:"string"},appId:{type:"string"},appSecret:{type:"string"},apiGatewayUrl:{type:"string"}}},conversation:{type:"object",properties:{allowFrom:{type:"array",items:{type:"string"}},requireMention:{type:"boolean",default:!0},requirePrefix:{type:"string"},isolateContextPerUserInGroup:{type:"boolean",default:!1}}},reply:{type:"object",properties:{replyMode:{type:"string",enum:["text","markdown"],default:"markdown"},maxChars:{type:"number",default:4e3}}},connection:{type:"object",properties:{apiBase:{type:"string"},apiGatewayUrl:{type:"string"},apiGatewayWssUrl:{type:"string"}}},testMode:{type:"object",properties:{enabled:{type:"boolean",default:!1}}}},additionalProperties:!0},uiHints:{enabled:{label:"\u542F\u7528\u84DD\u4FE1\u6E20\u9053",help:"\u603B\u5F00\u5173\u3002\u5173\u95ED\u540E\u8BE5\u8D26\u53F7\u4E0D\u63A5\u6536\u6D88\u606F\u4E5F\u4E0D\u53D1\u9001\u56DE\u590D\u3002",order:10},credentials:{label:"1. \u63A5\u5165\u51ED\u636E",help:"\u5148\u5B8C\u6210\u673A\u5668\u4EBA\u51ED\u636E\u914D\u7F6E\uFF0C\u518D\u7EE7\u7EED\u914D\u7F6E\u6D88\u606F\u884C\u4E3A\u3002",order:20},"credentials.name":{label:"\u8D26\u53F7\u663E\u793A\u540D\u79F0",help:"\u7528\u4E8E\u591A\u8D26\u53F7\u573A\u666F\u4E0B\u7684\u8BC6\u522B\u540D\u79F0\uFF08\u53EF\u9009\uFF09\u3002",order:10},"credentials.appId":{label:"App ID",help:"\u84DD\u4FE1\u5E94\u7528\u7684 App ID\u3002\u53EF\u5728\u5F00\u53D1\u8005\u540E\u53F0\u67E5\u770B\u3002",placeholder:"3417088-3744000",order:20},"credentials.appSecret":{label:"App Secret",help:"\u84DD\u4FE1\u5E94\u7528\u5BC6\u94A5\u3002",sensitive:!0,order:30},"credentials.apiGatewayUrl":{label:"API \u7F51\u5173\u5730\u5740",help:"\u84DD\u4FE1\u5F00\u653E\u5E73\u53F0 API \u7F51\u5173\u5730\u5740\u3002",advanced:!0,order:40},conversation:{label:"2. \u4F1A\u8BDD\u89E6\u53D1\u4E0E\u6743\u9650",help:"\u63A7\u5236\u54EA\u4E9B\u6D88\u606F\u4F1A\u89E6\u53D1\u673A\u5668\u4EBA\u3002",order:30},"conversation.allowFrom":{label:"\u5141\u8BB8\u53D1\u9001\u8005\u5217\u8868",help:"\u4EC5\u5141\u8BB8\u5217\u8868\u5185\u7528\u6237\u89E6\u53D1\uFF08\u7559\u7A7A\u8868\u793A\u5141\u8BB8\u6240\u6709\u7528\u6237\uFF09\u3002",advanced:!0,order:10},"conversation.requireMention":{label:"\u7FA4\u804A\u8981\u6C42 @\u673A\u5668\u4EBA",help:"\u5F00\u542F\u540E\uFF0C\u7FA4\u804A\u91CC\u9700\u8981 @ \u673A\u5668\u4EBA\u624D\u4F1A\u54CD\u5E94\u3002",advanced:!0,order:20},"conversation.requirePrefix":{label:"\u7FA4\u804A\u89E6\u53D1\u524D\u7F00",help:"\u8BBE\u7F6E\u540E\u4EC5\u54CD\u5E94\u4EE5\u6B64\u524D\u7F00\u5F00\u5934\u7684\u6D88\u606F\u3002",advanced:!0,order:30},"conversation.isolateContextPerUserInGroup":{label:"\u7FA4\u804A\u6309\u7528\u6237\u9694\u79BB\u4E0A\u4E0B\u6587",help:"\u5F00\u542F\u540E\u540C\u4E00\u7FA4\u5185\u6BCF\u4E2A\u7528\u6237\u62E5\u6709\u72EC\u7ACB\u4F1A\u8BDD\u4E0A\u4E0B\u6587\u3002",advanced:!0,order:40},reply:{label:"3. \u56DE\u590D\u7B56\u7565",help:"\u8BBE\u7F6E\u56DE\u590D\u683C\u5F0F\u3001\u6587\u672C\u957F\u5EA6\u9650\u5236\u3002",order:40},"reply.replyMode":{label:"\u56DE\u590D\u6A21\u5F0F",help:"text \u7EAF\u6587\u672C / markdown \u5BCC\u6587\u672C",order:10},"reply.maxChars":{label:"\u5355\u6761\u6D88\u606F\u6700\u5927\u957F\u5EA6",help:"\u8D85\u8FC7\u81EA\u52A8\u62C6\u5206",order:20},connection:{label:"4. \u8FDE\u63A5\u4E0E\u7F51\u5173",help:"\u9AD8\u7EA7\u8FDE\u63A5\u53C2\u6570\uFF0C\u9ED8\u8BA4\u5373\u53EF\u3002",order:50},"connection.apiBase":{label:"API \u57FA\u7840\u5730\u5740",advanced:!0,order:10},"connection.apiGatewayUrl":{label:"API \u7F51\u5173\u5730\u5740",help:"\u84DD\u4FE1\u5F00\u653E\u5E73\u53F0 API \u7F51\u5173\u5730\u5740\u3002",advanced:!0,order:20},"connection.apiGatewayWssUrl":{label:"API WebSocket \u7F51\u5173\u5730\u5740",help:"\u84DD\u4FE1\u5F00\u653E\u5E73\u53F0 WebSocket \u7F51\u5173\u5730\u5740\uFF0C\u4F18\u5148\u4F7F\u7528\uFF0C\u672A\u914D\u7F6E\u5219\u4F7F\u7528 API \u7F51\u5173\u5730\u5740\u7684 wss \u534F\u8BAE\u3002",advanced:!0,order:30},testMode:{label:"5. \u6D4B\u8BD5\u6A21\u5F0F",help:"\u5F00\u542F\u540E\uFF0C\u63A5\u6536\u5230\u7684\u6D88\u606F\u5C06\u76F4\u63A5\u53D1\u9001\u5230 staffId \u7684\u79C1\u804A\uFF0C\u7528\u4E8E\u6D4B\u8BD5\u6D88\u606F\u63A5\u6536\u529F\u80FD\u3002",order:60},"testMode.enabled":{label:"\u542F\u7528\u6D4B\u8BD5\u6A21\u5F0F",help:"\u5F00\u542F\u540E\uFF0C\u63A5\u6536\u5230\u7684\u6D88\u606F\u5C06\u76F4\u63A5\u53D1\u9001\u5230 staffId \u7684\u79C1\u804A\uFF0C\u8DF3\u8FC7 OpenClaw \u5904\u7406\u3002",advanced:!0,order:10}}},config:{listAccountIds:n=>te(n),resolveAccount:(n,e)=>P({cfg:n,accountId:e}),defaultAccountId:n=>Be(n),setAccountEnabled:({cfg:n,accountId:e,enabled:t})=>tr({cfg:n,sectionKey:"Lansenger",accountId:e,enabled:t,allowTopLevel:!0}),deleteAccount:({cfg:n,accountId:e})=>er({cfg:n,sectionKey:"Lansenger",accountId:e,clearBaseFields:["appId","appSecret","name"]}),isConfigured:n=>!!(n.appId?.trim()&&n.appSecret?.trim()),describeAccount:n=>({accountId:n.accountId,name:n.name,enabled:n.enabled,configured:!!(n.appId?.trim()&&n.appSecret?.trim()),tokenSource:n.tokenSource}),resolveAllowFrom:({cfg:n,accountId:e})=>(P({cfg:n,accountId:e}).config.allowFrom??[]).map(t=>String(t)),formatAllowFrom:({allowFrom:n})=>n.map(e=>String(e).trim()).filter(Boolean).map(e=>e.replace(/^(Lansenger|lark|fs):/i,"")).map(e=>e.toLowerCase()),updateConfig:({cfg:n,updates:e})=>e?.openStaffId&&e?.accountId?ye({cfg:n,accountId:e.accountId,staffId:e.openStaffId}):n},security:{resolveDmPolicy:({cfg:n,accountId:e,account:t})=>{i.info("Resolving DM policy",{accountId:e,account:t});let r=e??t.accountId??F,a=!!n.channels?.Lansenger?.accounts?.[r]?`channels.Lansenger.accounts.${r}.`:"channels.Lansenger.",s={policy:t.config.dmPolicy??"pairing",allowFrom:t.config.allowFrom??[],policyPath:`${a}dmPolicy`,allowFromPath:a,approveHint:nr("Lansenger"),normalizeEntry:c=>c.replace(/^(Lansenger|lark|fs):/i,"")};return i.info("Resolved DM policy",{dmPolicy:s}),s}},groups:{resolveRequireMention:()=>!0},threading:{resolveReplyToMode:()=>"off"},messaging:{normalizeTarget:Tn,targetResolver:{looksLikeId:n=>{let e=n.trim();return e?/^(oc|ou|on)_[a-f0-9]+$/i.test(e)||/^[a-f0-9]{20,}$/i.test(e):!1},hint:"<chatId>"}},directory:{self:async()=>null,listPeers:async({cfg:n,accountId:e,query:t,limit:r})=>{let o=P({cfg:n,accountId:e}),a=t?.trim().toLowerCase()||"";return Array.from(new Set((o.config.allowFrom??[]).map(c=>String(c).trim()).filter(c=>!!c&&c!=="*").map(c=>c.replace(/^(Lansenger|lark|fs):/i,"")))).filter(c=>a?c.toLowerCase().includes(a):!0).slice(0,r&&r>0?r:void 0).map(c=>({kind:"user",id:c}))},listGroups:async()=>[]},setup:{resolveAccountId:({accountId:n})=>fe(n),applyAccountName:({cfg:n,accountId:e,name:t})=>_e({cfg:n,channelKey:"Lansenger",accountId:e,name:t}),validateInput:({accountId:n,input:e})=>null,applyAccountConfig:({cfg:n,accountId:e,input:t})=>vt({cfg:n,accountId:e,input:t})},pairing:{idLabel:"LansengerUserId",normalizeAllowEntry:n=>n.replace(/^(Lansenger|lark|fs):/i,""),getSessionByCode:async n=>{try{return ot().getSessionByCode(n)}catch(e){i.error("Error getting session by code:",e);return}},notifyApproval:async({cfg:n,id:e})=>{i.info(`[Lansenger] notifyApproval method called with parameters: id=${e}`);let t=P({cfg:n});if(!t.appId||!t.appSecret)throw new Error("Lansenger credentials not configured");let r=xe(t);await H(r,t.config,e,or,{hookToken:t.config.hookToken,isGroup:e.startsWith("oc_")})}},outbound:{deliveryMode:"direct",chunker:(n,e)=>(i.debug(`[Lansenger] chunker method called with parameters: text=${n.slice(0,80)}, limit=${e}`),xn(n,e)),chunkerMode:"text",textChunkLimit:4e3,sendText:async({to:n,text:e,accountId:t,cfg:r})=>bn({to:n,text:e,accountId:t,cfg:r}),sendMedia:async({to:n,text:e,mediaUrl:t,accountId:r,cfg:o})=>$n({to:n,text:e,mediaUrl:t,accountId:r,cfg:o}),push:async({to:n,text:e,accountId:t,cfg:r,log:o})=>Sn({to:n,text:e,accountId:t,cfg:r,log:o})},status:{defaultRuntime:vn,collectStatusIssues:wn,buildChannelSummary:An,probeAccount:Cn,buildAccountSnapshot:Mn},gateway:{startAccount:async n=>{let e=n.account,t="";try{let a=n.log?typeof n.log=="function"?{info:s=>n.log?.(s),error:s=>n.log?.(s),debug:s=>n.log?.(s)}:{info:s=>n.log?.info?.(s)??console.log(s),error:s=>n.log?.error?.(s)??console.error(s),debug:s=>n.log?.debug?.(s)??console.debug(s)}:{info:s=>console.log(s),error:s=>console.error(s),debug:s=>console.debug(s)};i.setOpenClawLog(a)}catch(a){console.error("[Lansenger] Failed to setup OpenClaw log interface:",a),i.setOpenClawLog({info:s=>console.log(s),error:s=>console.error(s),debug:s=>console.debug(s)})}try{let a=xe(e),s;a==="webhook"?s=await it(e.config.hookToken||"",3e3,e.config.apiGatewayUrl):s=await st(e.appId,e.appSecret,3e3,e.config.apiGatewayUrl),s.ok&&(t=` (${a} bot)`),n.setStatus({accountId:e.accountId,bot:{name:`${a} bot`}})}catch{}De.initializeSkills(e);let o=(await Tr({account:e,config:n.runtime?.config?.current?.()??n.cfg,log:{info:a=>{typeof n.log=="function"?n.log(a):n.log?.info(a)},error:a=>{typeof n.log=="function"?n.log(a):n.log?.error(a)},debug:a=>{typeof n.log=="function"?n.log(a):n.log?.debug?.(a)}},abortSignal:n.abortSignal,statusSink:a=>n.setStatus({accountId:n.accountId,...a})})).stop;return{stop:()=>{o(),De.shutdownSkills(),typeof n.log=="function"?n.log(`[${e.accountId}] Shutdown skills`):n.log?.info(`[${e.accountId}] Shutdown skills`)}}}}};Tt();u();L();u();L();var Kt=class{highRiskTools;defaultEnabled;constructor(e={}){this.highRiskTools=e.highRiskTools||["read","write","edit","delete","exec","trash","rm"],this.defaultEnabled=e.defaultEnabled??!1}isHighRiskTool(e){return this.highRiskTools.includes(e)}parseHighRiskTools(e){return e?typeof e=="string"?e.split(",").map(t=>t.trim()).filter(Boolean):this.highRiskTools:this.highRiskTools}async handleBeforeToolCall(e,t){i.info(`[Lansenger][Approval] before_tool_call hook triggered event: ${JSON.stringify(e)} ctx: ${JSON.stringify(t)}`);try{if(!e||typeof e!="object")return i.warn(`[Lansenger][Approval] Invalid event type: ${typeof e}`),{block:!1};let{toolName:r,params:o}=e;if(typeof r!="string")return i.warn(`[Lansenger][Approval] Invalid toolName type: ${typeof r}`),{block:!1};i.info(`[Lansenger][Approval] Tool call: ${r} Tool params: ${o?JSON.stringify(o):"undefined"}`);let a=t.pluginConfig,s=a?.approval?.enabled??this.defaultEnabled,c=a?.approval?.highRiskTools,l=s?this.parseHighRiskTools(c):[];return i.info(`[Lansenger][Approval] High risk tools: ${l}`),l.includes(r)?(i.info(`[Lansenger][Approval] High risk tool detected: ${r}`),i.debug(`[Lansenger][Approval] Tool params: ${o?JSON.stringify(o):"undefined"}`),i.info(`[Lansenger][Approval] Default approving high risk tool: ${r}`),i.info("[Lansenger][Approval] TODO: Call Lansenger approval API here"),{block:!1}):{block:!1}}catch(r){return i.error(`[Lansenger][Approval] Error in before_tool_call hook: ${r instanceof Error?r.message:String(r)}`),{block:!1}}}handleApprovalResult(e){return e.approved?(i.info("[Lansenger][Approval] Operation approved"),!0):(i.info(`[Lansenger][Approval] Operation denied: ${e.reason||"No reason provided"}`),!1)}},$o=new Kt;async function Vt(n,e){return $o.handleBeforeToolCall(n,e)}u();G();var Yt=class{config;constructor(e={}){this.config={enabled:e.enabled??!0,rules:e.rules??[],sensitiveWords:e.sensitiveWords??[]}}interceptMessage(e){if(!this.config.enabled)return{blocked:!1,requireApproval:!1};for(let t of this.config.sensitiveWords)if(e.includes(t))return i.info(`[Lansenger][MessageInterceptor] Sensitive word detected: ${t}`),{blocked:!1,requireApproval:!0,reason:`\u6D88\u606F\u5305\u542B\u654F\u611F\u8BCD: ${t}`};for(let t of this.config.rules.sort((r,o)=>(o.priority||0)-(r.priority||0))){let r=!1;switch(t.type){case"keyword":r=e.includes(t.value);break;case"regex":r=new RegExp(t.value).test(e);break;case"custom":r=t.value(e);break}if(r)return i.info(`[Lansenger][MessageInterceptor] Rule matched: ${t.name}`),{blocked:!1,requireApproval:t.requireApproval,reason:`\u89E6\u53D1\u89C4\u5219: ${t.description}`}}return{blocked:!1,requireApproval:!1}}addRule(e){this.config.rules.push(e)}removeRule(e){this.config.rules=this.config.rules.filter(t=>t.name!==e)}addSensitiveWord(e){this.config.sensitiveWords.includes(e)||this.config.sensitiveWords.push(e)}removeSensitiveWord(e){this.config.sensitiveWords=this.config.sensitiveWords.filter(t=>t!==e)}enable(){this.config.enabled=!0}disable(){this.config.enabled=!1}getConfig(){return{...this.config}}updateConfig(e){this.config={...this.config,...e}}};function Pn(n={}){return new Yt(n)}var Xt=class{enabled;messageInterceptor;constructor(e={}){this.enabled=e.enabled??!1,this.messageInterceptor=Pn({enabled:!0,sensitiveWords:["\u654F\u611F\u8BCD1","\u654F\u611F\u8BCD2","\u654F\u611F\u8BCD3"],rules:[{name:"group_message_rule",description:"\u7FA4\u6D88\u606F\u68C0\u67E5",type:"custom",value:t=>t.includes("\u7FA4\u6D88\u606F"),requireApproval:!0,priority:10},{name:"sensitive_content_rule",description:"\u654F\u611F\u5185\u5BB9\u68C0\u67E5",type:"regex",value:/敏感内容|不良信息/g,requireApproval:!0,priority:5}],...e.messageInterceptor})}registerHooks(e){if(!this.enabled){i.info("[Lansenger][HookRegistry] Hooks are disabled, skipping registration");return}this.registerBeforeToolCallHook(e),this.registerMessageSendingHook(e)}registerBeforeToolCallHook(e){e.on?(i.info("[Lansenger][Approval] Registering before_tool_call hook"),e.on("before_tool_call",async(t,r)=>await Vt(t,r),{priority:100}),i.info("[Lansenger] Registered before_tool_call hook for high-risk operation approval")):e.registerHook?(i.info("[Lansenger][Approval] Registering before_tool_call hook using registerHook"),e.registerHook("before_tool_call",async(t,r)=>await Vt(t,r),{name:"lansenger-approval-hook",priority:100}),i.info("[Lansenger] Registered before_tool_call hook for high-risk operation approval using registerHook")):i.warn("[Lansenger] Neither api.on nor api.registerHook is available in current API version")}registerMessageSendingHook(e){e.on?(i.info("[Lansenger][MessageInterceptor] Registering message_sending hook"),e.on("message_sending",async(t,r)=>{i.info(`[Lansenger][MessageInterceptor] message_sending hook triggered event: ${JSON.stringify(t)} ctx: ${JSON.stringify(r)}`);let o=t.content||t.text||"",a=this.messageInterceptor.interceptMessage(o);return a.requireApproval?(i.info(`[Lansenger][MessageInterceptor] Message requires approval: ${a.reason}`),{requireApproval:{title:"\u6D88\u606F\u53D1\u9001\u5BA1\u6279",description:a.reason||"\u8BE5\u6D88\u606F\u9700\u8981\u5BA1\u6279\u624D\u80FD\u53D1\u9001",severity:"warning",timeoutMs:6e4,timeoutBehavior:"deny"}}):{}},{priority:100}),i.info("[Lansenger] Registered message_sending hook for message interception")):e.registerHook?(i.info("[Lansenger][MessageInterceptor] Registering message_sending hook using registerHook"),e.registerHook("message_sending",async(t,r)=>{i.info(`[Lansenger][MessageInterceptor] message_sending hook triggered event: ${JSON.stringify(t)} ctx: ${JSON.stringify(r)}`);let o=t.content||t.text||"",a=this.messageInterceptor.interceptMessage(o);return a.requireApproval?(i.info(`[Lansenger][MessageInterceptor] Message requires approval: ${a.reason}`),{requireApproval:{title:"\u6D88\u606F\u53D1\u9001\u5BA1\u6279",description:a.reason||"\u8BE5\u6D88\u606F\u9700\u8981\u5BA1\u6279\u624D\u80FD\u53D1\u9001",severity:"warning",timeoutMs:6e4,timeoutBehavior:"deny"}}):{}},{name:"lansenger-message-interceptor-hook",priority:100}),i.info("[Lansenger] Registered message_sending hook for message interception using registerHook")):i.warn("[Lansenger] Neither api.on nor api.registerHook is available for message_sending hook")}setEnabled(e){this.enabled=e}isEnabled(){return this.enabled}};function Ln(n={}){return new Xt(n)}var lt=Ln({enabled:!1});function So(){return JSON.stringify({plugins:{enabled:!0,allow:["openclaw-channel-lansenger"],entries:{"openclaw-channel-lansenger":{enabled:!0}},bundledDiscovery:"compat"},channels:{Lansenger:{enabled:!0,accounts:{default:{enabled:!0,appId:"YOUR_APP_ID",appSecret:"YOUR_APP_SECRET",apiGatewayUrl:"https://apigw.example.com",approval:{enabled:!0,highRiskTools:"write,delete,trash,rm"}}}}}},null,2)}function Un(n){let e=`
|
|
38
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
39
|
+
\u2551 Lansenger (\u84DD\u4FE1) \u63D2\u4EF6\u63A8\u8350\u914D\u7F6E \u2551
|
|
40
|
+
\u2557\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
41
|
+
`,t=`
|
|
42
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
43
|
+
|
|
44
|
+
\u8BF4\u660E\uFF1A
|
|
45
|
+
1. \u8BF7\u5C06\u4E0A\u8FF0\u914D\u7F6E\u5408\u5E76\u6DFB\u52A0\u5230 ~/.openclaw/openclaw.json \u6587\u4EF6\u4E2D
|
|
46
|
+
2. \u66FF\u6362 YOUR_APP_ID \u548C YOUR_APP_SECRET \u4E3A\u5B9E\u9645\u7684\u84DD\u4FE1\u5E94\u7528\u51ED\u636E
|
|
47
|
+
3. \u66FF\u6362 https://apigw.example.com \u4E3A\u5B9E\u9645\u7684 API \u7F51\u5173\u5730\u5740
|
|
48
|
+
4. \u914D\u7F6E\u5B8C\u6210\u540E\u91CD\u542F OpenClaw: openclaw gateway restart
|
|
49
|
+
5. \u6216\u76F4\u63A5\u4F7F\u7528\u547D\u4EE4\u6DFB\u52A0\u8D26\u53F7: openclaw channels add --channel Lansenger --token "appId:appSecret:apiGatewayUrl"\uFF08\u5982\u4E0D\u751F\u6548\uFF0C\u9700\u8981\u624B\u52A8\u6DFB\u52A0\uFF09
|
|
50
|
+
`,r=So(),o=e+r+t;globalThis.console?.log(o),n&&n.log&&n.log(o)}var vo=n=>{ae.init(n.runtime),$e(n.runtime),lt.registerHooks(n)},Ao={id:"openclaw-channel-lansenger",name:"Lansenger",description:"Lansenger (\u84DD\u4FE1) channel plugin \u2014 WebSocket long-connection bot",configSchema:Zt(),plugin:ct,setRuntime:$e,setHooksEnabled:n=>{lt.setEnabled(n)},isHooksEnabled:()=>lt.isEnabled(),registerFull:vo,onInstall:function(n){Un(n)},register(n){ae.init(n.runtime),$e(n.runtime);try{let e=n.runtime?.config;(!e||!e.channels||!e.channels.Lansenger)&&Un(n.runtime)}catch{}ae.isUsingNewSdk()?n.registerChannel(ct):n.registerChannel({plugin:ct,dock:En}),lt.registerHooks(n)}},Co=ae.createPluginEntry(Ao),zl=Co;export{zl as default};
|