birdcash-chat-sdk-alpha 1.0.1 → 1.0.2

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/README.md CHANGED
@@ -54,6 +54,9 @@ await chat.sendFileMessage(msgID, [file.upload_id])
54
54
  const audio = await chat.uploadFile(bytes, 'clip.m4a', 'audio/m4a')
55
55
  await chat.sendSoundMessage(msgID, audio.upload_id, 12)
56
56
 
57
+ // Sticker (by pack + sticker identifiers)
58
+ await chat.sendStickerMessage(msgID, 'weather', 'Cloud with lightning')
59
+
57
60
  // Typing indicator (best effort — never throws)
58
61
  await chat.sendTypingStatus(msgID, true)
59
62
 
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";async function s(t){var s;const{clientId:n,clientSecret:r}=t;if(!n||!r)throw new Error("getAccessToken: clientId and clientSecret are required");const o=e.replace(/\/$/,""),i=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 a=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:n,client_secret:r,scope:i})});if(!a.ok)throw new Error(`Token request failed: ${a.status} ${a.statusText}`);return await a.json()}var n;function r(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 i(e){return{elemType:exports.ElemType.File,priority:0,fileElem:{upload_ids:e}}}function a(e,t=0){return{elemType:exports.ElemType.Sound,priority:0,soundElem:{uploadID:e,duration:t}}}function l(e){return{elemType:exports.ElemType.Custom,priority:0,customElem:{data:e}}}function u(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 c(e){const t=(new TextEncoder).encode(e);let s="";for(const e of t)s+=String.fromCharCode(e);return btoa(s)}function d(e,t=10){if(e.length<=t)return[e];const s=[];let n="";for(const r of e.split(" "))n.length+r.length+1>t&&n.length>0?(s.push(n.trim()+" "),n=r):n+=(n?" ":"")+r;return n&&s.push(n.trim()),s.length>0?s:[e]}exports.ElemType=void 0,(n=exports.ElemType||(exports.ElemType={}))[n.None=0]="None",n[n.Text=1]="Text",n[n.Image=2]="Image",n[n.Sound=3]="Sound",n[n.Video=4]="Video",n[n.File=5]="File",n[n.Sticker=6]="Sticker",n[n.GroupTips=7]="GroupTips",n[n.Merger=8]="Merger",n[n.Custom=9]="Custom",n[n.Location=10]="Location",n[n.GroupAnnouncement=11]="GroupAnnouncement",n[n.Quote=12]="Quote",n[n.InputStatus=14]="InputStatus",n[n.TypingStatus=15]="TypingStatus",n[n.MiniApp=16]="MiniApp",n[n.Order=17]="Order",n[n.Transfer=18]="Transfer";class h{constructor(t){var s,n;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!==(n=t.fetch)&&void 0!==n?n:"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 s({clientId:e.clientId,clientSecret:e.clientSecret,scope:e.scope});return new h({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`}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 n;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}),i=await o.json();if(!o.ok)throw new Error(`uploadImage failed: ${o.status} ${JSON.stringify(i)}`);if(!i.upload_id)throw new Error(`uploadImage: missing upload_id: ${JSON.stringify(i)}`);return{upload_id:i.upload_id,url:null!==(n=i.url)&&void 0!==n?n:""}}async uploadFile(e,t,s="application/octet-stream"){var n;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}),i=await o.json();if(!o.ok)throw new Error(`uploadFile failed: ${o.status} ${JSON.stringify(i)}`);if(!i.upload_id)throw new Error(`uploadFile: missing upload_id: ${JSON.stringify(i)}`);return{upload_id:i.upload_id,url:null!==(n=i.url)&&void 0!==n?n:""}}async sendMessage(e,t){var s;const n=Array.isArray(t)?t.map((e=>e.trim())).filter(Boolean).map(r):[r(t)];if(0===n.length)return;const o=await this.postElements(e,n),i=await o.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] message sent",{status:o.status,elements:n.length}),!o.ok)throw new Error(`sendMessage failed: ${o.status} ${i}`)}async sendImageMessage(e,t){var s;if(!(null==t?void 0:t.length))return;const n=await this.postElements(e,[o(t)]),r=await n.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] image message sent",{status:n.status}),!n.ok)throw new Error(`sendImageMessage failed: ${n.status} ${r}`)}async sendFileMessage(e,t){var s;if(!(null==t?void 0:t.length))return;const n=await this.postElements(e,[i(t)]),r=await n.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] file message sent",{status:n.status}),!n.ok)throw new Error(`sendFileMessage failed: ${n.status} ${r}`)}async sendSoundMessage(e,t,s=0){var n;if(!(null==t?void 0:t.trim()))return;const r=await this.postElements(e,[a(t,s)]),o=await r.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] sound message sent",{status:r.status}),!r.ok)throw new Error(`sendSoundMessage failed: ${r.status} ${o.slice(0,500)}`)}async sendTypingStatus(e,t){var s,n;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,[l(c(JSON.stringify(r)))])}catch(e){null===(s=this.logger)||void 0===s||s.error("[chat-sdk] typing status failed",null!==(n=null==e?void 0:e.message)&&void 0!==n?n:String(e))}}async sendStreamingChunk(e,t,s,n){const r={businessID:"chatbotPlugin",src:0,chunks:t,isFinished:s,TMessageCell_Name:"ChatbotMessageCell_Minimalist",TMessageCell_Data_Name:"ChatbotMessageCellData"},o={msgID:e,...l(c(JSON.stringify(r)))},i=await this.postElements(e,[o],n?"POST":"PATCH");if(!i.ok)throw new Error(`sendStreamingChunk failed: ${i.statusText}`);await i.text()}async sendMiniAppMessage(e,t){var s;const n=await this.postElements(e,[u(t)]),r=await n.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] miniapp card sent",{status:n.status}),!n.ok)throw new Error(`sendMiniAppMessage failed: ${n.status} ${r}`)}async sendWebLinkMessage(e,s){var n;const r={businessID:t,url:s},o=await this.postElements(e,[l(c(JSON.stringify(r)))]),i=await o.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] web link sent",{status:o.status}),!o.ok)throw new Error(`sendWebLinkMessage failed: ${o.status} ${i.slice(0,500)}`)}async streamMessage(e,t,s=10){const n=d(t,s),r=[];for(let t=0;t<n.length;t++)r.push(n[t]),await this.sendStreamingChunk(e,r,t===n.length-1,0===t)}}h.ElemType=exports.ElemType,exports.ChatClient=h,exports.DEFAULT_BASE_URL=e,exports.WEB_LINK_BUSINESS_ID=t,exports.arrayBufferToBase64=function(e){let t="";const s=new Uint8Array(e),n=s.byteLength;for(let e=0;e<n;e++)t+=String.fromCharCode(s[e]);return btoa(t)},exports.base64ToArrayBuffer=function(e){const t=atob(e),s=t.length,n=new Uint8Array(s);for(let e=0;e<s;e++)n[e]=t.charCodeAt(e);return n.buffer},exports.customElem=l,exports.fileElem=i,exports.getAccessToken=s,exports.imageElem=o,exports.miniAppElem=u,exports.soundElem=a,exports.splitIntoChunks=d,exports.textElem=r,exports.toBase64=c;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});const e="https://chat-api2-3rnt.onrender.com",t="web_link";async function s(t){var s;const{clientId:n,clientSecret:r}=t;if(!n||!r)throw new Error("getAccessToken: clientId and clientSecret are required");const i=e.replace(/\/$/,""),o=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 a=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:n,client_secret:r,scope:o})});if(!a.ok)throw new Error(`Token request failed: ${a.status} ${a.statusText}`);return await a.json()}var n;function r(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 o(e){return{elemType:exports.ElemType.File,priority:0,fileElem:{upload_ids:e}}}function a(e,t=0){return{elemType:exports.ElemType.Sound,priority:0,soundElem:{uploadID:e,duration:t}}}function l(e,t){return{elemType:exports.ElemType.Sticker,priority:0,stickerElem:{packID:e,stickerID:t}}}function u(e){return{elemType:exports.ElemType.Custom,priority:0,customElem:{data:e}}}function p(e){return{elemType:exports.ElemType.MiniApp,priority:0,miniAppElem:e}}function c(e){const t=new Uint8Array(e.byteLength);return t.set(e),t}function d(e){const t=(new TextEncoder).encode(e);let s="";for(const e of t)s+=String.fromCharCode(e);return btoa(s)}function h(e,t=10){if(e.length<=t)return[e];const s=[];let n="";for(const r of e.split(" "))n.length+r.length+1>t&&n.length>0?(s.push(n.trim()+" "),n=r):n+=(n?" ":"")+r;return n&&s.push(n.trim()),s.length>0?s:[e]}exports.ElemType=void 0,(n=exports.ElemType||(exports.ElemType={}))[n.None=0]="None",n[n.Text=1]="Text",n[n.Image=2]="Image",n[n.Sound=3]="Sound",n[n.Video=4]="Video",n[n.File=5]="File",n[n.Sticker=6]="Sticker",n[n.GroupTips=7]="GroupTips",n[n.Merger=8]="Merger",n[n.Custom=9]="Custom",n[n.Location=10]="Location",n[n.GroupAnnouncement=11]="GroupAnnouncement",n[n.Quote=12]="Quote",n[n.InputStatus=14]="InputStatus",n[n.TypingStatus=15]="TypingStatus",n[n.MiniApp=16]="MiniApp",n[n.Order=17]="Order",n[n.Transfer=18]="Transfer";class g{constructor(t){var s,n;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!==(n=t.fetch)&&void 0!==n?n:"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 s({clientId:e.clientId,clientSecret:e.clientSecret,scope:e.scope});return new g({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`}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 n;const r=new FormData;r.append("file",new Blob([c(e)],{type:s}),t);const i=await this.fetchImpl(`${this.baseUrl}/v1/upload/image`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:r}),o=await i.json();if(!i.ok)throw new Error(`uploadImage failed: ${i.status} ${JSON.stringify(o)}`);if(!o.upload_id)throw new Error(`uploadImage: missing upload_id: ${JSON.stringify(o)}`);return{upload_id:o.upload_id,url:null!==(n=o.url)&&void 0!==n?n:""}}async uploadFile(e,t,s="application/octet-stream"){var n;const r=new FormData;r.append("file",new Blob([c(e)],{type:s}),t);const i=await this.fetchImpl(`${this.baseUrl}/v1/upload/file`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:r}),o=await i.json();if(!i.ok)throw new Error(`uploadFile failed: ${i.status} ${JSON.stringify(o)}`);if(!o.upload_id)throw new Error(`uploadFile: missing upload_id: ${JSON.stringify(o)}`);return{upload_id:o.upload_id,url:null!==(n=o.url)&&void 0!==n?n:""}}async sendMessage(e,t){var s;const n=Array.isArray(t)?t.map((e=>e.trim())).filter(Boolean).map(r):[r(t)];if(0===n.length)return;const i=await this.postElements(e,n),o=await i.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] message sent",{status:i.status,elements:n.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 n=await this.postElements(e,[i(t)]),r=await n.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] image message sent",{status:n.status}),!n.ok)throw new Error(`sendImageMessage failed: ${n.status} ${r}`)}async sendFileMessage(e,t){var s;if(!(null==t?void 0:t.length))return;const n=await this.postElements(e,[o(t)]),r=await n.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] file message sent",{status:n.status}),!n.ok)throw new Error(`sendFileMessage failed: ${n.status} ${r}`)}async sendSoundMessage(e,t,s=0){var n;if(!(null==t?void 0:t.trim()))return;const r=await this.postElements(e,[a(t,s)]),i=await r.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] sound message sent",{status:r.status}),!r.ok)throw new Error(`sendSoundMessage failed: ${r.status} ${i.slice(0,500)}`)}async sendStickerMessage(e,t,s){var n;if(!(null==t?void 0:t.trim())||!(null==s?void 0:s.trim()))return;const r=await this.postElements(e,[l(t,s)]),i=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} ${i}`)}async sendTypingStatus(e,t){var s,n;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,[u(d(JSON.stringify(r)))])}catch(e){null===(s=this.logger)||void 0===s||s.error("[chat-sdk] typing status failed",null!==(n=null==e?void 0:e.message)&&void 0!==n?n:String(e))}}async sendStreamingChunk(e,t,s,n){const r={businessID:"chatbotPlugin",src:0,chunks:t,isFinished:s,TMessageCell_Name:"ChatbotMessageCell_Minimalist",TMessageCell_Data_Name:"ChatbotMessageCellData"},i={msgID:e,...u(d(JSON.stringify(r)))},o=await this.postElements(e,[i],n?"POST":"PATCH");if(!o.ok)throw new Error(`sendStreamingChunk failed: ${o.statusText}`);await o.text()}async sendMiniAppMessage(e,t){var s;const n=await this.postElements(e,[p(t)]),r=await n.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] miniapp card sent",{status:n.status}),!n.ok)throw new Error(`sendMiniAppMessage failed: ${n.status} ${r}`)}async sendWebLinkMessage(e,s){var n;const r={businessID:t,url:s},i=await this.postElements(e,[u(d(JSON.stringify(r)))]),o=await i.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] web link sent",{status:i.status}),!i.ok)throw new Error(`sendWebLinkMessage failed: ${i.status} ${o.slice(0,500)}`)}async streamMessage(e,t,s=10){const n=h(t,s),r=[];for(let t=0;t<n.length;t++)r.push(n[t]),await this.sendStreamingChunk(e,r,t===n.length-1,0===t)}}g.ElemType=exports.ElemType,exports.ChatClient=g,exports.DEFAULT_BASE_URL=e,exports.WEB_LINK_BUSINESS_ID=t,exports.arrayBufferToBase64=function(e){let t="";const s=new Uint8Array(e),n=s.byteLength;for(let e=0;e<n;e++)t+=String.fromCharCode(s[e]);return btoa(t)},exports.base64ToArrayBuffer=function(e){const t=atob(e),s=t.length,n=new Uint8Array(s);for(let e=0;e<s;e++)n[e]=t.charCodeAt(e);return n.buffer},exports.customElem=u,exports.fileElem=o,exports.getAccessToken=s,exports.imageElem=i,exports.miniAppElem=p,exports.soundElem=a,exports.splitIntoChunks=h,exports.stickerElem=l,exports.textElem=r,exports.toBase64=d;
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";async function n(e){var n;const{clientId:s,clientSecret:i}=e;if(!s||!i)throw new Error("getAccessToken: clientId and clientSecret are required");const a=t.replace(/\/$/,""),r=null!==(n=e.scope)&&void 0!==n?n:"chat:write uploads:write";if("undefined"==typeof fetch)throw new Error("getAccessToken: global fetch is not available");const o=await fetch(`${a}/v1/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"client_credentials",client_id:s,client_secret:i,scope:r})});if(!o.ok)throw new Error(`Token request failed: ${o.status} ${o.statusText}`);return await o.json()}var s;function i(t){return{elemType:s.Text,priority:0,textElem:{text:t.trim()}}}function a(t){return{elemType:s.Image,priority:0,imageElem:{upload_ids:t}}}function r(t){return{elemType:s.File,priority:0,fileElem:{upload_ids:t}}}function o(t,e=0){return{elemType:s.Sound,priority:0,soundElem:{uploadID:t,duration:e}}}function l(t){return{elemType:s.Custom,priority:0,customElem:{data:t}}}function u(t){return{elemType:s.MiniApp,priority:0,miniAppElem:t}}function c(t){const e=new Uint8Array(t.byteLength);return e.set(t),e}function d(t){let e="";const n=new Uint8Array(t),s=n.byteLength;for(let t=0;t<s;t++)e+=String.fromCharCode(n[t]);return btoa(e)}function h(t){const e=atob(t),n=e.length,s=new Uint8Array(n);for(let t=0;t<n;t++)s[t]=e.charCodeAt(t);return s.buffer}function p(t){const e=(new TextEncoder).encode(t);let n="";for(const t of e)n+=String.fromCharCode(t);return btoa(n)}function g(t,e=10){if(t.length<=e)return[t];const n=[];let s="";for(const i of t.split(" "))s.length+i.length+1>e&&s.length>0?(n.push(s.trim()+" "),s=i):s+=(s?" ":"")+i;return s&&n.push(s.trim()),n.length>0?n:[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"}(s||(s={}));class f{constructor(e){var n,s;if(!(null==e?void 0:e.token))throw new Error("ChatClient: token is required");this.token=e.token,this.baseUrl=(null!==(n=e.baseUrl)&&void 0!==n?n:t).replace(/\/$/,""),this.logger=e.logger;const i=null!==(s=e.fetch)&&void 0!==s?s:"undefined"!=typeof fetch?fetch:void 0;if(!i)throw new Error("ChatClient: no fetch implementation available; pass `fetch` in options");this.fetchImpl=i.bind(globalThis)}static async fromCredentials(t){const{access_token:e}=await n({clientId:t.clientId,clientSecret:t.clientSecret,scope:t.scope});return new f({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`}async postElements(t,e,n="POST"){return await this.fetchImpl(this.replyUrl(t),{method:n,headers:this.authHeaders,body:JSON.stringify(e)})}async uploadImage(t,e,n="image/png"){var s;const i=new FormData;i.append("file",new Blob([c(t)],{type:n}),e);const a=await this.fetchImpl(`${this.baseUrl}/v1/upload/image`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:i}),r=await a.json();if(!a.ok)throw new Error(`uploadImage failed: ${a.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!==(s=r.url)&&void 0!==s?s:""}}async uploadFile(t,e,n="application/octet-stream"){var s;const i=new FormData;i.append("file",new Blob([c(t)],{type:n}),e);const a=await this.fetchImpl(`${this.baseUrl}/v1/upload/file`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:i}),r=await a.json();if(!a.ok)throw new Error(`uploadFile failed: ${a.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!==(s=r.url)&&void 0!==s?s:""}}async sendMessage(t,e){var n;const s=Array.isArray(e)?e.map((t=>t.trim())).filter(Boolean).map(i):[i(e)];if(0===s.length)return;const a=await this.postElements(t,s),r=await a.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] message sent",{status:a.status,elements:s.length}),!a.ok)throw new Error(`sendMessage failed: ${a.status} ${r}`)}async sendImageMessage(t,e){var n;if(!(null==e?void 0:e.length))return;const s=await this.postElements(t,[a(e)]),i=await s.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] image message sent",{status:s.status}),!s.ok)throw new Error(`sendImageMessage failed: ${s.status} ${i}`)}async sendFileMessage(t,e){var n;if(!(null==e?void 0:e.length))return;const s=await this.postElements(t,[r(e)]),i=await s.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] file message sent",{status:s.status}),!s.ok)throw new Error(`sendFileMessage failed: ${s.status} ${i}`)}async sendSoundMessage(t,e,n=0){var s;if(!(null==e?void 0:e.trim()))return;const i=await this.postElements(t,[o(e,n)]),a=await i.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] sound message sent",{status:i.status}),!i.ok)throw new Error(`sendSoundMessage failed: ${i.status} ${a.slice(0,500)}`)}async sendTypingStatus(t,e){var n,s;const i={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,[l(p(JSON.stringify(i)))])}catch(t){null===(n=this.logger)||void 0===n||n.error("[chat-sdk] typing status failed",null!==(s=null==t?void 0:t.message)&&void 0!==s?s:String(t))}}async sendStreamingChunk(t,e,n,s){const i={businessID:"chatbotPlugin",src:0,chunks:e,isFinished:n,TMessageCell_Name:"ChatbotMessageCell_Minimalist",TMessageCell_Data_Name:"ChatbotMessageCellData"},a={msgID:t,...l(p(JSON.stringify(i)))},r=await this.postElements(t,[a],s?"POST":"PATCH");if(!r.ok)throw new Error(`sendStreamingChunk failed: ${r.statusText}`);await r.text()}async sendMiniAppMessage(t,e){var n;const s=await this.postElements(t,[u(e)]),i=await s.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] miniapp card sent",{status:s.status}),!s.ok)throw new Error(`sendMiniAppMessage failed: ${s.status} ${i}`)}async sendWebLinkMessage(t,n){var s;const i={businessID:e,url:n},a=await this.postElements(t,[l(p(JSON.stringify(i)))]),r=await a.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] web link sent",{status:a.status}),!a.ok)throw new Error(`sendWebLinkMessage failed: ${a.status} ${r.slice(0,500)}`)}async streamMessage(t,e,n=10){const s=g(e,n),i=[];for(let e=0;e<s.length;e++)i.push(s[e]),await this.sendStreamingChunk(t,i,e===s.length-1,0===e)}}f.ElemType=s;export{f as ChatClient,t as DEFAULT_BASE_URL,s as ElemType,e as WEB_LINK_BUSINESS_ID,d as arrayBufferToBase64,h as base64ToArrayBuffer,l as customElem,r as fileElem,n as getAccessToken,a as imageElem,u as miniAppElem,o as soundElem,g as splitIntoChunks,i as textElem,p as toBase64};
1
+ const t="https://chat-api2-3rnt.onrender.com",e="web_link";async function s(e){var s;const{clientId:n,clientSecret:i}=e;if(!n||!i)throw new Error("getAccessToken: clientId and clientSecret are required");const r=t.replace(/\/$/,""),a=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(`${r}/v1/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({grant_type:"client_credentials",client_id:n,client_secret:i,scope:a})});if(!o.ok)throw new Error(`Token request failed: ${o.status} ${o.statusText}`);return await o.json()}var n;function i(t){return{elemType:n.Text,priority:0,textElem:{text:t.trim()}}}function r(t){return{elemType:n.Image,priority:0,imageElem:{upload_ids:t}}}function a(t){return{elemType:n.File,priority:0,fileElem:{upload_ids:t}}}function o(t,e=0){return{elemType:n.Sound,priority:0,soundElem:{uploadID:t,duration:e}}}function l(t,e){return{elemType:n.Sticker,priority:0,stickerElem:{packID:t,stickerID:e}}}function u(t){return{elemType:n.Custom,priority:0,customElem:{data:t}}}function c(t){return{elemType:n.MiniApp,priority:0,miniAppElem:t}}function d(t){const e=new Uint8Array(t.byteLength);return e.set(t),e}function h(t){let e="";const s=new Uint8Array(t),n=s.byteLength;for(let t=0;t<n;t++)e+=String.fromCharCode(s[t]);return btoa(e)}function p(t){const e=atob(t),s=e.length,n=new Uint8Array(s);for(let t=0;t<s;t++)n[t]=e.charCodeAt(t);return n.buffer}function g(t){const e=(new TextEncoder).encode(t);let s="";for(const t of e)s+=String.fromCharCode(t);return btoa(s)}function f(t,e=10){if(t.length<=e)return[t];const s=[];let n="";for(const i of t.split(" "))n.length+i.length+1>e&&n.length>0?(s.push(n.trim()+" "),n=i):n+=(n?" ":"")+i;return n&&s.push(n.trim()),s.length>0?s:[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"}(n||(n={}));class m{constructor(e){var s,n;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 i=null!==(n=e.fetch)&&void 0!==n?n:"undefined"!=typeof fetch?fetch:void 0;if(!i)throw new Error("ChatClient: no fetch implementation available; pass `fetch` in options");this.fetchImpl=i.bind(globalThis)}static async fromCredentials(t){const{access_token:e}=await s({clientId:t.clientId,clientSecret:t.clientSecret,scope:t.scope});return new m({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`}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 n;const i=new FormData;i.append("file",new Blob([d(t)],{type:s}),e);const r=await this.fetchImpl(`${this.baseUrl}/v1/upload/image`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:i}),a=await r.json();if(!r.ok)throw new Error(`uploadImage failed: ${r.status} ${JSON.stringify(a)}`);if(!a.upload_id)throw new Error(`uploadImage: missing upload_id: ${JSON.stringify(a)}`);return{upload_id:a.upload_id,url:null!==(n=a.url)&&void 0!==n?n:""}}async uploadFile(t,e,s="application/octet-stream"){var n;const i=new FormData;i.append("file",new Blob([d(t)],{type:s}),e);const r=await this.fetchImpl(`${this.baseUrl}/v1/upload/file`,{method:"POST",headers:{Authorization:`Bearer ${this.token}`},body:i}),a=await r.json();if(!r.ok)throw new Error(`uploadFile failed: ${r.status} ${JSON.stringify(a)}`);if(!a.upload_id)throw new Error(`uploadFile: missing upload_id: ${JSON.stringify(a)}`);return{upload_id:a.upload_id,url:null!==(n=a.url)&&void 0!==n?n:""}}async sendMessage(t,e){var s;const n=Array.isArray(e)?e.map((t=>t.trim())).filter(Boolean).map(i):[i(e)];if(0===n.length)return;const r=await this.postElements(t,n),a=await r.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] message sent",{status:r.status,elements:n.length}),!r.ok)throw new Error(`sendMessage failed: ${r.status} ${a}`)}async sendImageMessage(t,e){var s;if(!(null==e?void 0:e.length))return;const n=await this.postElements(t,[r(e)]),i=await n.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] image message sent",{status:n.status}),!n.ok)throw new Error(`sendImageMessage failed: ${n.status} ${i}`)}async sendFileMessage(t,e){var s;if(!(null==e?void 0:e.length))return;const n=await this.postElements(t,[a(e)]),i=await n.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] file message sent",{status:n.status}),!n.ok)throw new Error(`sendFileMessage failed: ${n.status} ${i}`)}async sendSoundMessage(t,e,s=0){var n;if(!(null==e?void 0:e.trim()))return;const i=await this.postElements(t,[o(e,s)]),r=await i.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] sound message sent",{status:i.status}),!i.ok)throw new Error(`sendSoundMessage failed: ${i.status} ${r.slice(0,500)}`)}async sendStickerMessage(t,e,s){var n;if(!(null==e?void 0:e.trim())||!(null==s?void 0:s.trim()))return;const i=await this.postElements(t,[l(e,s)]),r=await i.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] sticker message sent",{status:i.status}),!i.ok)throw new Error(`sendStickerMessage failed: ${i.status} ${r}`)}async sendTypingStatus(t,e){var s,n;const i={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,[u(g(JSON.stringify(i)))])}catch(t){null===(s=this.logger)||void 0===s||s.error("[chat-sdk] typing status failed",null!==(n=null==t?void 0:t.message)&&void 0!==n?n:String(t))}}async sendStreamingChunk(t,e,s,n){const i={businessID:"chatbotPlugin",src:0,chunks:e,isFinished:s,TMessageCell_Name:"ChatbotMessageCell_Minimalist",TMessageCell_Data_Name:"ChatbotMessageCellData"},r={msgID:t,...u(g(JSON.stringify(i)))},a=await this.postElements(t,[r],n?"POST":"PATCH");if(!a.ok)throw new Error(`sendStreamingChunk failed: ${a.statusText}`);await a.text()}async sendMiniAppMessage(t,e){var s;const n=await this.postElements(t,[c(e)]),i=await n.text();if(null===(s=this.logger)||void 0===s||s.log("[chat-sdk] miniapp card sent",{status:n.status}),!n.ok)throw new Error(`sendMiniAppMessage failed: ${n.status} ${i}`)}async sendWebLinkMessage(t,s){var n;const i={businessID:e,url:s},r=await this.postElements(t,[u(g(JSON.stringify(i)))]),a=await r.text();if(null===(n=this.logger)||void 0===n||n.log("[chat-sdk] web link sent",{status:r.status}),!r.ok)throw new Error(`sendWebLinkMessage failed: ${r.status} ${a.slice(0,500)}`)}async streamMessage(t,e,s=10){const n=f(e,s),i=[];for(let e=0;e<n.length;e++)i.push(n[e]),await this.sendStreamingChunk(t,i,e===n.length-1,0===e)}}m.ElemType=n;export{m as ChatClient,t as DEFAULT_BASE_URL,n as ElemType,e as WEB_LINK_BUSINESS_ID,h as arrayBufferToBase64,p as base64ToArrayBuffer,u as customElem,a as fileElem,s as getAccessToken,r as imageElem,c as miniAppElem,o as soundElem,f as splitIntoChunks,l as stickerElem,i as textElem,g as toBase64};
2
2
  //# sourceMappingURL=main.esm.js.map
