birdcash-chat-sdk-alpha 1.0.7 → 1.0.8
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/main.cjs.js +1 -1
- package/dist/main.esm.js +1 -1
- package/dist/types/client.d.ts +8 -1
- package/dist/types/elements.d.ts +6 -1
- package/dist/types/types.d.ts +29 -0
- package/package.json +1 -1
package/dist/main.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const e="https://chat-api2-3rnt.onrender.com",t="web_link",s="ai_choice_prompt",r="official_account_tweet";async function a(t){var s;const{clientId:r,clientSecret:a}=t;if(!r||!a)throw new Error("getAccessToken: clientId and clientSecret are required");const i=e.replace(/\/$/,""),n=null!==(s=t.scope)&&void 0!==s?s:"chat:write uploads:write";if("undefined"==typeof fetch)throw new Error("getAccessToken: global fetch is not available");const o=await fetch(`${i}/v1/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"client_credentials",client_id:r,client_secret:a,scope:n})});if(!o.ok)throw new Error(`Token request failed: ${o.status} ${o.statusText}`);return await o.json()}var i;function n(e){return{elemType:exports.ElemType.Text,priority:0,textElem:{text:e.trim()}}}function o(e){return{elemType:exports.ElemType.Image,priority:0,imageElem:{upload_ids:e}}}function l(e){return{elemType:exports.ElemType.File,priority:0,fileElem:{upload_ids:e}}}function u(e,t=0){return{elemType:exports.ElemType.Sound,priority:0,soundElem:{uploadID:e,duration:t}}}function c(e,t){return{elemType:exports.ElemType.Sticker,priority:0,stickerElem:{packID:e,stickerID:t}}}function d(e){return{elemType:exports.ElemType.Custom,priority:0,customElem:{data:e}}}function h(e){return{elemType:exports.ElemType.MiniApp,priority:0,miniAppElem:e}}function g(e){const t=new Uint8Array(e.byteLength);return t.set(e),t}function p(e){const t=(new TextEncoder).encode(e);let s="";for(const e of t)s+=String.fromCharCode(e);return btoa(s)}function m(e,t=10){if(e.length<=t)return[e];const s=[];let r="";for(const a of e.split(" "))r.length+a.length+1>t&&r.length>0?(s.push(r.trim()+" "),r=a):r+=(r?" ":"")+a;return r&&s.push(r.trim()),s.length>0?s:[e]}exports.ElemType=void 0,(i=exports.ElemType||(exports.ElemType={}))[i.None=0]="None",i[i.Text=1]="Text",i[i.Image=2]="Image",i[i.Sound=3]="Sound",i[i.Video=4]="Video",i[i.File=5]="File",i[i.Sticker=6]="Sticker",i[i.GroupTips=7]="GroupTips",i[i.Merger=8]="Merger",i[i.Custom=9]="Custom",i[i.Location=10]="Location",i[i.GroupAnnouncement=11]="GroupAnnouncement",i[i.Quote=12]="Quote",i[i.InputStatus=14]="InputStatus",i[i.TypingStatus=15]="TypingStatus",i[i.MiniApp=16]="MiniApp",i[i.Order=17]="Order",i[i.Transfer=18]="Transfer";class f{constructor(t){var s,r;if(!(null==t?void 0:t.token))throw new Error("ChatClient: token is required");this.token=t.token,this.baseUrl=(null!==(s=t.baseUrl)&&void 0!==s?s:e).replace(/\/$/,""),this.logger=t.logger;const a=null!==(r=t.fetch)&&void 0!==r?r:"undefined"!=typeof fetch?fetch:void 0;if(!a)throw new Error("ChatClient: no fetch implementation available; pass `fetch` in options");this.fetchImpl=a.bind(globalThis)}static async fromCredentials(e){const{access_token:t}=await a({clientId:e.clientId,clientSecret:e.clientSecret,scope:e.scope});return new f({token:t,baseUrl:e.baseUrl,logger:e.logger,fetch:e.fetch})}get authHeaders(){return{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`}}replyUrl(e){return`${this.baseUrl}/v1/chat/message/${e}/reply`}newMsgID(){return globalThis.crypto.randomUUID()}async postElements(e,t,s="POST"){return await this.fetchImpl(this.replyUrl(e),{method:s,headers:this.authHeaders,body:JSON.stringify(t)})}async uploadImage(e,t,s="image/png"){var r;const a=new FormData;a.append("file",new Blob([g(e)],{type:s}),t);const i=await this.fetchImpl(`${this.baseUrl}/v1/upload/image`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:a}),n=await i.json();if(!i.ok)throw new Error(`uploadImage failed: ${i.status} ${JSON.stringify(n)}`);if(!n.upload_id)throw new Error(`uploadImage: missing upload_id: ${JSON.stringify(n)}`);return{upload_id:n.upload_id,url:null!==(r=n.url)&&void 0!==r?r:""}}async uploadFile(e,t,s="application/octet-stream"){var r;const a=new FormData;a.append("file",new Blob([g(e)],{type:s}),t);const i=await this.fetchImpl(`${this.baseUrl}/v1/upload/file`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:a}),n=await i.json();if(!i.ok)throw new Error(`uploadFile failed: ${i.status} ${JSON.stringify(n)}`);if(!n.upload_id)throw new Error(`uploadFile: missing upload_id: ${JSON.stringify(n)}`);return{upload_id:n.upload_id,url:null!==(r=n.url)&&void 0!==r?r:""}}async sendMessage(e,t,s){var r;let a=Array.isArray(t)?t.map((e=>e.trim())).filter(Boolean).map(n):[n(t)];if(0===a.length)return;s&&(a=a.map((e=>({...e,msgID:s}))));const i=await this.postElements(e,a),o=await i.text();if(null===(r=this.logger)||void 0===r||r.log("[chat-sdk] message sent",{status:i.status,elements:a.length}),!i.ok)throw new Error(`sendMessage failed: ${i.status} ${o}`)}async sendImageMessage(e,t){var s;if(!(null==t?void 0:t.length))return;const r=await this.postElements(e,[o(t)]),a=await r.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] image message sent",{status:r.status}),!r.ok)throw new Error(`sendImageMessage failed: ${r.status} ${a}`)}async sendFileMessage(e,t){var s;if(!(null==t?void 0:t.length))return;const r=await this.postElements(e,[l(t)]),a=await r.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] file message sent",{status:r.status}),!r.ok)throw new Error(`sendFileMessage failed: ${r.status} ${a}`)}async sendSoundMessage(e,t,s=0){var r;if(!(null==t?void 0:t.trim()))return;const a=await this.postElements(e,[u(t,s)]),i=await a.text();if(null===(r=this.logger)||void 0===r||r.log("[chat-sdk] sound message sent",{status:a.status}),!a.ok)throw new Error(`sendSoundMessage failed: ${a.status} ${i.slice(0,500)}`)}async sendStickerMessage(e,t,s,r){var a;if(!(null==t?void 0:t.trim())||!(null==s?void 0:s.trim()))return;const i=c(t,s),n=await this.postElements(e,[r?{...i,msgID:r}:i]),o=await n.text();if(null===(a=this.logger)||void 0===a||a.log("[chat-sdk] sticker message sent",{status:n.status}),!n.ok)throw new Error(`sendStickerMessage failed: ${n.status} ${o}`)}async editTextMessage(e,t){var s;const r=await this.postElements(e,[{msgID:e,...n(t)}]),a=await r.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] text message edited",{status:r.status}),!r.ok)throw new Error(`editTextMessage failed: ${r.status} ${a.slice(0,500)}`)}async editStickerMessage(e,t,s){var r;const a=await this.postElements(e,[{msgID:e,...c(t,s)}]),i=await a.text();if(null===(r=this.logger)||void 0===r||r.log("[chat-sdk] sticker message edited",{status:a.status}),!a.ok)throw new Error(`editStickerMessage failed: ${a.status} ${i.slice(0,500)}`)}async editImageMessage(e,t){var s;const r=await this.postElements(e,[{msgID:e,...o(t)}]),a=await r.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] image message edited",{status:r.status}),!r.ok)throw new Error(`editImageMessage failed: ${r.status} ${a.slice(0,500)}`)}async deleteMessage(e){var t;const s=await this.fetchImpl(`${this.baseUrl}/v1/chat/message/${e}`,{method:"DELETE",headers:this.authHeaders});if(null===(t=this.logger)||void 0===t||t.log("[chat-sdk] message deleted",{status:s.status}),!s.ok){const e=await s.text();throw new Error(`deleteMessage failed: ${s.status} ${e.slice(0,500)}`)}}async sendTypingStatus(e,t){var s,r;const a={businessID:"user_typing_status",typingStatus:t?1:0,version:1,userAction:14,actionParam:t?"EIMAMSG_InputStatus_Ing":"EIMAMSG_InputStatus_End"};try{await this.postElements(e,[d(p(JSON.stringify(a)))])}catch(e){null===(s=this.logger)||void 0===s||s.error("[chat-sdk] typing status failed",null!==(r=null==e?void 0:e.message)&&void 0!==r?r:String(e))}}async sendStreamingChunk(e,t,s,r){const a={businessID:"chatbotPlugin",src:0,chunks:t,isFinished:s,TMessageCell_Name:"ChatbotMessageCell_Minimalist",TMessageCell_Data_Name:"ChatbotMessageCellData"},i={msgID:e,...d(p(JSON.stringify(a)))},n=await this.postElements(e,[i],r?"POST":"PATCH");if(!n.ok)throw new Error(`sendStreamingChunk failed: ${n.statusText}`);await n.text()}async sendMiniAppMessage(e,t){var s;const r=await this.postElements(e,[h(t)]),a=await r.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] miniapp card sent",{status:r.status}),!r.ok)throw new Error(`sendMiniAppMessage failed: ${r.status} ${a}`)}async sendWebLinkMessage(e,s){var r;const a={businessID:t,url:s},i=await this.postElements(e,[d(p(JSON.stringify(a)))]),n=await i.text();if(null===(r=this.logger)||void 0===r||r.log("[chat-sdk] web link sent",{status:i.status}),!i.ok)throw new Error(`sendWebLinkMessage failed: ${i.status} ${n.slice(0,500)}`)}async sendChoicesMessage(e,t){var r,a,i;const n=this.newMsgID(),o={businessID:s,promptId:null!==(r=t.promptId)&&void 0!==r?r:this.newMsgID(),prompt:t.prompt,selectionMode:null!==(a=t.selectionMode)&&void 0!==a?a:"single",choices:t.choices},l=await this.postElements(e,[{msgID:n,...d(p(JSON.stringify(o)))}]),u=await l.text();if(null===(i=this.logger)||void 0===i||i.log("[chat-sdk] choices message sent",{status:l.status}),!l.ok)throw new Error(`sendChoicesMessage failed: ${l.status} ${u.slice(0,500)}`);return n}async sendOfficialAccountTweetMessage(e,t){var s;const a=this.newMsgID(),i={businessID:r,...t},n=await this.postElements(e,[{msgID:a,...d(p(JSON.stringify(i)))}]),o=await n.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] official account tweet sent",{status:n.status}),!n.ok)throw new Error(`sendOfficialAccountTweetMessage failed: ${n.status} ${o.slice(0,500)}`);return a}async streamMessage(e,t,s=10){const r=m(t,s),a=[];for(let t=0;t<r.length;t++)a.push(r[t]),await this.sendStreamingChunk(e,a,t===r.length-1,0===t)}}f.ElemType=exports.ElemType,exports.AI_CHOICE_PROMPT_BUSINESS_ID=s,exports.DEFAULT_BASE_URL=e,exports.OFFICIAL_ACCOUNT_TWEET_BUSINESS_ID=r,exports.WEB_LINK_BUSINESS_ID=t,exports.arrayBufferToBase64=function(e){let t="";const s=new Uint8Array(e),r=s.byteLength;for(let e=0;e<r;e++)t+=String.fromCharCode(s[e]);return btoa(t)},exports.base64ToArrayBuffer=function(e){const t=atob(e),s=t.length,r=new Uint8Array(s);for(let e=0;e<s;e++)r[e]=t.charCodeAt(e);return r.buffer},exports.chatClient=function(e){return new f({token:e})},exports.customElem=d,exports.fileElem=l,exports.getAccessToken=a,exports.imageElem=o,exports.miniAppElem=h,exports.soundElem=u,exports.splitIntoChunks=m,exports.stickerElem=c,exports.textElem=n,exports.toBase64=p,exports.verifyWebhookSignature=async function(e,t,s,r={}){const{toleranceSec:a=300,logger:i}=r,n=e.headers.get("X-Webhook-Signature");if(!n)return null==i||i.error("[chat-sdk] webhook missing X-Webhook-Signature header"),{valid:!1,error:"Missing X-Webhook-Signature header"};const o=e.headers.get("X-Webhook-Timestamp");if(!o)return null==i||i.error("[chat-sdk] webhook missing X-Webhook-Timestamp header"),{valid:!1,error:"Missing X-Webhook-Timestamp header"};const l=n.startsWith("sha256=")?n.slice(7):n,u=await async function(e,t){const s=new TextEncoder,r=await crypto.subtle.importKey("raw",s.encode(e),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),a=await crypto.subtle.sign("HMAC",r,s.encode(t));return[...new Uint8Array(a)].map((e=>e.toString(16).padStart(2,"0"))).join("")}(t,`${o}.${s}`);if(!function(e,t){if(e.length!==t.length)return!1;let s=0;for(let r=0;r<e.length;r++)s|=e.charCodeAt(r)^t.charCodeAt(r);return 0===s}(l,u))return null==i||i.error("[chat-sdk] webhook invalid signature"),{valid:!1,error:"Invalid signature"};const c=parseInt(o,10),d=Math.floor(Date.now()/1e3);return!Number.isFinite(c)||Math.abs(d-c)>a?(null==i||i.error("[chat-sdk] webhook timestamp out of range"),{valid:!1,error:"Request timestamp too old or too far in future"}):(null==i||i.log("[chat-sdk] webhook signature valid"),{valid:!0})};
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const e="https://chat-api2-3rnt.onrender.com",t="web_link",s="ai_choice_prompt",a="official_account_tweet";async function r(t){var s;const{clientId:a,clientSecret:r}=t;if(!a||!r)throw new Error("getAccessToken: clientId and clientSecret are required");const o=e.replace(/\/$/,""),n=null!==(s=t.scope)&&void 0!==s?s:"chat:write uploads:write";if("undefined"==typeof fetch)throw new Error("getAccessToken: global fetch is not available");const i=await fetch(`${o}/v1/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"client_credentials",client_id:a,client_secret:r,scope:n})});if(!i.ok)throw new Error(`Token request failed: ${i.status} ${i.statusText}`);return await i.json()}var o;function n(e){return{elemType:exports.ElemType.Text,priority:0,textElem:{text:e.trim()}}}function i(e){return{elemType:exports.ElemType.Image,priority:0,imageElem:{upload_ids:e}}}function l(e){return{elemType:exports.ElemType.File,priority:0,fileElem:{upload_ids:e}}}function u(e,t=0){return{elemType:exports.ElemType.Sound,priority:0,soundElem:{uploadID:e,duration:t}}}function c(e,t){return{elemType:exports.ElemType.Sticker,priority:0,stickerElem:{packID:e,stickerID:t}}}function d(e,t,s){const a={...n(e),cloudCustomData:{messageReply:t}};return s?{msgID:s,...a}:a}function g(e){return{elemType:exports.ElemType.Custom,priority:0,customElem:{data:e}}}function h(e){return{elemType:exports.ElemType.MiniApp,priority:0,miniAppElem:e}}function p(e){const t=new Uint8Array(e.byteLength);return t.set(e),t}function m(e){const t=(new TextEncoder).encode(e);let s="";for(const e of t)s+=String.fromCharCode(e);return btoa(s)}function f(e,t=10){if(e.length<=t)return[e];const s=[];let a="";for(const r of e.split(" "))a.length+r.length+1>t&&a.length>0?(s.push(a.trim()+" "),a=r):a+=(a?" ":"")+r;return a&&s.push(a.trim()),s.length>0?s:[e]}exports.ElemType=void 0,(o=exports.ElemType||(exports.ElemType={}))[o.None=0]="None",o[o.Text=1]="Text",o[o.Image=2]="Image",o[o.Sound=3]="Sound",o[o.Video=4]="Video",o[o.File=5]="File",o[o.Sticker=6]="Sticker",o[o.GroupTips=7]="GroupTips",o[o.Merger=8]="Merger",o[o.Custom=9]="Custom",o[o.Location=10]="Location",o[o.GroupAnnouncement=11]="GroupAnnouncement",o[o.Quote=12]="Quote",o[o.InputStatus=14]="InputStatus",o[o.TypingStatus=15]="TypingStatus",o[o.MiniApp=16]="MiniApp",o[o.Order=17]="Order",o[o.Transfer=18]="Transfer";class w{constructor(t){var s,a;if(!(null==t?void 0:t.token))throw new Error("ChatClient: token is required");this.token=t.token,this.baseUrl=(null!==(s=t.baseUrl)&&void 0!==s?s:e).replace(/\/$/,""),this.logger=t.logger;const r=null!==(a=t.fetch)&&void 0!==a?a:"undefined"!=typeof fetch?fetch:void 0;if(!r)throw new Error("ChatClient: no fetch implementation available; pass `fetch` in options");this.fetchImpl=r.bind(globalThis)}static async fromCredentials(e){const{access_token:t}=await r({clientId:e.clientId,clientSecret:e.clientSecret,scope:e.scope});return new w({token:t,baseUrl:e.baseUrl,logger:e.logger,fetch:e.fetch})}get authHeaders(){return{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`}}replyUrl(e){return`${this.baseUrl}/v1/chat/message/${e}/reply`}newMsgID(){return globalThis.crypto.randomUUID()}async postElements(e,t,s="POST"){return await this.fetchImpl(this.replyUrl(e),{method:s,headers:this.authHeaders,body:JSON.stringify(t)})}async uploadImage(e,t,s="image/png"){var a;const r=new FormData;r.append("file",new Blob([p(e)],{type:s}),t);const o=await this.fetchImpl(`${this.baseUrl}/v1/upload/image`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:r}),n=await o.json();if(!o.ok)throw new Error(`uploadImage failed: ${o.status} ${JSON.stringify(n)}`);if(!n.upload_id)throw new Error(`uploadImage: missing upload_id: ${JSON.stringify(n)}`);return{upload_id:n.upload_id,url:null!==(a=n.url)&&void 0!==a?a:""}}async uploadFile(e,t,s="application/octet-stream"){var a;const r=new FormData;r.append("file",new Blob([p(e)],{type:s}),t);const o=await this.fetchImpl(`${this.baseUrl}/v1/upload/file`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:r}),n=await o.json();if(!o.ok)throw new Error(`uploadFile failed: ${o.status} ${JSON.stringify(n)}`);if(!n.upload_id)throw new Error(`uploadFile: missing upload_id: ${JSON.stringify(n)}`);return{upload_id:n.upload_id,url:null!==(a=n.url)&&void 0!==a?a:""}}async sendMessage(e,t,s){var a;let r=Array.isArray(t)?t.map((e=>e.trim())).filter(Boolean).map(n):[n(t)];if(0===r.length)return;s&&(r=r.map((e=>({...e,msgID:s}))));const o=await this.postElements(e,r),i=await o.text();if(null===(a=this.logger)||void 0===a||a.log("[chat-sdk] message sent",{status:o.status,elements:r.length}),!o.ok)throw new Error(`sendMessage failed: ${o.status} ${i}`)}async sendQuoteMessage(e,t,s){var a,r,o,n;const i=null!==(a=s.replyMsgID)&&void 0!==a?a:this.newMsgID(),l=d(t,{messageID:s.quotedMessageID,messageAbstract:s.messageAbstract,messageSender:s.messageSender,messageType:null!==(r=s.messageType)&&void 0!==r?r:1,version:null!==(o=s.version)&&void 0!==o?o:1},i),u=await this.postElements(e,[l]),c=await u.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] quote message sent",{status:u.status}),!u.ok)throw new Error(`sendQuoteMessage failed: ${u.status} ${c}`);return i}async sendImageMessage(e,t){var s;if(!(null==t?void 0:t.length))return;const a=await this.postElements(e,[i(t)]),r=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] image message sent",{status:a.status}),!a.ok)throw new Error(`sendImageMessage failed: ${a.status} ${r}`)}async sendFileMessage(e,t){var s;if(!(null==t?void 0:t.length))return;const a=await this.postElements(e,[l(t)]),r=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] file message sent",{status:a.status}),!a.ok)throw new Error(`sendFileMessage failed: ${a.status} ${r}`)}async sendSoundMessage(e,t,s=0){var a;if(!(null==t?void 0:t.trim()))return;const r=await this.postElements(e,[u(t,s)]),o=await r.text();if(null===(a=this.logger)||void 0===a||a.log("[chat-sdk] sound message sent",{status:r.status}),!r.ok)throw new Error(`sendSoundMessage failed: ${r.status} ${o.slice(0,500)}`)}async sendStickerMessage(e,t,s,a){var r;if(!(null==t?void 0:t.trim())||!(null==s?void 0:s.trim()))return;const o=c(t,s),n=await this.postElements(e,[a?{...o,msgID:a}:o]),i=await n.text();if(null===(r=this.logger)||void 0===r||r.log("[chat-sdk] sticker message sent",{status:n.status}),!n.ok)throw new Error(`sendStickerMessage failed: ${n.status} ${i}`)}async editTextMessage(e,t){var s;const a=await this.postElements(e,[{msgID:e,...n(t)}]),r=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] text message edited",{status:a.status}),!a.ok)throw new Error(`editTextMessage failed: ${a.status} ${r.slice(0,500)}`)}async editStickerMessage(e,t,s){var a;const r=await this.postElements(e,[{msgID:e,...c(t,s)}]),o=await r.text();if(null===(a=this.logger)||void 0===a||a.log("[chat-sdk] sticker message edited",{status:r.status}),!r.ok)throw new Error(`editStickerMessage failed: ${r.status} ${o.slice(0,500)}`)}async editImageMessage(e,t){var s;const a=await this.postElements(e,[{msgID:e,...i(t)}]),r=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] image message edited",{status:a.status}),!a.ok)throw new Error(`editImageMessage failed: ${a.status} ${r.slice(0,500)}`)}async deleteMessage(e){var t;const s=await this.fetchImpl(`${this.baseUrl}/v1/chat/message/${e}`,{method:"DELETE",headers:this.authHeaders});if(null===(t=this.logger)||void 0===t||t.log("[chat-sdk] message deleted",{status:s.status}),!s.ok){const e=await s.text();throw new Error(`deleteMessage failed: ${s.status} ${e.slice(0,500)}`)}}async sendTypingStatus(e,t){var s,a;const r={businessID:"user_typing_status",typingStatus:t?1:0,version:1,userAction:14,actionParam:t?"EIMAMSG_InputStatus_Ing":"EIMAMSG_InputStatus_End"};try{await this.postElements(e,[g(m(JSON.stringify(r)))])}catch(e){null===(s=this.logger)||void 0===s||s.error("[chat-sdk] typing status failed",null!==(a=null==e?void 0:e.message)&&void 0!==a?a:String(e))}}async sendStreamingChunk(e,t,s,a){const r={businessID:"chatbotPlugin",src:0,chunks:t,isFinished:s,TMessageCell_Name:"ChatbotMessageCell_Minimalist",TMessageCell_Data_Name:"ChatbotMessageCellData"},o={msgID:e,...g(m(JSON.stringify(r)))},n=await this.postElements(e,[o],a?"POST":"PATCH");if(!n.ok)throw new Error(`sendStreamingChunk failed: ${n.statusText}`);await n.text()}async sendMiniAppMessage(e,t){var s;const a=await this.postElements(e,[h(t)]),r=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] miniapp card sent",{status:a.status}),!a.ok)throw new Error(`sendMiniAppMessage failed: ${a.status} ${r}`)}async sendWebLinkMessage(e,s){var a;const r={businessID:t,url:s},o=await this.postElements(e,[g(m(JSON.stringify(r)))]),n=await o.text();if(null===(a=this.logger)||void 0===a||a.log("[chat-sdk] web link sent",{status:o.status}),!o.ok)throw new Error(`sendWebLinkMessage failed: ${o.status} ${n.slice(0,500)}`)}async sendChoicesMessage(e,t){var a,r,o;const n=this.newMsgID(),i={businessID:s,promptId:null!==(a=t.promptId)&&void 0!==a?a:this.newMsgID(),prompt:t.prompt,selectionMode:null!==(r=t.selectionMode)&&void 0!==r?r:"single",choices:t.choices},l=await this.postElements(e,[{msgID:n,...g(m(JSON.stringify(i)))}]),u=await l.text();if(null===(o=this.logger)||void 0===o||o.log("[chat-sdk] choices message sent",{status:l.status}),!l.ok)throw new Error(`sendChoicesMessage failed: ${l.status} ${u.slice(0,500)}`);return n}async sendOfficialAccountTweetMessage(e,t){var s;const r=this.newMsgID(),o={businessID:a,...t},n=await this.postElements(e,[{msgID:r,...g(m(JSON.stringify(o)))}]),i=await n.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] official account tweet sent",{status:n.status}),!n.ok)throw new Error(`sendOfficialAccountTweetMessage failed: ${n.status} ${i.slice(0,500)}`);return r}async streamMessage(e,t,s=10){const a=f(t,s),r=[];for(let t=0;t<a.length;t++)r.push(a[t]),await this.sendStreamingChunk(e,r,t===a.length-1,0===t)}}w.ElemType=exports.ElemType,exports.AI_CHOICE_PROMPT_BUSINESS_ID=s,exports.DEFAULT_BASE_URL=e,exports.OFFICIAL_ACCOUNT_TWEET_BUSINESS_ID=a,exports.WEB_LINK_BUSINESS_ID=t,exports.arrayBufferToBase64=function(e){let t="";const s=new Uint8Array(e),a=s.byteLength;for(let e=0;e<a;e++)t+=String.fromCharCode(s[e]);return btoa(t)},exports.base64ToArrayBuffer=function(e){const t=atob(e),s=t.length,a=new Uint8Array(s);for(let e=0;e<s;e++)a[e]=t.charCodeAt(e);return a.buffer},exports.chatClient=function(e){return new w({token:e})},exports.customElem=g,exports.fileElem=l,exports.getAccessToken=r,exports.imageElem=i,exports.miniAppElem=h,exports.quoteTextElem=d,exports.soundElem=u,exports.splitIntoChunks=f,exports.stickerElem=c,exports.textElem=n,exports.toBase64=m,exports.verifyWebhookSignature=async function(e,t,s,a={}){const{toleranceSec:r=300,logger:o}=a,n=e.headers.get("X-Webhook-Signature");if(!n)return null==o||o.error("[chat-sdk] webhook missing X-Webhook-Signature header"),{valid:!1,error:"Missing X-Webhook-Signature header"};const i=e.headers.get("X-Webhook-Timestamp");if(!i)return null==o||o.error("[chat-sdk] webhook missing X-Webhook-Timestamp header"),{valid:!1,error:"Missing X-Webhook-Timestamp header"};const l=n.startsWith("sha256=")?n.slice(7):n,u=await async function(e,t){const s=new TextEncoder,a=await crypto.subtle.importKey("raw",s.encode(e),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),r=await crypto.subtle.sign("HMAC",a,s.encode(t));return[...new Uint8Array(r)].map((e=>e.toString(16).padStart(2,"0"))).join("")}(t,`${i}.${s}`);if(!function(e,t){if(e.length!==t.length)return!1;let s=0;for(let a=0;a<e.length;a++)s|=e.charCodeAt(a)^t.charCodeAt(a);return 0===s}(l,u))return null==o||o.error("[chat-sdk] webhook invalid signature"),{valid:!1,error:"Invalid signature"};const c=parseInt(i,10),d=Math.floor(Date.now()/1e3);return!Number.isFinite(c)||Math.abs(d-c)>r?(null==o||o.error("[chat-sdk] webhook timestamp out of range"),{valid:!1,error:"Request timestamp too old or too far in future"}):(null==o||o.log("[chat-sdk] webhook signature valid"),{valid:!0})};
|
|
2
2
|
//# sourceMappingURL=main.cjs.js.map
|
package/dist/main.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const t="https://chat-api2-3rnt.onrender.com",e="web_link",s="ai_choice_prompt",a="official_account_tweet";async function n(e){var s;const{clientId:a,clientSecret:n}=e;if(!a||!n)throw new Error("getAccessToken: clientId and clientSecret are required");const i=t.replace(/\/$/,""),r=null!==(s=e.scope)&&void 0!==s?s:"chat:write uploads:write";if("undefined"==typeof fetch)throw new Error("getAccessToken: global fetch is not available");const o=await fetch(`${i}/v1/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"client_credentials",client_id:a,client_secret:n,scope:r})});if(!o.ok)throw new Error(`Token request failed: ${o.status} ${o.statusText}`);return await o.json()}var i;function r(t){return{elemType:i.Text,priority:0,textElem:{text:t.trim()}}}function o(t){return{elemType:i.Image,priority:0,imageElem:{upload_ids:t}}}function l(t){return{elemType:i.File,priority:0,fileElem:{upload_ids:t}}}function u(t,e=0){return{elemType:i.Sound,priority:0,soundElem:{uploadID:t,duration:e}}}function c(t,e){return{elemType:i.Sticker,priority:0,stickerElem:{packID:t,stickerID:e}}}function d(t){return{elemType:i.Custom,priority:0,customElem:{data:t}}}function h(t){return{elemType:i.MiniApp,priority:0,miniAppElem:t}}function g(t){const e=new Uint8Array(t.byteLength);return e.set(t),e}function p(t){let e="";const s=new Uint8Array(t),a=s.byteLength;for(let t=0;t<a;t++)e+=String.fromCharCode(s[t]);return btoa(e)}function m(t){const e=atob(t),s=e.length,a=new Uint8Array(s);for(let t=0;t<s;t++)a[t]=e.charCodeAt(t);return a.buffer}function f(t){const e=(new TextEncoder).encode(t);let s="";for(const t of e)s+=String.fromCharCode(t);return btoa(s)}function w(t,e=10){if(t.length<=e)return[t];const s=[];let a="";for(const n of t.split(" "))a.length+n.length+1>e&&a.length>0?(s.push(a.trim()+" "),a=n):a+=(a?" ":"")+n;return a&&s.push(a.trim()),s.length>0?s:[t]}function k(t){return new y({token:t})}!function(t){t[t.None=0]="None",t[t.Text=1]="Text",t[t.Image=2]="Image",t[t.Sound=3]="Sound",t[t.Video=4]="Video",t[t.File=5]="File",t[t.Sticker=6]="Sticker",t[t.GroupTips=7]="GroupTips",t[t.Merger=8]="Merger",t[t.Custom=9]="Custom",t[t.Location=10]="Location",t[t.GroupAnnouncement=11]="GroupAnnouncement",t[t.Quote=12]="Quote",t[t.InputStatus=14]="InputStatus",t[t.TypingStatus=15]="TypingStatus",t[t.MiniApp=16]="MiniApp",t[t.Order=17]="Order",t[t.Transfer=18]="Transfer"}(i||(i={}));class y{constructor(e){var s,a;if(!(null==e?void 0:e.token))throw new Error("ChatClient: token is required");this.token=e.token,this.baseUrl=(null!==(s=e.baseUrl)&&void 0!==s?s:t).replace(/\/$/,""),this.logger=e.logger;const n=null!==(a=e.fetch)&&void 0!==a?a:"undefined"!=typeof fetch?fetch:void 0;if(!n)throw new Error("ChatClient: no fetch implementation available; pass `fetch` in options");this.fetchImpl=n.bind(globalThis)}static async fromCredentials(t){const{access_token:e}=await n({clientId:t.clientId,clientSecret:t.clientSecret,scope:t.scope});return new y({token:e,baseUrl:t.baseUrl,logger:t.logger,fetch:t.fetch})}get authHeaders(){return{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`}}replyUrl(t){return`${this.baseUrl}/v1/chat/message/${t}/reply`}newMsgID(){return globalThis.crypto.randomUUID()}async postElements(t,e,s="POST"){return await this.fetchImpl(this.replyUrl(t),{method:s,headers:this.authHeaders,body:JSON.stringify(e)})}async uploadImage(t,e,s="image/png"){var a;const n=new FormData;n.append("file",new Blob([g(t)],{type:s}),e);const i=await this.fetchImpl(`${this.baseUrl}/v1/upload/image`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:n}),r=await i.json();if(!i.ok)throw new Error(`uploadImage failed: ${i.status} ${JSON.stringify(r)}`);if(!r.upload_id)throw new Error(`uploadImage: missing upload_id: ${JSON.stringify(r)}`);return{upload_id:r.upload_id,url:null!==(a=r.url)&&void 0!==a?a:""}}async uploadFile(t,e,s="application/octet-stream"){var a;const n=new FormData;n.append("file",new Blob([g(t)],{type:s}),e);const i=await this.fetchImpl(`${this.baseUrl}/v1/upload/file`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:n}),r=await i.json();if(!i.ok)throw new Error(`uploadFile failed: ${i.status} ${JSON.stringify(r)}`);if(!r.upload_id)throw new Error(`uploadFile: missing upload_id: ${JSON.stringify(r)}`);return{upload_id:r.upload_id,url:null!==(a=r.url)&&void 0!==a?a:""}}async sendMessage(t,e,s){var a;let n=Array.isArray(e)?e.map((t=>t.trim())).filter(Boolean).map(r):[r(e)];if(0===n.length)return;s&&(n=n.map((t=>({...t,msgID:s}))));const i=await this.postElements(t,n),o=await i.text();if(null===(a=this.logger)||void 0===a||a.log("[chat-sdk] message sent",{status:i.status,elements:n.length}),!i.ok)throw new Error(`sendMessage failed: ${i.status} ${o}`)}async sendImageMessage(t,e){var s;if(!(null==e?void 0:e.length))return;const a=await this.postElements(t,[o(e)]),n=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] image message sent",{status:a.status}),!a.ok)throw new Error(`sendImageMessage failed: ${a.status} ${n}`)}async sendFileMessage(t,e){var s;if(!(null==e?void 0:e.length))return;const a=await this.postElements(t,[l(e)]),n=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] file message sent",{status:a.status}),!a.ok)throw new Error(`sendFileMessage failed: ${a.status} ${n}`)}async sendSoundMessage(t,e,s=0){var a;if(!(null==e?void 0:e.trim()))return;const n=await this.postElements(t,[u(e,s)]),i=await n.text();if(null===(a=this.logger)||void 0===a||a.log("[chat-sdk] sound message sent",{status:n.status}),!n.ok)throw new Error(`sendSoundMessage failed: ${n.status} ${i.slice(0,500)}`)}async sendStickerMessage(t,e,s,a){var n;if(!(null==e?void 0:e.trim())||!(null==s?void 0:s.trim()))return;const i=c(e,s),r=await this.postElements(t,[a?{...i,msgID:a}:i]),o=await r.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] sticker message sent",{status:r.status}),!r.ok)throw new Error(`sendStickerMessage failed: ${r.status} ${o}`)}async editTextMessage(t,e){var s;const a=await this.postElements(t,[{msgID:t,...r(e)}]),n=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] text message edited",{status:a.status}),!a.ok)throw new Error(`editTextMessage failed: ${a.status} ${n.slice(0,500)}`)}async editStickerMessage(t,e,s){var a;const n=await this.postElements(t,[{msgID:t,...c(e,s)}]),i=await n.text();if(null===(a=this.logger)||void 0===a||a.log("[chat-sdk] sticker message edited",{status:n.status}),!n.ok)throw new Error(`editStickerMessage failed: ${n.status} ${i.slice(0,500)}`)}async editImageMessage(t,e){var s;const a=await this.postElements(t,[{msgID:t,...o(e)}]),n=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] image message edited",{status:a.status}),!a.ok)throw new Error(`editImageMessage failed: ${a.status} ${n.slice(0,500)}`)}async deleteMessage(t){var e;const s=await this.fetchImpl(`${this.baseUrl}/v1/chat/message/${t}`,{method:"DELETE",headers:this.authHeaders});if(null===(e=this.logger)||void 0===e||e.log("[chat-sdk] message deleted",{status:s.status}),!s.ok){const t=await s.text();throw new Error(`deleteMessage failed: ${s.status} ${t.slice(0,500)}`)}}async sendTypingStatus(t,e){var s,a;const n={businessID:"user_typing_status",typingStatus:e?1:0,version:1,userAction:14,actionParam:e?"EIMAMSG_InputStatus_Ing":"EIMAMSG_InputStatus_End"};try{await this.postElements(t,[d(f(JSON.stringify(n)))])}catch(t){null===(s=this.logger)||void 0===s||s.error("[chat-sdk] typing status failed",null!==(a=null==t?void 0:t.message)&&void 0!==a?a:String(t))}}async sendStreamingChunk(t,e,s,a){const n={businessID:"chatbotPlugin",src:0,chunks:e,isFinished:s,TMessageCell_Name:"ChatbotMessageCell_Minimalist",TMessageCell_Data_Name:"ChatbotMessageCellData"},i={msgID:t,...d(f(JSON.stringify(n)))},r=await this.postElements(t,[i],a?"POST":"PATCH");if(!r.ok)throw new Error(`sendStreamingChunk failed: ${r.statusText}`);await r.text()}async sendMiniAppMessage(t,e){var s;const a=await this.postElements(t,[h(e)]),n=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] miniapp card sent",{status:a.status}),!a.ok)throw new Error(`sendMiniAppMessage failed: ${a.status} ${n}`)}async sendWebLinkMessage(t,s){var a;const n={businessID:e,url:s},i=await this.postElements(t,[d(f(JSON.stringify(n)))]),r=await i.text();if(null===(a=this.logger)||void 0===a||a.log("[chat-sdk] web link sent",{status:i.status}),!i.ok)throw new Error(`sendWebLinkMessage failed: ${i.status} ${r.slice(0,500)}`)}async sendChoicesMessage(t,e){var a,n,i;const r=this.newMsgID(),o={businessID:s,promptId:null!==(a=e.promptId)&&void 0!==a?a:this.newMsgID(),prompt:e.prompt,selectionMode:null!==(n=e.selectionMode)&&void 0!==n?n:"single",choices:e.choices},l=await this.postElements(t,[{msgID:r,...d(f(JSON.stringify(o)))}]),u=await l.text();if(null===(i=this.logger)||void 0===i||i.log("[chat-sdk] choices message sent",{status:l.status}),!l.ok)throw new Error(`sendChoicesMessage failed: ${l.status} ${u.slice(0,500)}`);return r}async sendOfficialAccountTweetMessage(t,e){var s;const n=this.newMsgID(),i={businessID:a,...e},r=await this.postElements(t,[{msgID:n,...d(f(JSON.stringify(i)))}]),o=await r.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] official account tweet sent",{status:r.status}),!r.ok)throw new Error(`sendOfficialAccountTweetMessage failed: ${r.status} ${o.slice(0,500)}`);return n}async streamMessage(t,e,s=10){const a=w(e,s),n=[];for(let e=0;e<a.length;e++)n.push(a[e]),await this.sendStreamingChunk(t,n,e===a.length-1,0===e)}}async function v(t,e,s,a={}){const{toleranceSec:n=300,logger:i}=a,r=t.headers.get("X-Webhook-Signature");if(!r)return null==i||i.error("[chat-sdk] webhook missing X-Webhook-Signature header"),{valid:!1,error:"Missing X-Webhook-Signature header"};const o=t.headers.get("X-Webhook-Timestamp");if(!o)return null==i||i.error("[chat-sdk] webhook missing X-Webhook-Timestamp header"),{valid:!1,error:"Missing X-Webhook-Timestamp header"};const l=r.startsWith("sha256=")?r.slice(7):r,u=await async function(t,e){const s=new TextEncoder,a=await crypto.subtle.importKey("raw",s.encode(t),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),n=await crypto.subtle.sign("HMAC",a,s.encode(e));return[...new Uint8Array(n)].map((t=>t.toString(16).padStart(2,"0"))).join("")}(e,`${o}.${s}`);if(!function(t,e){if(t.length!==e.length)return!1;let s=0;for(let a=0;a<t.length;a++)s|=t.charCodeAt(a)^e.charCodeAt(a);return 0===s}(l,u))return null==i||i.error("[chat-sdk] webhook invalid signature"),{valid:!1,error:"Invalid signature"};const c=parseInt(o,10),d=Math.floor(Date.now()/1e3);return!Number.isFinite(c)||Math.abs(d-c)>n?(null==i||i.error("[chat-sdk] webhook timestamp out of range"),{valid:!1,error:"Request timestamp too old or too far in future"}):(null==i||i.log("[chat-sdk] webhook signature valid"),{valid:!0})}y.ElemType=i;export{s as AI_CHOICE_PROMPT_BUSINESS_ID,t as DEFAULT_BASE_URL,i as ElemType,a as OFFICIAL_ACCOUNT_TWEET_BUSINESS_ID,e as WEB_LINK_BUSINESS_ID,p as arrayBufferToBase64,m as base64ToArrayBuffer,k as chatClient,d as customElem,l as fileElem,n as getAccessToken,o as imageElem,h as miniAppElem,u as soundElem,w as splitIntoChunks,c as stickerElem,r as textElem,f as toBase64,v as verifyWebhookSignature};
|
|
1
|
+
const e="https://chat-api2-3rnt.onrender.com",t="web_link",s="ai_choice_prompt",a="official_account_tweet";async function n(t){var s;const{clientId:a,clientSecret:n}=t;if(!a||!n)throw new Error("getAccessToken: clientId and clientSecret are required");const i=e.replace(/\/$/,""),r=null!==(s=t.scope)&&void 0!==s?s:"chat:write uploads:write";if("undefined"==typeof fetch)throw new Error("getAccessToken: global fetch is not available");const o=await fetch(`${i}/v1/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"client_credentials",client_id:a,client_secret:n,scope:r})});if(!o.ok)throw new Error(`Token request failed: ${o.status} ${o.statusText}`);return await o.json()}var i;function r(e){return{elemType:i.Text,priority:0,textElem:{text:e.trim()}}}function o(e){return{elemType:i.Image,priority:0,imageElem:{upload_ids:e}}}function l(e){return{elemType:i.File,priority:0,fileElem:{upload_ids:e}}}function u(e,t=0){return{elemType:i.Sound,priority:0,soundElem:{uploadID:e,duration:t}}}function c(e,t){return{elemType:i.Sticker,priority:0,stickerElem:{packID:e,stickerID:t}}}function d(e,t,s){const a={...r(e),cloudCustomData:{messageReply:t}};return s?{msgID:s,...a}:a}function g(e){return{elemType:i.Custom,priority:0,customElem:{data:e}}}function h(e){return{elemType:i.MiniApp,priority:0,miniAppElem:e}}function p(e){const t=new Uint8Array(e.byteLength);return t.set(e),t}function m(e){let t="";const s=new Uint8Array(e),a=s.byteLength;for(let e=0;e<a;e++)t+=String.fromCharCode(s[e]);return btoa(t)}function f(e){const t=atob(e),s=t.length,a=new Uint8Array(s);for(let e=0;e<s;e++)a[e]=t.charCodeAt(e);return a.buffer}function w(e){const t=(new TextEncoder).encode(e);let s="";for(const e of t)s+=String.fromCharCode(e);return btoa(s)}function y(e,t=10){if(e.length<=t)return[e];const s=[];let a="";for(const n of e.split(" "))a.length+n.length+1>t&&a.length>0?(s.push(a.trim()+" "),a=n):a+=(a?" ":"")+n;return a&&s.push(a.trim()),s.length>0?s:[e]}function k(e){return new v({token:e})}!function(e){e[e.None=0]="None",e[e.Text=1]="Text",e[e.Image=2]="Image",e[e.Sound=3]="Sound",e[e.Video=4]="Video",e[e.File=5]="File",e[e.Sticker=6]="Sticker",e[e.GroupTips=7]="GroupTips",e[e.Merger=8]="Merger",e[e.Custom=9]="Custom",e[e.Location=10]="Location",e[e.GroupAnnouncement=11]="GroupAnnouncement",e[e.Quote=12]="Quote",e[e.InputStatus=14]="InputStatus",e[e.TypingStatus=15]="TypingStatus",e[e.MiniApp=16]="MiniApp",e[e.Order=17]="Order",e[e.Transfer=18]="Transfer"}(i||(i={}));class v{constructor(t){var s,a;if(!(null==t?void 0:t.token))throw new Error("ChatClient: token is required");this.token=t.token,this.baseUrl=(null!==(s=t.baseUrl)&&void 0!==s?s:e).replace(/\/$/,""),this.logger=t.logger;const n=null!==(a=t.fetch)&&void 0!==a?a:"undefined"!=typeof fetch?fetch:void 0;if(!n)throw new Error("ChatClient: no fetch implementation available; pass `fetch` in options");this.fetchImpl=n.bind(globalThis)}static async fromCredentials(e){const{access_token:t}=await n({clientId:e.clientId,clientSecret:e.clientSecret,scope:e.scope});return new v({token:t,baseUrl:e.baseUrl,logger:e.logger,fetch:e.fetch})}get authHeaders(){return{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`}}replyUrl(e){return`${this.baseUrl}/v1/chat/message/${e}/reply`}newMsgID(){return globalThis.crypto.randomUUID()}async postElements(e,t,s="POST"){return await this.fetchImpl(this.replyUrl(e),{method:s,headers:this.authHeaders,body:JSON.stringify(t)})}async uploadImage(e,t,s="image/png"){var a;const n=new FormData;n.append("file",new Blob([p(e)],{type:s}),t);const i=await this.fetchImpl(`${this.baseUrl}/v1/upload/image`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:n}),r=await i.json();if(!i.ok)throw new Error(`uploadImage failed: ${i.status} ${JSON.stringify(r)}`);if(!r.upload_id)throw new Error(`uploadImage: missing upload_id: ${JSON.stringify(r)}`);return{upload_id:r.upload_id,url:null!==(a=r.url)&&void 0!==a?a:""}}async uploadFile(e,t,s="application/octet-stream"){var a;const n=new FormData;n.append("file",new Blob([p(e)],{type:s}),t);const i=await this.fetchImpl(`${this.baseUrl}/v1/upload/file`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:n}),r=await i.json();if(!i.ok)throw new Error(`uploadFile failed: ${i.status} ${JSON.stringify(r)}`);if(!r.upload_id)throw new Error(`uploadFile: missing upload_id: ${JSON.stringify(r)}`);return{upload_id:r.upload_id,url:null!==(a=r.url)&&void 0!==a?a:""}}async sendMessage(e,t,s){var a;let n=Array.isArray(t)?t.map((e=>e.trim())).filter(Boolean).map(r):[r(t)];if(0===n.length)return;s&&(n=n.map((e=>({...e,msgID:s}))));const i=await this.postElements(e,n),o=await i.text();if(null===(a=this.logger)||void 0===a||a.log("[chat-sdk] message sent",{status:i.status,elements:n.length}),!i.ok)throw new Error(`sendMessage failed: ${i.status} ${o}`)}async sendQuoteMessage(e,t,s){var a,n,i,r;const o=null!==(a=s.replyMsgID)&&void 0!==a?a:this.newMsgID(),l=d(t,{messageID:s.quotedMessageID,messageAbstract:s.messageAbstract,messageSender:s.messageSender,messageType:null!==(n=s.messageType)&&void 0!==n?n:1,version:null!==(i=s.version)&&void 0!==i?i:1},o),u=await this.postElements(e,[l]),c=await u.text();if(null===(r=this.logger)||void 0===r||r.log("[chat-sdk] quote message sent",{status:u.status}),!u.ok)throw new Error(`sendQuoteMessage failed: ${u.status} ${c}`);return o}async sendImageMessage(e,t){var s;if(!(null==t?void 0:t.length))return;const a=await this.postElements(e,[o(t)]),n=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] image message sent",{status:a.status}),!a.ok)throw new Error(`sendImageMessage failed: ${a.status} ${n}`)}async sendFileMessage(e,t){var s;if(!(null==t?void 0:t.length))return;const a=await this.postElements(e,[l(t)]),n=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] file message sent",{status:a.status}),!a.ok)throw new Error(`sendFileMessage failed: ${a.status} ${n}`)}async sendSoundMessage(e,t,s=0){var a;if(!(null==t?void 0:t.trim()))return;const n=await this.postElements(e,[u(t,s)]),i=await n.text();if(null===(a=this.logger)||void 0===a||a.log("[chat-sdk] sound message sent",{status:n.status}),!n.ok)throw new Error(`sendSoundMessage failed: ${n.status} ${i.slice(0,500)}`)}async sendStickerMessage(e,t,s,a){var n;if(!(null==t?void 0:t.trim())||!(null==s?void 0:s.trim()))return;const i=c(t,s),r=await this.postElements(e,[a?{...i,msgID:a}:i]),o=await r.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] sticker message sent",{status:r.status}),!r.ok)throw new Error(`sendStickerMessage failed: ${r.status} ${o}`)}async editTextMessage(e,t){var s;const a=await this.postElements(e,[{msgID:e,...r(t)}]),n=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] text message edited",{status:a.status}),!a.ok)throw new Error(`editTextMessage failed: ${a.status} ${n.slice(0,500)}`)}async editStickerMessage(e,t,s){var a;const n=await this.postElements(e,[{msgID:e,...c(t,s)}]),i=await n.text();if(null===(a=this.logger)||void 0===a||a.log("[chat-sdk] sticker message edited",{status:n.status}),!n.ok)throw new Error(`editStickerMessage failed: ${n.status} ${i.slice(0,500)}`)}async editImageMessage(e,t){var s;const a=await this.postElements(e,[{msgID:e,...o(t)}]),n=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] image message edited",{status:a.status}),!a.ok)throw new Error(`editImageMessage failed: ${a.status} ${n.slice(0,500)}`)}async deleteMessage(e){var t;const s=await this.fetchImpl(`${this.baseUrl}/v1/chat/message/${e}`,{method:"DELETE",headers:this.authHeaders});if(null===(t=this.logger)||void 0===t||t.log("[chat-sdk] message deleted",{status:s.status}),!s.ok){const e=await s.text();throw new Error(`deleteMessage failed: ${s.status} ${e.slice(0,500)}`)}}async sendTypingStatus(e,t){var s,a;const n={businessID:"user_typing_status",typingStatus:t?1:0,version:1,userAction:14,actionParam:t?"EIMAMSG_InputStatus_Ing":"EIMAMSG_InputStatus_End"};try{await this.postElements(e,[g(w(JSON.stringify(n)))])}catch(e){null===(s=this.logger)||void 0===s||s.error("[chat-sdk] typing status failed",null!==(a=null==e?void 0:e.message)&&void 0!==a?a:String(e))}}async sendStreamingChunk(e,t,s,a){const n={businessID:"chatbotPlugin",src:0,chunks:t,isFinished:s,TMessageCell_Name:"ChatbotMessageCell_Minimalist",TMessageCell_Data_Name:"ChatbotMessageCellData"},i={msgID:e,...g(w(JSON.stringify(n)))},r=await this.postElements(e,[i],a?"POST":"PATCH");if(!r.ok)throw new Error(`sendStreamingChunk failed: ${r.statusText}`);await r.text()}async sendMiniAppMessage(e,t){var s;const a=await this.postElements(e,[h(t)]),n=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] miniapp card sent",{status:a.status}),!a.ok)throw new Error(`sendMiniAppMessage failed: ${a.status} ${n}`)}async sendWebLinkMessage(e,s){var a;const n={businessID:t,url:s},i=await this.postElements(e,[g(w(JSON.stringify(n)))]),r=await i.text();if(null===(a=this.logger)||void 0===a||a.log("[chat-sdk] web link sent",{status:i.status}),!i.ok)throw new Error(`sendWebLinkMessage failed: ${i.status} ${r.slice(0,500)}`)}async sendChoicesMessage(e,t){var a,n,i;const r=this.newMsgID(),o={businessID:s,promptId:null!==(a=t.promptId)&&void 0!==a?a:this.newMsgID(),prompt:t.prompt,selectionMode:null!==(n=t.selectionMode)&&void 0!==n?n:"single",choices:t.choices},l=await this.postElements(e,[{msgID:r,...g(w(JSON.stringify(o)))}]),u=await l.text();if(null===(i=this.logger)||void 0===i||i.log("[chat-sdk] choices message sent",{status:l.status}),!l.ok)throw new Error(`sendChoicesMessage failed: ${l.status} ${u.slice(0,500)}`);return r}async sendOfficialAccountTweetMessage(e,t){var s;const n=this.newMsgID(),i={businessID:a,...t},r=await this.postElements(e,[{msgID:n,...g(w(JSON.stringify(i)))}]),o=await r.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] official account tweet sent",{status:r.status}),!r.ok)throw new Error(`sendOfficialAccountTweetMessage failed: ${r.status} ${o.slice(0,500)}`);return n}async streamMessage(e,t,s=10){const a=y(t,s),n=[];for(let t=0;t<a.length;t++)n.push(a[t]),await this.sendStreamingChunk(e,n,t===a.length-1,0===t)}}async function M(e,t,s,a={}){const{toleranceSec:n=300,logger:i}=a,r=e.headers.get("X-Webhook-Signature");if(!r)return null==i||i.error("[chat-sdk] webhook missing X-Webhook-Signature header"),{valid:!1,error:"Missing X-Webhook-Signature header"};const o=e.headers.get("X-Webhook-Timestamp");if(!o)return null==i||i.error("[chat-sdk] webhook missing X-Webhook-Timestamp header"),{valid:!1,error:"Missing X-Webhook-Timestamp header"};const l=r.startsWith("sha256=")?r.slice(7):r,u=await async function(e,t){const s=new TextEncoder,a=await crypto.subtle.importKey("raw",s.encode(e),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),n=await crypto.subtle.sign("HMAC",a,s.encode(t));return[...new Uint8Array(n)].map((e=>e.toString(16).padStart(2,"0"))).join("")}(t,`${o}.${s}`);if(!function(e,t){if(e.length!==t.length)return!1;let s=0;for(let a=0;a<e.length;a++)s|=e.charCodeAt(a)^t.charCodeAt(a);return 0===s}(l,u))return null==i||i.error("[chat-sdk] webhook invalid signature"),{valid:!1,error:"Invalid signature"};const c=parseInt(o,10),d=Math.floor(Date.now()/1e3);return!Number.isFinite(c)||Math.abs(d-c)>n?(null==i||i.error("[chat-sdk] webhook timestamp out of range"),{valid:!1,error:"Request timestamp too old or too far in future"}):(null==i||i.log("[chat-sdk] webhook signature valid"),{valid:!0})}v.ElemType=i;export{s as AI_CHOICE_PROMPT_BUSINESS_ID,e as DEFAULT_BASE_URL,i as ElemType,a as OFFICIAL_ACCOUNT_TWEET_BUSINESS_ID,t as WEB_LINK_BUSINESS_ID,m as arrayBufferToBase64,f as base64ToArrayBuffer,k as chatClient,g as customElem,l as fileElem,n as getAccessToken,o as imageElem,h as miniAppElem,d as quoteTextElem,u as soundElem,y as splitIntoChunks,c as stickerElem,r as textElem,w as toBase64,M as verifyWebhookSignature};
|
|
2
2
|
//# sourceMappingURL=main.esm.js.map
|
package/dist/types/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChatClientOptions, ChoicesPrompt, ElemType, Logger, MiniAppElem, OfficialAccountTweet, UploadV1FileResponse, UploadV1ImageResponse } from "./types";
|
|
1
|
+
import { ChatClientOptions, ChoicesPrompt, ElemType, Logger, MiniAppElem, OfficialAccountTweet, QuoteReply, UploadV1FileResponse, UploadV1ImageResponse } from "./types";
|
|
2
2
|
/** Build a one-off ChatClient bound to a bearer token (shorthand for `new ChatClient({ token })`). */
|
|
3
3
|
export declare function chatClient(token: string): ChatClient;
|
|
4
4
|
/**
|
|
@@ -49,6 +49,13 @@ declare class ChatClient {
|
|
|
49
49
|
* be edited via {@link editTextMessage}); it is applied to every element sent.
|
|
50
50
|
*/
|
|
51
51
|
sendMessage(msgID: string, message: string | string[], replyMsgID?: string): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Send a text reply that quotes another message (persists
|
|
54
|
+
* `cloudCustomData.messageReply` so the quoted preview renders). `parentMsgID`
|
|
55
|
+
* is the message being replied to — usually the same as `quote.quotedMessageID`
|
|
56
|
+
* when quoting that message. Returns the new reply's id.
|
|
57
|
+
*/
|
|
58
|
+
sendQuoteMessage(parentMsgID: string, text: string, quote: QuoteReply): Promise<string>;
|
|
52
59
|
/** Send an image message by upload_id(s) (use uploadImage first). */
|
|
53
60
|
sendImageMessage(msgID: string, uploadIDs: string[]): Promise<void>;
|
|
54
61
|
/** Send a file message by upload_id(s) (use uploadFile first). */
|
package/dist/types/elements.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MessageElem, MiniAppElem } from './types';
|
|
1
|
+
import { MessageElem, MessageReplyCloudCustom, MiniAppElem } from './types';
|
|
2
2
|
/** Single text message element for the chat API body. */
|
|
3
3
|
export declare function textElem(text: string): MessageElem;
|
|
4
4
|
/** Single image message element (requires upload_ids from uploadImage). */
|
|
@@ -9,6 +9,11 @@ export declare function fileElem(uploadIDs: string[]): MessageElem;
|
|
|
9
9
|
export declare function soundElem(uploadID: string, durationSec?: number): MessageElem;
|
|
10
10
|
/** Single sticker message element (pack + sticker identifiers). */
|
|
11
11
|
export declare function stickerElem(packID: string, stickerID: string): MessageElem;
|
|
12
|
+
/**
|
|
13
|
+
* Text element that quotes another message (persists cloudCustomData.messageReply
|
|
14
|
+
* so the quoted preview renders). Pass `msgID` to assign the reply a known id.
|
|
15
|
+
*/
|
|
16
|
+
export declare function quoteTextElem(text: string, reply: MessageReplyCloudCustom, msgID?: string): MessageElem;
|
|
12
17
|
/** Single custom message element carrying a base64-encoded payload. */
|
|
13
18
|
export declare function customElem(dataBase64: string): MessageElem;
|
|
14
19
|
/** Single miniapp card message element. */
|
package/dist/types/types.d.ts
CHANGED
|
@@ -41,6 +41,32 @@ export type StickerElem = {
|
|
|
41
41
|
packID: string;
|
|
42
42
|
stickerID: string;
|
|
43
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* cloudCustomData.messageReply — the quoted-message preview persisted on a
|
|
46
|
+
* reply (POST /v1/chat/message/{parentMsgID}/reply).
|
|
47
|
+
*/
|
|
48
|
+
export type MessageReplyCloudCustom = {
|
|
49
|
+
messageID: string;
|
|
50
|
+
messageAbstract: string;
|
|
51
|
+
messageSender: string;
|
|
52
|
+
messageType: number;
|
|
53
|
+
version: number;
|
|
54
|
+
};
|
|
55
|
+
/** Describes the message being quoted in a quote reply. */
|
|
56
|
+
export type QuoteReply = {
|
|
57
|
+
/** The id of the message being quoted. */
|
|
58
|
+
quotedMessageID: string;
|
|
59
|
+
/** Short preview text shown for the quoted message. */
|
|
60
|
+
messageAbstract: string;
|
|
61
|
+
/** Display name of the quoted message's sender. */
|
|
62
|
+
messageSender: string;
|
|
63
|
+
/** ElemType of the quoted message. Defaults to 1 (text). */
|
|
64
|
+
messageType?: number;
|
|
65
|
+
/** cloudCustomData schema version. Defaults to 1. */
|
|
66
|
+
version?: number;
|
|
67
|
+
/** Optional id to assign the outgoing reply (so it can be edited later). */
|
|
68
|
+
replyMsgID?: string;
|
|
69
|
+
};
|
|
44
70
|
/** A single choice in an `ai_choice_prompt` message. */
|
|
45
71
|
export type Choice = {
|
|
46
72
|
id: string;
|
|
@@ -139,6 +165,9 @@ export type MessageElem = {
|
|
|
139
165
|
data: string;
|
|
140
166
|
};
|
|
141
167
|
miniAppElem?: MiniAppElem;
|
|
168
|
+
cloudCustomData?: {
|
|
169
|
+
messageReply: MessageReplyCloudCustom;
|
|
170
|
+
};
|
|
142
171
|
};
|
|
143
172
|
/** Minimal logger interface — pass `console` to enable logging, omit for silence. */
|
|
144
173
|
export interface Logger {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "birdcash-chat-sdk-alpha",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "TypeScript SDK for sending messages through the chat API (text, images, files, miniapp cards, streaming).",
|
|
5
5
|
"main": "dist/main.cjs.js",
|
|
6
6
|
"module": "dist/main.esm.js",
|