@@ -48,6 +48,8 @@ export declare class ChatClient {
48
48
  sendFileMessage(msgID: string, uploadIDs: string[]): Promise<void>;
49
49
  /** Send a sound message by uploadID (duration in seconds). */
50
50
  sendSoundMessage(msgID: string, uploadID: string, durationSec?: number): Promise<void>;
51
+ /** Send a sticker message by pack + sticker identifiers. */
52
+ sendStickerMessage(msgID: string, packID: string, stickerID: string): Promise<void>;
51
53
  /** Send typing status (best effort — never throws). */
52
54
  sendTypingStatus(msgID: string, isTyping: boolean): Promise<void>;
53
55
  /**
@@ -7,6 +7,8 @@ export declare function imageElem(uploadIDs: string[]): MessageElem;
7
7
  export declare function fileElem(uploadIDs: string[]): MessageElem;
8
8
  /** Single sound message element (requires an uploadID; duration in seconds). */
9
9
  export declare function soundElem(uploadID: string, durationSec?: number): MessageElem;
10
+ /** Single sticker message element (pack + sticker identifiers). */
11
+ export declare function stickerElem(packID: string, stickerID: string): MessageElem;
10
12
  /** Single custom message element carrying a base64-encoded payload. */
11
13
  export declare function customElem(dataBase64: string): MessageElem;
12
14
  /** Single miniapp card message element. */
@@ -37,6 +37,10 @@ export type SoundElem = {
37
37
  uploadID: string;
38
38
  duration: number;
39
39
  };
40
+ export type StickerElem = {
41
+ packID: string;
42
+ stickerID: string;
43
+ };
40
44
  /** OAuth client_credentials token response (POST /v1/oauth/token). */
41
45
  export type TokenResponse = {
42
46
  access_token: string;
@@ -60,6 +64,7 @@ export type MessageElem = {
60
64
  upload_ids: string[];
61
65
  };
62
66
  soundElem?: SoundElem;
67
+ stickerElem?: StickerElem;
63
68
  customElem?: {
64
69
  data: string;
65
70
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "birdcash-chat-sdk-alpha",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
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",