@k-msg/provider 0.27.1 → 0.27.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.
@@ -1,24 +1,9 @@
1
- import { type MessageBinaryInput, type Template, type TemplateContext } from "@k-msg/core";
2
- import { type TemplateButton } from "@k-msg/template";
3
- import type { AligoConfig } from "./types/aligo";
4
- export declare function resolveImageRef(options: {
5
- imageUrl?: string;
6
- media?: {
7
- image?: MessageBinaryInput;
8
- };
9
- providerId: string;
10
- }): string | undefined;
11
- export declare function getAligoEndpoint(operation: "sendSMS" | "sendAlimTalk" | "sendFriendTalk", config: AligoConfig): string;
12
- export declare function formatAligoDate(date: Date): {
13
- date: string;
14
- time: string;
15
- };
16
- export declare function normalizeAligoKakaoCode(value: unknown): number | undefined;
17
- export declare function resolveKakaoSenderKey(params: {
18
- providerId: string;
19
- config: AligoConfig;
20
- }, ctx?: TemplateContext): string;
21
- export declare function toAligoTplButton(buttons: TemplateButton[] | undefined): string | undefined;
22
- export declare function mapAligoTemplateStatus(item: Record<string, unknown>): Template["status"];
23
- export declare function parseAligoDateTime(value: unknown): Date | undefined;
24
- export declare function resolveAligoTemplateMessage(variables: Record<string, unknown> | undefined, templateContent?: string): string;
1
+ /**
2
+ * Backward-compatible helper barrel.
3
+ *
4
+ * New code should import from:
5
+ * - ./aligo.shared.helpers (send/channel/common)
6
+ * - ./aligo.template.helpers (template-only)
7
+ */
8
+ export * from "./aligo.shared.helpers";
9
+ export * from "./aligo.template.helpers";
@@ -0,0 +1,22 @@
1
+ import { type MessageBinaryInput, type Template, type TemplateContext } from "@k-msg/core";
2
+ import type { AligoConfig } from "./types/aligo";
3
+ export declare function resolveImageRef(options: {
4
+ imageUrl?: string;
5
+ media?: {
6
+ image?: MessageBinaryInput;
7
+ };
8
+ providerId: string;
9
+ }): string | undefined;
10
+ export declare function getAligoEndpoint(operation: "sendSMS" | "sendAlimTalk" | "sendFriendTalk", config: AligoConfig): string;
11
+ export declare function formatAligoDate(date: Date): {
12
+ date: string;
13
+ time: string;
14
+ };
15
+ export declare function normalizeAligoKakaoCode(value: unknown): number | undefined;
16
+ export declare function resolveKakaoSenderKey(params: {
17
+ providerId: string;
18
+ config: AligoConfig;
19
+ }, ctx?: TemplateContext): string;
20
+ export declare function mapAligoTemplateStatus(item: Record<string, unknown>): Template["status"];
21
+ export declare function parseAligoDateTime(value: unknown): Date | undefined;
22
+ export declare function resolveAligoTemplateMessage(variables: Record<string, unknown> | undefined, templateContent?: string): string;
@@ -0,0 +1,2 @@
1
+ import { type TemplateButton } from "@k-msg/template/send";
2
+ export declare function toAligoTplButton(buttons: TemplateButton[] | undefined): string | undefined;
@@ -1,5 +1,5 @@
1
- var{defineProperty:U,getOwnPropertyNames:le,getOwnPropertyDescriptor:pe}=Object,ue=Object.prototype.hasOwnProperty;var H=new WeakMap,ge=(e)=>{var r=H.get(e),t;if(r)return r;if(r=U({},"__esModule",{value:!0}),e&&typeof e==="object"||typeof e==="function")le(e).map((i)=>!ue.call(r,i)&&U(r,i,{get:()=>e[i],enumerable:!(t=pe(e,i))||t.enumerable}));return H.set(e,r),r};var fe=(e,r)=>{for(var t in r)U(e,t,{get:r[t],enumerable:!0,configurable:!0,set:(i)=>r[t]=()=>i})};var ve={};fe(ve,{initializeAligo:()=>ae,createDefaultAligoProvider:()=>Q,createAligoProvider:()=>oe,AligoProviderFactory:()=>j,AligoProvider:()=>T});module.exports=ge(ve);var h=require("@k-msg/core");var B={iwinv:{providerId:"iwinv",providerName:"IWINV Messaging Provider",channelOnboarding:"manual",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"unsupported",liveTestSupport:"supported",checks:[{id:"channel_registered_in_console",title:"Kakao channel is registered in IWINV console",description:"IWINV channel onboarding is manual. Confirm channel registration and approval in console.",kind:"manual",severity:"blocker",scopes:["doctor","preflight"]},{id:"iwinv_config_required",title:"IWINV config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey"]},{id:"template_capability_available",title:"Template lifecycle APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate","updateTemplate","deleteTemplate"]},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}],notes:["Channel add/auth is not available via IWINV public API in current integration.","Template APIs are available and can be probed."]},aligo:{providerId:"aligo",providerName:"Aligo Smart SMS",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"required_if_no_inference",plusIdInference:"supported",liveTestSupport:"supported",checks:[{id:"aligo_config_required",title:"Aligo config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","userId"]},{id:"channel_api_capability_available",title:"Kakao channel APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listKakaoChannels","requestKakaoChannelAuth","addKakaoChannel"]},{id:"channel_list_probe",title:"Kakao channel list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_kakao_channels"},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}]},solapi:{providerId:"solapi",providerName:"SOLAPI Messaging Provider",channelOnboarding:"none",templateLifecycleApi:"unavailable",plusIdPolicy:"required_if_no_inference",plusIdInference:"unsupported",liveTestSupport:"partial",checks:[{id:"solapi_config_required",title:"SOLAPI config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","apiSecret"]}],notes:["SOLAPI ALIMTALK requires kakao profileId/pfId, but plusId inference is not available in current integration."]},mock:{providerId:"mock",providerName:"Mock Provider",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"supported",liveTestSupport:"none",checks:[{id:"mock_template_capability_available",title:"Mock template APIs are available",kind:"capability",severity:"info",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate"]}]}};function $(e){return B[e]}function Ae(){return Object.values(B)}var f=require("@k-msg/core");function v(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}var y=require("@k-msg/core");function k(e,r){if(e instanceof y.KMsgError)return e;return new y.KMsgError(y.KMsgErrorCode.PROVIDER_ERROR,e instanceof Error?e.message:String(e),{providerId:r})}function w(e,r){if(e instanceof y.KMsgError)return e;let t=v(e)?e:{},i=t.result_code,n=i!==void 0&&i!==null?String(i):"UNKNOWN",a=typeof t.message==="string"&&t.message.length>0?t.message:typeof t.msg==="string"&&t.msg.length>0?t.msg:e instanceof Error?e.message:"Unknown Aligo error",s=y.KMsgErrorCode.PROVIDER_ERROR;switch(n){case"-100":case"-101":s=y.KMsgErrorCode.AUTHENTICATION_FAILED;break;case"-102":case"-201":s=y.KMsgErrorCode.INSUFFICIENT_BALANCE;break;case"-103":case"-105":s=y.KMsgErrorCode.INVALID_REQUEST;break;case"-501":s=y.KMsgErrorCode.TEMPLATE_NOT_FOUND;break;default:s=y.KMsgErrorCode.PROVIDER_ERROR}return new y.KMsgError(s,`${a} (code: ${n})`,{providerId:r,resultCode:n})}var E=require("@k-msg/core"),N=require("@k-msg/template");function q(e){let r=typeof e.imageUrl==="string"&&e.imageUrl.trim().length>0?e.imageUrl.trim():void 0;if(r)return r;let t=e.media?.image;if(!t)return;if("ref"in t){let i=t.ref.trim();return i.length>0?i:void 0}throw new E.KMsgError(E.KMsgErrorCode.INVALID_REQUEST,"Aligo MMS/FriendTalk image requires `options.imageUrl` or `options.media.image.ref` (url/path).",{providerId:e.providerId})}function O(e,r){switch(e){case"sendSMS":return"/send/";case"sendAlimTalk":return"/akv10/alimtalk/send/";case"sendFriendTalk":return r.friendtalkEndpoint||"/akv10/friendtalk/send/";default:return"/"}}function P(e){let r=e.getFullYear(),t=String(e.getMonth()+1).padStart(2,"0"),i=String(e.getDate()).padStart(2,"0"),n=String(e.getHours()).padStart(2,"0"),a=String(e.getMinutes()).padStart(2,"0");return{date:`${r}${t}${i}`,time:`${n}${a}`}}function W(e){if(typeof e==="number"&&Number.isFinite(e))return e;if(typeof e==="string"){let r=e.trim();if(!r)return;let t=Number(r);if(Number.isFinite(t))return t}return}function S(e,r){let t=(typeof r?.kakaoChannelSenderKey==="string"&&r.kakaoChannelSenderKey.trim().length>0?r.kakaoChannelSenderKey.trim():e.config.senderKey)||"";if(!t)throw new E.KMsgError(E.KMsgErrorCode.INVALID_REQUEST,"kakao channel senderKey is required (ctx.kakaoChannelSenderKey or config.senderKey)",{providerId:e.providerId});return t}function F(e){if(!Array.isArray(e)||e.length===0)return;let r=JSON.parse(N.ButtonParser.serializeButtons(e));return JSON.stringify({button:r})}function D(e){switch(typeof e.inspStatus==="string"?e.inspStatus.trim().toUpperCase():""){case"APR":return"APPROVED";case"REJ":return"REJECTED";case"REQ":case"REG":return"INSPECTION";default:return"PENDING"}}function m(e){if(typeof e!=="string")return;let r=e.trim();if(!r)return;let t=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/.exec(r);if(!t)return;let i=Number(t[1]),n=Number(t[2]),a=Number(t[3]),s=Number(t[4]),l=Number(t[5]),d=Number(t[6]),o=new Date(i,n-1,a,s,l,d);return Number.isNaN(o.getTime())?void 0:o}function Y(e,r){if(!e)return"";let t=e._full_text;if(t!==void 0&&t!==null)return String(t);if(!r)return Object.values(e).map(String).join(`
2
- `);return N.interpolate(r,e)}var R=require("@k-msg/core");async function c(e){let r=new FormData;for(let[i,n]of Object.entries(e.data))if(n!==void 0&&n!==null)r.append(i,String(n));let t=await fetch(`${e.host}${e.endpoint}`,{method:"POST",body:r});if(!t.ok)throw new R.KMsgError(R.KMsgErrorCode.NETWORK_ERROR,`HTTP error! status: ${t.status}`,{providerId:e.providerId});return await t.json()}function A(e){let{providerId:r,response:t,fallbackMessage:i}=e,n=t.code,a=W(n);if(a===0)return R.ok(void 0);let s=typeof t.message==="string"&&t.message.length>0?t.message:i,l=a===509||a===-99?R.KMsgErrorCode.INVALID_REQUEST:R.KMsgErrorCode.PROVIDER_ERROR;return R.fail(new R.KMsgError(l,s,{providerId:r,originalCode:n,raw:t}))}async function G(e,r){try{let t={apikey:e.config.apiKey,userid:e.config.userId,...typeof r?.plusId==="string"&&r.plusId.trim().length>0?{plusid:r.plusId.trim()}:{},...typeof r?.senderKey==="string"&&r.senderKey.trim().length>0?{senderkey:r.senderKey.trim()}:{}},i=await c({host:e.alimtalkHost,endpoint:"/akv10/profile/list/",data:t,providerId:e.providerId}),n=A({providerId:e.providerId,response:i,fallbackMessage:"channel list failed"});if(n.isFailure)return n;let a=i.list,l=(Array.isArray(a)?a:[]).filter(v).map((d)=>({providerId:e.providerId,senderKey:String(d.senderKey??""),plusId:typeof d.uuid==="string"?d.uuid:void 0,name:typeof d.name==="string"?d.name:void 0,status:typeof d.status==="string"?d.status:void 0,createdAt:m(d.cdate),updatedAt:m(d.udate),raw:d})).filter((d)=>d.senderKey.length>0);return f.ok(l)}catch(t){return f.fail(k(t,e.providerId))}}async function J(e){try{let r=await c({host:e.alimtalkHost,endpoint:"/akv10/category/",data:{apikey:e.config.apiKey,userid:e.config.userId},providerId:e.providerId}),t=A({providerId:e.providerId,response:r,fallbackMessage:"category list failed"});if(t.isFailure)return t;let i=v(r.data)?r.data:{},n=(a)=>{return(Array.isArray(a)?a:[]).filter(v).map((l)=>({code:String(l.code??""),name:String(l.name??""),parentCode:typeof l.parentCode==="string"&&l.parentCode.length>0?l.parentCode:void 0})).filter((l)=>l.code.length>0)};return f.ok({first:n(i.firstBusinessType),second:n(i.secondBusinessType),third:n(i.thirdBusinessType)})}catch(r){return f.fail(k(r,e.providerId))}}async function z(e,r){try{let t=r.plusId.trim(),i=r.phoneNumber.trim();if(!t||!i)return f.fail(new f.KMsgError(f.KMsgErrorCode.INVALID_REQUEST,"plusId and phoneNumber are required",{providerId:e.providerId}));let n=await c({host:e.alimtalkHost,endpoint:"/akv10/profile/auth/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:t,phonenumber:i},providerId:e.providerId}),a=A({providerId:e.providerId,response:n,fallbackMessage:"channel auth failed"});if(a.isFailure)return a;return f.ok(void 0)}catch(t){return f.fail(k(t,e.providerId))}}async function X(e,r){try{let t=r.plusId.trim(),i=r.authNum.trim(),n=r.phoneNumber.trim(),a=r.categoryCode.trim();if(!t||!i||!n||!a)return f.fail(new f.KMsgError(f.KMsgErrorCode.INVALID_REQUEST,"plusId, authNum, phoneNumber, categoryCode are required",{providerId:e.providerId}));let s=await c({host:e.alimtalkHost,endpoint:"/akv10/profile/add/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:t,authnum:i,phonenumber:n,categorycode:a},providerId:e.providerId}),l=A({providerId:e.providerId,response:s,fallbackMessage:"channel add failed"});if(l.isFailure)return l;let d=s.data,o=Array.isArray(d)?d.find(v):v(d)?d:void 0;if(!o)return f.fail(new f.KMsgError(f.KMsgErrorCode.PROVIDER_ERROR,"channel add returned empty data",{providerId:e.providerId,raw:s}));let g=String(o.senderKey??"");if(!g)return f.fail(new f.KMsgError(f.KMsgErrorCode.PROVIDER_ERROR,"channel add did not return senderKey",{providerId:e.providerId,raw:o}));return f.ok({providerId:e.providerId,senderKey:g,plusId:typeof o.uuid==="string"?o.uuid:t,name:typeof o.name==="string"?o.name:void 0,status:typeof o.status==="string"?o.status:void 0,createdAt:m(o.cdate),updatedAt:m(o.udate),raw:o})}catch(t){return f.fail(k(t,e.providerId))}}var u=require("@k-msg/core");function ce(e,r){if(e.type!=="ALIMTALK")return;if(e.failover?.enabled!==!0)return;return[{code:"FAILOVER_PARTIAL_PROVIDER",message:"Aligo failover mapping is partial. API-level fallback may be attempted for non-Kakao-user failures.",details:{providerId:r,mappedFields:["failover","fmessage_1","fsubject_1"],unsupportedFields:["fallbackChannel"]}}]}async function me(e,r){let t=r.from||e.config.sender||"";if(!t)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"from is required for SMS/LMS/MMS (options.from or config.sender)",{providerId:e.providerId}));let i={key:e.config.apiKey,user_id:e.config.userId,sender:t,receiver:r.to,msg:r.text,msg_type:r.type,title:r.subject,testmode_yn:e.config.testMode?"Y":"N"},n=r.options?.scheduledAt;if(n instanceof Date&&!Number.isNaN(n.getTime())){let{date:s,time:l}=P(n);i.rdate=s,i.rtime=l}if(r.type==="MMS"){let s=q({imageUrl:r.imageUrl,media:r.media,providerId:e.providerId});if(!s)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"image is required for MMS (options.imageUrl or options.media.image.ref)",{providerId:e.providerId}));i.image=s}let a=await c({host:e.smsHost,endpoint:O("sendSMS",e.config),data:i,providerId:e.providerId});if(a.result_code!=="1")return u.fail(w(a,e.providerId));return u.ok({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:a.msg_id,status:"PENDING",type:r.type,to:r.to,raw:a})}async function Ie(e,r){let t=ce(r,e.providerId),i=(typeof r.kakao?.profileId==="string"?r.kakao.profileId:e.config.senderKey)||"";if(!i)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let n=r.from||e.config.sender||"";if(!n)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"from is required for ALIMTALK (options.from or config.sender)",{providerId:e.providerId}));let{variables:a,templateId:s}=r;if(!s||s.length===0)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"templateId is required for ALIMTALK",{providerId:e.providerId}));let l=typeof r.providerOptions?.templateContent==="string"?r.providerOptions.templateContent:void 0,d={apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:s,sender:n,receiver_1:r.to,subject_1:"알림톡",message_1:Y(a,l),testMode:e.config.testMode?"Y":"N"},o=typeof r.providerOptions?.failover==="string"?r.providerOptions.failover.trim().toUpperCase():"",g=o==="Y"||o==="N"?o:void 0,I=r.failover?.enabled===!0?"Y":r.failover?.enabled===!1?"N":void 0,b=g??I,C=typeof r.providerOptions?.fsubject_1==="string"&&r.providerOptions.fsubject_1.trim().length>0?r.providerOptions.fsubject_1.trim():typeof r.failover?.fallbackTitle==="string"&&r.failover.fallbackTitle.trim().length>0?r.failover.fallbackTitle.trim():void 0,_=typeof r.providerOptions?.fmessage_1==="string"&&r.providerOptions.fmessage_1.trim().length>0?r.providerOptions.fmessage_1.trim():typeof r.failover?.fallbackContent==="string"&&r.failover.fallbackContent.trim().length>0?r.failover.fallbackContent.trim():void 0;if(b)d.failover=b;if(C)d.fsubject_1=C;if(_)d.fmessage_1=_;let K=r.options?.scheduledAt;if(K instanceof Date&&!Number.isNaN(K.getTime())){let{date:se,time:de}=P(K);d.reserve="Y",d.reserve_date=se,d.reserve_time=de}let M=await c({host:e.alimtalkHost,endpoint:O("sendAlimTalk",e.config),data:d,providerId:e.providerId});if(M.result_code!=="0")return u.fail(w(M,e.providerId));return u.ok({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:M.msg_id,status:"PENDING",type:r.type,to:r.to,...Array.isArray(t)&&t.length>0?{warnings:t}:{},raw:M})}async function ye(e,r){let t=(typeof r.kakao?.profileId==="string"?r.kakao.profileId:e.config.senderKey)||"";if(!t)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let i=r.from||e.config.sender||"";if(!i)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"from is required for FRIENDTALK (options.from or config.sender)",{providerId:e.providerId}));let n={apikey:e.config.apiKey,userid:e.config.userId,senderkey:t,sender:i,receiver_1:r.to,subject_1:"친구톡",message_1:r.text,testMode:e.config.testMode?"Y":"N"},a=q({imageUrl:r.imageUrl,media:r.media,providerId:e.providerId});if(a)n.image_1=a;let s=Array.isArray(r.kakao?.buttons)?r.kakao.buttons:r.buttons;if(s)n.button_1=JSON.stringify(s);let l=r.options?.scheduledAt;if(l instanceof Date&&!Number.isNaN(l.getTime())){let{date:o,time:g}=P(l);n.reserve="Y",n.reserve_date=o,n.reserve_time=g}let d=await c({host:e.alimtalkHost,endpoint:O("sendFriendTalk",e.config),data:n,providerId:e.providerId});if(d.result_code!=="0")return u.fail(w(d,e.providerId));return u.ok({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:d.msg_id,status:"PENDING",type:r.type,to:r.to,raw:d})}async function Z(e,r){try{switch(r.type){case"ALIMTALK":return await Ie(e,r);case"FRIENDTALK":return await ye(e,r);case"SMS":case"LMS":case"MMS":return await me(e,r);default:return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,`AligoProvider does not support type ${r.type}`,{providerId:e.providerId,type:r.type}))}}catch(t){return u.fail(w(t,e.providerId))}}var p=require("@k-msg/core"),V=require("@k-msg/template");function x(e,r){return new p.KMsgError(e.code,e.message,{providerId:r,...e.details??{}})}async function ee(e,r,t){try{let i=S(e,t),n=V.validateTemplatePayload(r,{requireName:!0,requireContent:!0});if(n.isFailure)return p.fail(x(n.error,e.providerId));let a={apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_name:n.value.name??r.name,tpl_content:n.value.content??r.content},s=F(n.value.buttons);if(s)a.tpl_button=s;let l=await c({host:e.alimtalkHost,endpoint:"/akv10/template/add/",data:a,providerId:e.providerId}),d=A({providerId:e.providerId,response:l,fallbackMessage:"template create failed"});if(d.isFailure)return d;let o=v(l.data)?l.data:{},g=String(o.templtCode??"");if(!g)return p.fail(new p.KMsgError(p.KMsgErrorCode.PROVIDER_ERROR,"template create did not return templtCode",{providerId:e.providerId,raw:l}));let I=m(o.cdate)??new Date,b=m(o.udate)??m(o.cdate)??I;return p.ok({id:g,code:g,name:String(o.templtName??n.value.name??r.name),content:String(o.templtContent??n.value.content??r.content),category:r.category,status:D(o),buttons:Array.isArray(o.buttons)?o.buttons:n.value.buttons,variables:r.variables,createdAt:I,updatedAt:b})}catch(i){return p.fail(k(i,e.providerId))}}async function L(e,r,t){try{let i=S(e,t),n=r.trim();if(!n)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let a=await c({host:e.alimtalkHost,endpoint:"/akv10/template/list/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:n},providerId:e.providerId}),s=A({providerId:e.providerId,response:a,fallbackMessage:"template get failed"});if(s.isFailure)return s;let l=a.list,o=(Array.isArray(l)?l:[]).find(v);if(!o)return p.fail(new p.KMsgError(p.KMsgErrorCode.TEMPLATE_NOT_FOUND,"Template not found",{providerId:e.providerId,templateCode:n}));let g=String(o.templtCode??n),I=m(o.cdate)??new Date,b=m(o.udate)??m(o.cdate)??I;return p.ok({id:g,code:g,name:String(o.templtName??""),content:String(o.templtContent??""),status:D(o),buttons:Array.isArray(o.buttons)?o.buttons:void 0,createdAt:I,updatedAt:b})}catch(i){return p.fail(k(i,e.providerId))}}async function re(e,r,t,i){try{let n=S(e,i),a=r.trim();if(!a)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let s=await L(e,a,{kakaoChannelSenderKey:n});if(s.isFailure)return s;let l=s.value,d=typeof t.name==="string"&&t.name.trim().length>0?t.name.trim():l.name,o=typeof t.content==="string"&&t.content.trim().length>0?t.content:l.content,g=V.validateTemplatePayload({name:d,content:o,buttons:t.buttons!==void 0?t.buttons:l.buttons},{requireName:!0,requireContent:!0});if(g.isFailure)return p.fail(x(g.error,e.providerId));let I={apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_code:a,tpl_name:g.value.name??d,tpl_content:g.value.content??o},b=F(g.value.buttons);if(b)I.tpl_button=b;let C=await c({host:e.alimtalkHost,endpoint:"/akv10/template/modify/",data:I,providerId:e.providerId}),_=A({providerId:e.providerId,response:C,fallbackMessage:"template update failed"});if(_.isFailure)return _;let K=await L(e,a,{kakaoChannelSenderKey:n});if(K.isSuccess)return K;return p.ok({...l,name:g.value.name??d,content:g.value.content??o,...t.category!==void 0?{category:t.category}:{},...t.variables!==void 0?{variables:t.variables}:{},...t.buttons!==void 0?{buttons:g.value.buttons}:{},updatedAt:new Date})}catch(n){return p.fail(k(n,e.providerId))}}async function te(e,r,t){try{let i=S(e,t),n=r.trim();if(!n)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let a=await c({host:e.alimtalkHost,endpoint:"/akv10/template/del/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:n},providerId:e.providerId}),s=A({providerId:e.providerId,response:a,fallbackMessage:"template delete failed"});if(s.isFailure)return s;return p.ok(void 0)}catch(i){return p.fail(k(i,e.providerId))}}async function ne(e,r,t){try{let i=S(e,t),n=await c({host:e.alimtalkHost,endpoint:"/akv10/template/list/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i},providerId:e.providerId}),a=A({providerId:e.providerId,response:n,fallbackMessage:"template list failed"});if(a.isFailure)return a;let s=n.list,d=(Array.isArray(s)?s:[]).filter(v).map((o)=>{let g=String(o.templtCode??""),I=m(o.cdate)??new Date,b=m(o.udate)??m(o.cdate)??I;return{id:g,code:g,name:String(o.templtName??""),content:String(o.templtContent??""),status:D(o),buttons:Array.isArray(o.buttons)?o.buttons:void 0,createdAt:I,updatedAt:b}}).filter((o)=>o.code.length>0);if(r?.status){let o=r.status.trim().toUpperCase();return p.ok(d.filter((g)=>g.status===o))}return p.ok(d)}catch(i){return p.fail(k(i,e.providerId))}}async function ie(e,r,t){try{let i=S(e,t),n=r.trim();if(!n)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let a=await c({host:e.alimtalkHost,endpoint:"/akv10/template/request/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:n},providerId:e.providerId}),s=A({providerId:e.providerId,response:a,fallbackMessage:"template inspection request failed"});if(s.isFailure)return s;return p.ok(void 0)}catch(i){return p.fail(k(i,e.providerId))}}class T{config;id="aligo";name="Aligo Smart SMS";supportedTypes=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS"];smsHost;alimtalkHost;getOnboardingSpec(){let e=$(this.id);if(!e)throw Error(`Onboarding spec missing for provider: ${this.id}`);return e}constructor(e){this.config=e;if(!e||typeof e!=="object")throw Error("AligoProvider requires a config object");if(!e.apiKey||e.apiKey.length===0)throw Error("AligoProvider requires `apiKey`");if(!e.userId||e.userId.length===0)throw Error("AligoProvider requires `userId`");this.smsHost=e.smsBaseUrl||"https://apis.aligo.in",this.alimtalkHost=e.alimtalkBaseUrl||"https://kakaoapi.aligo.in"}getRuntimeContext(){return{providerId:this.id,config:this.config,smsHost:this.smsHost,alimtalkHost:this.alimtalkHost}}async healthCheck(){let e=Date.now(),r=[];try{if(!this.config.apiKey)r.push("Missing apiKey");if(!this.config.userId)r.push("Missing userId");if(!this.config.sender)r.push("Missing sender (default from)");try{new URL(this.smsHost)}catch{r.push("Invalid smsBaseUrl")}try{new URL(this.alimtalkHost)}catch{r.push("Invalid alimtalkBaseUrl")}return{healthy:r.length===0,issues:r,latencyMs:Date.now()-e,data:{provider:this.id,smsBaseUrl:this.smsHost,alimtalkBaseUrl:this.alimtalkHost}}}catch(t){return r.push(t instanceof Error?t.message:String(t)),{healthy:!1,issues:r,latencyMs:Date.now()-e}}}async send(e){let r=e.messageId||crypto.randomUUID(),t={...e,messageId:r};return Z(this.getRuntimeContext(),t)}async listKakaoChannels(e){return G(this.getRuntimeContext(),e)}async listKakaoChannelCategories(){return J(this.getRuntimeContext())}async requestKakaoChannelAuth(e){return z(this.getRuntimeContext(),e)}async addKakaoChannel(e){return X(this.getRuntimeContext(),e)}async createTemplate(e,r){return ee(this.getRuntimeContext(),e,r)}async updateTemplate(e,r,t){return re(this.getRuntimeContext(),e,r,t)}async deleteTemplate(e,r){return te(this.getRuntimeContext(),e,r)}async getTemplate(e,r){return L(this.getRuntimeContext(),e,r)}async listTemplates(e,r){return ne(this.getRuntimeContext(),e,r)}async requestTemplateInspection(e,r){return ie(this.getRuntimeContext(),e,r)}}var oe=(e)=>new T(e),Q=()=>{let e={apiKey:h.readRuntimeEnv("ALIGO_API_KEY")||"",userId:h.readRuntimeEnv("ALIGO_USER_ID")||"",senderKey:h.readRuntimeEnv("ALIGO_SENDER_KEY")||"",sender:h.readRuntimeEnv("ALIGO_SENDER")||"",friendtalkEndpoint:h.readRuntimeEnv("ALIGO_FRIENDTALK_ENDPOINT"),testMode:h.readRuntimeEnv("NODE_ENV")!=="production",debug:h.readRuntimeEnv("NODE_ENV")==="development"};if(!e.apiKey||!e.userId)throw Error("ALIGO_API_KEY and ALIGO_USER_ID are required");return new T(e)};class j{static create(e){return new T(e)}static createDefault(){return Q()}}function ae(){}
1
+ var{defineProperty:U,getOwnPropertyNames:ue,getOwnPropertyDescriptor:fe}=Object,ge=Object.prototype.hasOwnProperty;var B=new WeakMap,me=(e)=>{var r=B.get(e),t;if(r)return r;if(r=U({},"__esModule",{value:!0}),e&&typeof e==="object"||typeof e==="function")ue(e).map((i)=>!ge.call(r,i)&&U(r,i,{get:()=>e[i],enumerable:!(t=fe(e,i))||t.enumerable}));return B.set(e,r),r};var ce=(e,r)=>{for(var t in r)U(e,t,{get:r[t],enumerable:!0,configurable:!0,set:(i)=>r[t]=()=>i})};var he={};ce(he,{initializeAligo:()=>de,createDefaultAligoProvider:()=>j,createAligoProvider:()=>se,AligoProviderFactory:()=>H,AligoProvider:()=>_});module.exports=me(he);var p=require("@k-msg/core"),V=require("@k-msg/template/send");function v(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}var y=require("@k-msg/core");function k(e,r){if(e instanceof y.KMsgError)return e;return new y.KMsgError(y.KMsgErrorCode.PROVIDER_ERROR,e instanceof Error?e.message:String(e),{providerId:r})}function M(e,r){if(e instanceof y.KMsgError)return e;let t=v(e)?e:{},i=t.result_code,n=i!==void 0&&i!==null?String(i):"UNKNOWN",a=typeof t.message==="string"&&t.message.length>0?t.message:typeof t.msg==="string"&&t.msg.length>0?t.msg:e instanceof Error?e.message:"Unknown Aligo error",s=y.KMsgErrorCode.PROVIDER_ERROR;switch(n){case"-100":case"-101":s=y.KMsgErrorCode.AUTHENTICATION_FAILED;break;case"-102":case"-201":s=y.KMsgErrorCode.INSUFFICIENT_BALANCE;break;case"-103":case"-105":s=y.KMsgErrorCode.INVALID_REQUEST;break;case"-501":s=y.KMsgErrorCode.TEMPLATE_NOT_FOUND;break;default:s=y.KMsgErrorCode.PROVIDER_ERROR}return new y.KMsgError(s,`${a} (code: ${n})`,{providerId:r,resultCode:n})}var R=require("@k-msg/core");var T=require("@k-msg/core");function Ie(e,r){if(!e)return"";return e.replace(/#\{([^}]+)\}/g,(t,i)=>{let n=r[i];return n===void 0||n===null?t:String(n)})}function q(e){let r=typeof e.imageUrl==="string"&&e.imageUrl.trim().length>0?e.imageUrl.trim():void 0;if(r)return r;let t=e.media?.image;if(!t)return;if("ref"in t){let i=t.ref.trim();return i.length>0?i:void 0}throw new T.KMsgError(T.KMsgErrorCode.INVALID_REQUEST,"Aligo MMS/FriendTalk image requires `options.imageUrl` or `options.media.image.ref` (url/path).",{providerId:e.providerId})}function O(e,r){switch(e){case"sendSMS":return"/send/";case"sendAlimTalk":return"/akv10/alimtalk/send/";case"sendFriendTalk":return r.friendtalkEndpoint||"/akv10/friendtalk/send/";default:return"/"}}function D(e){let r=e.getFullYear(),t=String(e.getMonth()+1).padStart(2,"0"),i=String(e.getDate()).padStart(2,"0"),n=String(e.getHours()).padStart(2,"0"),a=String(e.getMinutes()).padStart(2,"0");return{date:`${r}${t}${i}`,time:`${n}${a}`}}function $(e){if(typeof e==="number"&&Number.isFinite(e))return e;if(typeof e==="string"){let r=e.trim();if(!r)return;let t=Number(r);if(Number.isFinite(t))return t}return}function K(e,r){let t=(typeof r?.kakaoChannelSenderKey==="string"&&r.kakaoChannelSenderKey.trim().length>0?r.kakaoChannelSenderKey.trim():e.config.senderKey)||"";if(!t)throw new T.KMsgError(T.KMsgErrorCode.INVALID_REQUEST,"kakao channel senderKey is required (ctx.kakaoChannelSenderKey or config.senderKey)",{providerId:e.providerId});return t}function P(e){switch(typeof e.inspStatus==="string"?e.inspStatus.trim().toUpperCase():""){case"APR":return"APPROVED";case"REJ":return"REJECTED";case"REQ":case"REG":return"INSPECTION";default:return"PENDING"}}function c(e){if(typeof e!=="string")return;let r=e.trim();if(!r)return;let t=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/.exec(r);if(!t)return;let i=Number(t[1]),n=Number(t[2]),a=Number(t[3]),s=Number(t[4]),l=Number(t[5]),d=Number(t[6]),o=new Date(i,n-1,a,s,l,d);return Number.isNaN(o.getTime())?void 0:o}function W(e,r){if(!e)return"";let t=e._full_text;if(t!==void 0&&t!==null)return String(t);if(!r)return Object.values(e).map(String).join(`
2
+ `);return Ie(r,e)}async function m(e){let r=new FormData;for(let[i,n]of Object.entries(e.data))if(n!==void 0&&n!==null)r.append(i,String(n));let t=await fetch(`${e.host}${e.endpoint}`,{method:"POST",body:r});if(!t.ok)throw new R.KMsgError(R.KMsgErrorCode.NETWORK_ERROR,`HTTP error! status: ${t.status}`,{providerId:e.providerId});return await t.json()}function A(e){let{providerId:r,response:t,fallbackMessage:i}=e,n=t.code,a=$(n);if(a===0)return R.ok(void 0);let s=typeof t.message==="string"&&t.message.length>0?t.message:i,l=a===509||a===-99?R.KMsgErrorCode.INVALID_REQUEST:R.KMsgErrorCode.PROVIDER_ERROR;return R.fail(new R.KMsgError(l,s,{providerId:r,originalCode:n,raw:t}))}var Y=require("@k-msg/template/send");function F(e){if(!Array.isArray(e)||e.length===0)return;let r=JSON.parse(Y.ButtonParser.serializeButtons(e));return JSON.stringify({button:r})}function G(e,r){return new p.KMsgError(e.code,e.message,{providerId:r,...e.details??{}})}async function J(e,r,t){try{let i=K(e,t),n=V.validateTemplatePayload(r,{requireName:!0,requireContent:!0});if(n.isFailure)return p.fail(G(n.error,e.providerId));let a={apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_name:n.value.name??r.name,tpl_content:n.value.content??r.content},s=F(n.value.buttons);if(s)a.tpl_button=s;let l=await m({host:e.alimtalkHost,endpoint:"/akv10/template/add/",data:a,providerId:e.providerId}),d=A({providerId:e.providerId,response:l,fallbackMessage:"template create failed"});if(d.isFailure)return d;let o=v(l.data)?l.data:{},f=String(o.templtCode??"");if(!f)return p.fail(new p.KMsgError(p.KMsgErrorCode.PROVIDER_ERROR,"template create did not return templtCode",{providerId:e.providerId,raw:l}));let I=c(o.cdate)??new Date,b=c(o.udate)??c(o.cdate)??I;return p.ok({id:f,code:f,name:String(o.templtName??n.value.name??r.name),content:String(o.templtContent??n.value.content??r.content),category:r.category,status:P(o),buttons:Array.isArray(o.buttons)?o.buttons:n.value.buttons,variables:r.variables,createdAt:I,updatedAt:b})}catch(i){return p.fail(k(i,e.providerId))}}async function L(e,r,t){try{let i=K(e,t),n=r.trim();if(!n)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let a=await m({host:e.alimtalkHost,endpoint:"/akv10/template/list/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:n},providerId:e.providerId}),s=A({providerId:e.providerId,response:a,fallbackMessage:"template get failed"});if(s.isFailure)return s;let l=a.list,o=(Array.isArray(l)?l:[]).find(v);if(!o)return p.fail(new p.KMsgError(p.KMsgErrorCode.TEMPLATE_NOT_FOUND,"Template not found",{providerId:e.providerId,templateCode:n}));let f=String(o.templtCode??n),I=c(o.cdate)??new Date,b=c(o.udate)??c(o.cdate)??I;return p.ok({id:f,code:f,name:String(o.templtName??""),content:String(o.templtContent??""),status:P(o),buttons:Array.isArray(o.buttons)?o.buttons:void 0,createdAt:I,updatedAt:b})}catch(i){return p.fail(k(i,e.providerId))}}async function z(e,r,t,i){try{let n=K(e,i),a=r.trim();if(!a)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let s=await L(e,a,{kakaoChannelSenderKey:n});if(s.isFailure)return s;let l=s.value,d=typeof t.name==="string"&&t.name.trim().length>0?t.name.trim():l.name,o=typeof t.content==="string"&&t.content.trim().length>0?t.content:l.content,f=V.validateTemplatePayload({name:d,content:o,buttons:t.buttons!==void 0?t.buttons:l.buttons},{requireName:!0,requireContent:!0});if(f.isFailure)return p.fail(G(f.error,e.providerId));let I={apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_code:a,tpl_name:f.value.name??d,tpl_content:f.value.content??o},b=F(f.value.buttons);if(b)I.tpl_button=b;let C=await m({host:e.alimtalkHost,endpoint:"/akv10/template/modify/",data:I,providerId:e.providerId}),w=A({providerId:e.providerId,response:C,fallbackMessage:"template update failed"});if(w.isFailure)return w;let E=await L(e,a,{kakaoChannelSenderKey:n});if(E.isSuccess)return E;return p.ok({...l,name:f.value.name??d,content:f.value.content??o,...t.category!==void 0?{category:t.category}:{},...t.variables!==void 0?{variables:t.variables}:{},...t.buttons!==void 0?{buttons:f.value.buttons}:{},updatedAt:new Date})}catch(n){return p.fail(k(n,e.providerId))}}async function X(e,r,t){try{let i=K(e,t),n=r.trim();if(!n)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let a=await m({host:e.alimtalkHost,endpoint:"/akv10/template/del/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:n},providerId:e.providerId}),s=A({providerId:e.providerId,response:a,fallbackMessage:"template delete failed"});if(s.isFailure)return s;return p.ok(void 0)}catch(i){return p.fail(k(i,e.providerId))}}async function Z(e,r,t){try{let i=K(e,t),n=await m({host:e.alimtalkHost,endpoint:"/akv10/template/list/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i},providerId:e.providerId}),a=A({providerId:e.providerId,response:n,fallbackMessage:"template list failed"});if(a.isFailure)return a;let s=n.list,d=(Array.isArray(s)?s:[]).filter(v).map((o)=>{let f=String(o.templtCode??""),I=c(o.cdate)??new Date,b=c(o.udate)??c(o.cdate)??I;return{id:f,code:f,name:String(o.templtName??""),content:String(o.templtContent??""),status:P(o),buttons:Array.isArray(o.buttons)?o.buttons:void 0,createdAt:I,updatedAt:b}}).filter((o)=>o.code.length>0);if(r?.status){let o=r.status.trim().toUpperCase();return p.ok(d.filter((f)=>f.status===o))}return p.ok(d)}catch(i){return p.fail(k(i,e.providerId))}}async function x(e,r,t){try{let i=K(e,t),n=r.trim();if(!n)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let a=await m({host:e.alimtalkHost,endpoint:"/akv10/template/request/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:n},providerId:e.providerId}),s=A({providerId:e.providerId,response:a,fallbackMessage:"template inspection request failed"});if(s.isFailure)return s;return p.ok(void 0)}catch(i){return p.fail(k(i,e.providerId))}}var h=require("@k-msg/core");var ee={iwinv:{providerId:"iwinv",providerName:"IWINV Messaging Provider",channelOnboarding:"manual",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"unsupported",liveTestSupport:"supported",checks:[{id:"channel_registered_in_console",title:"Kakao channel is registered in IWINV console",description:"IWINV channel onboarding is manual. Confirm channel registration and approval in console.",kind:"manual",severity:"blocker",scopes:["doctor","preflight"]},{id:"iwinv_config_required",title:"IWINV config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey"]},{id:"template_capability_available",title:"Template lifecycle APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate","updateTemplate","deleteTemplate"]},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}],notes:["Channel add/auth is not available via IWINV public API in current integration.","Template APIs are available and can be probed."]},aligo:{providerId:"aligo",providerName:"Aligo Smart SMS",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"required_if_no_inference",plusIdInference:"supported",liveTestSupport:"supported",checks:[{id:"aligo_config_required",title:"Aligo config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","userId"]},{id:"channel_api_capability_available",title:"Kakao channel APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listKakaoChannels","requestKakaoChannelAuth","addKakaoChannel"]},{id:"channel_list_probe",title:"Kakao channel list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_kakao_channels"},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}]},solapi:{providerId:"solapi",providerName:"SOLAPI Messaging Provider",channelOnboarding:"none",templateLifecycleApi:"unavailable",plusIdPolicy:"required_if_no_inference",plusIdInference:"unsupported",liveTestSupport:"partial",checks:[{id:"solapi_config_required",title:"SOLAPI config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","apiSecret"]}],notes:["SOLAPI ALIMTALK requires kakao profileId/pfId, but plusId inference is not available in current integration."]},mock:{providerId:"mock",providerName:"Mock Provider",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"supported",liveTestSupport:"none",checks:[{id:"mock_template_capability_available",title:"Mock template APIs are available",kind:"capability",severity:"info",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate"]}]}};function re(e){return ee[e]}function qe(){return Object.values(ee)}var g=require("@k-msg/core");async function te(e,r){try{let t={apikey:e.config.apiKey,userid:e.config.userId,...typeof r?.plusId==="string"&&r.plusId.trim().length>0?{plusid:r.plusId.trim()}:{},...typeof r?.senderKey==="string"&&r.senderKey.trim().length>0?{senderkey:r.senderKey.trim()}:{}},i=await m({host:e.alimtalkHost,endpoint:"/akv10/profile/list/",data:t,providerId:e.providerId}),n=A({providerId:e.providerId,response:i,fallbackMessage:"channel list failed"});if(n.isFailure)return n;let a=i.list,l=(Array.isArray(a)?a:[]).filter(v).map((d)=>({providerId:e.providerId,senderKey:String(d.senderKey??""),plusId:typeof d.uuid==="string"?d.uuid:void 0,name:typeof d.name==="string"?d.name:void 0,status:typeof d.status==="string"?d.status:void 0,createdAt:c(d.cdate),updatedAt:c(d.udate),raw:d})).filter((d)=>d.senderKey.length>0);return g.ok(l)}catch(t){return g.fail(k(t,e.providerId))}}async function ne(e){try{let r=await m({host:e.alimtalkHost,endpoint:"/akv10/category/",data:{apikey:e.config.apiKey,userid:e.config.userId},providerId:e.providerId}),t=A({providerId:e.providerId,response:r,fallbackMessage:"category list failed"});if(t.isFailure)return t;let i=v(r.data)?r.data:{},n=(a)=>{return(Array.isArray(a)?a:[]).filter(v).map((l)=>({code:String(l.code??""),name:String(l.name??""),parentCode:typeof l.parentCode==="string"&&l.parentCode.length>0?l.parentCode:void 0})).filter((l)=>l.code.length>0)};return g.ok({first:n(i.firstBusinessType),second:n(i.secondBusinessType),third:n(i.thirdBusinessType)})}catch(r){return g.fail(k(r,e.providerId))}}async function ie(e,r){try{let t=r.plusId.trim(),i=r.phoneNumber.trim();if(!t||!i)return g.fail(new g.KMsgError(g.KMsgErrorCode.INVALID_REQUEST,"plusId and phoneNumber are required",{providerId:e.providerId}));let n=await m({host:e.alimtalkHost,endpoint:"/akv10/profile/auth/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:t,phonenumber:i},providerId:e.providerId}),a=A({providerId:e.providerId,response:n,fallbackMessage:"channel auth failed"});if(a.isFailure)return a;return g.ok(void 0)}catch(t){return g.fail(k(t,e.providerId))}}async function oe(e,r){try{let t=r.plusId.trim(),i=r.authNum.trim(),n=r.phoneNumber.trim(),a=r.categoryCode.trim();if(!t||!i||!n||!a)return g.fail(new g.KMsgError(g.KMsgErrorCode.INVALID_REQUEST,"plusId, authNum, phoneNumber, categoryCode are required",{providerId:e.providerId}));let s=await m({host:e.alimtalkHost,endpoint:"/akv10/profile/add/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:t,authnum:i,phonenumber:n,categorycode:a},providerId:e.providerId}),l=A({providerId:e.providerId,response:s,fallbackMessage:"channel add failed"});if(l.isFailure)return l;let d=s.data,o=Array.isArray(d)?d.find(v):v(d)?d:void 0;if(!o)return g.fail(new g.KMsgError(g.KMsgErrorCode.PROVIDER_ERROR,"channel add returned empty data",{providerId:e.providerId,raw:s}));let f=String(o.senderKey??"");if(!f)return g.fail(new g.KMsgError(g.KMsgErrorCode.PROVIDER_ERROR,"channel add did not return senderKey",{providerId:e.providerId,raw:o}));return g.ok({providerId:e.providerId,senderKey:f,plusId:typeof o.uuid==="string"?o.uuid:t,name:typeof o.name==="string"?o.name:void 0,status:typeof o.status==="string"?o.status:void 0,createdAt:c(o.cdate),updatedAt:c(o.udate),raw:o})}catch(t){return g.fail(k(t,e.providerId))}}var u=require("@k-msg/core");function ye(e,r){if(e.type!=="ALIMTALK")return;if(e.failover?.enabled!==!0)return;return[{code:"FAILOVER_PARTIAL_PROVIDER",message:"Aligo failover mapping is partial. API-level fallback may be attempted for non-Kakao-user failures.",details:{providerId:r,mappedFields:["failover","fmessage_1","fsubject_1"],unsupportedFields:["fallbackChannel"]}}]}async function ve(e,r){let t=r.from||e.config.sender||"";if(!t)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"from is required for SMS/LMS/MMS (options.from or config.sender)",{providerId:e.providerId}));let i={key:e.config.apiKey,user_id:e.config.userId,sender:t,receiver:r.to,msg:r.text,msg_type:r.type,title:r.subject,testmode_yn:e.config.testMode?"Y":"N"},n=r.options?.scheduledAt;if(n instanceof Date&&!Number.isNaN(n.getTime())){let{date:s,time:l}=D(n);i.rdate=s,i.rtime=l}if(r.type==="MMS"){let s=q({imageUrl:r.imageUrl,media:r.media,providerId:e.providerId});if(!s)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"image is required for MMS (options.imageUrl or options.media.image.ref)",{providerId:e.providerId}));i.image=s}let a=await m({host:e.smsHost,endpoint:O("sendSMS",e.config),data:i,providerId:e.providerId});if(a.result_code!=="1")return u.fail(M(a,e.providerId));return u.ok({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:a.msg_id,status:"PENDING",type:r.type,to:r.to,raw:a})}async function ke(e,r){let t=ye(r,e.providerId),i=(typeof r.kakao?.profileId==="string"?r.kakao.profileId:e.config.senderKey)||"";if(!i)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let n=r.from||e.config.sender||"";if(!n)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"from is required for ALIMTALK (options.from or config.sender)",{providerId:e.providerId}));let{variables:a,templateId:s}=r;if(!s||s.length===0)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"templateId is required for ALIMTALK",{providerId:e.providerId}));let l=typeof r.providerOptions?.templateContent==="string"?r.providerOptions.templateContent:void 0,d={apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:s,sender:n,receiver_1:r.to,subject_1:"알림톡",message_1:W(a,l),testMode:e.config.testMode?"Y":"N"},o=typeof r.providerOptions?.failover==="string"?r.providerOptions.failover.trim().toUpperCase():"",f=o==="Y"||o==="N"?o:void 0,I=r.failover?.enabled===!0?"Y":r.failover?.enabled===!1?"N":void 0,b=f??I,C=typeof r.providerOptions?.fsubject_1==="string"&&r.providerOptions.fsubject_1.trim().length>0?r.providerOptions.fsubject_1.trim():typeof r.failover?.fallbackTitle==="string"&&r.failover.fallbackTitle.trim().length>0?r.failover.fallbackTitle.trim():void 0,w=typeof r.providerOptions?.fmessage_1==="string"&&r.providerOptions.fmessage_1.trim().length>0?r.providerOptions.fmessage_1.trim():typeof r.failover?.fallbackContent==="string"&&r.failover.fallbackContent.trim().length>0?r.failover.fallbackContent.trim():void 0;if(b)d.failover=b;if(C)d.fsubject_1=C;if(w)d.fmessage_1=w;let E=r.options?.scheduledAt;if(E instanceof Date&&!Number.isNaN(E.getTime())){let{date:le,time:pe}=D(E);d.reserve="Y",d.reserve_date=le,d.reserve_time=pe}let N=await m({host:e.alimtalkHost,endpoint:O("sendAlimTalk",e.config),data:d,providerId:e.providerId});if(N.result_code!=="0")return u.fail(M(N,e.providerId));return u.ok({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:N.msg_id,status:"PENDING",type:r.type,to:r.to,...Array.isArray(t)&&t.length>0?{warnings:t}:{},raw:N})}async function Ae(e,r){let t=(typeof r.kakao?.profileId==="string"?r.kakao.profileId:e.config.senderKey)||"";if(!t)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let i=r.from||e.config.sender||"";if(!i)return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,"from is required for FRIENDTALK (options.from or config.sender)",{providerId:e.providerId}));let n={apikey:e.config.apiKey,userid:e.config.userId,senderkey:t,sender:i,receiver_1:r.to,subject_1:"친구톡",message_1:r.text,testMode:e.config.testMode?"Y":"N"},a=q({imageUrl:r.imageUrl,media:r.media,providerId:e.providerId});if(a)n.image_1=a;let s=Array.isArray(r.kakao?.buttons)?r.kakao.buttons:r.buttons;if(s)n.button_1=JSON.stringify(s);let l=r.options?.scheduledAt;if(l instanceof Date&&!Number.isNaN(l.getTime())){let{date:o,time:f}=D(l);n.reserve="Y",n.reserve_date=o,n.reserve_time=f}let d=await m({host:e.alimtalkHost,endpoint:O("sendFriendTalk",e.config),data:n,providerId:e.providerId});if(d.result_code!=="0")return u.fail(M(d,e.providerId));return u.ok({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:d.msg_id,status:"PENDING",type:r.type,to:r.to,raw:d})}async function ae(e,r){try{switch(r.type){case"ALIMTALK":return await ke(e,r);case"FRIENDTALK":return await Ae(e,r);case"SMS":case"LMS":case"MMS":return await ve(e,r);default:return u.fail(new u.KMsgError(u.KMsgErrorCode.INVALID_REQUEST,`AligoProvider does not support type ${r.type}`,{providerId:e.providerId,type:r.type}))}}catch(t){return u.fail(M(t,e.providerId))}}function Q(){return{apiKey:h.readRuntimeEnv("ALIGO_API_KEY")||"",userId:h.readRuntimeEnv("ALIGO_USER_ID")||"",senderKey:h.readRuntimeEnv("ALIGO_SENDER_KEY")||"",sender:h.readRuntimeEnv("ALIGO_SENDER")||"",friendtalkEndpoint:h.readRuntimeEnv("ALIGO_FRIENDTALK_ENDPOINT"),testMode:h.readRuntimeEnv("NODE_ENV")!=="production",debug:h.readRuntimeEnv("NODE_ENV")==="development"}}class S{id="aligo";name="Aligo Smart SMS";supportedTypes=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS"];config;smsHost;alimtalkHost;getOnboardingSpec(){let e=re(this.id);if(!e)throw Error(`Onboarding spec missing for provider: ${this.id}`);return e}constructor(e){if(!e||typeof e!=="object")throw Error("AligoProvider requires a config object");if(!e.apiKey||e.apiKey.length===0)throw Error("AligoProvider requires `apiKey`");if(!e.userId||e.userId.length===0)throw Error("AligoProvider requires `userId`");this.config=e,this.smsHost=e.smsBaseUrl||"https://apis.aligo.in",this.alimtalkHost=e.alimtalkBaseUrl||"https://kakaoapi.aligo.in"}getRuntimeContext(){return{providerId:this.id,config:this.config,smsHost:this.smsHost,alimtalkHost:this.alimtalkHost}}async healthCheck(){let e=Date.now(),r=[];try{if(!this.config.apiKey)r.push("Missing apiKey");if(!this.config.userId)r.push("Missing userId");if(!this.config.sender)r.push("Missing sender (default from)");try{new URL(this.smsHost)}catch{r.push("Invalid smsBaseUrl")}try{new URL(this.alimtalkHost)}catch{r.push("Invalid alimtalkBaseUrl")}return{healthy:r.length===0,issues:r,latencyMs:Date.now()-e,data:{provider:this.id,smsBaseUrl:this.smsHost,alimtalkBaseUrl:this.alimtalkHost}}}catch(t){return r.push(t instanceof Error?t.message:String(t)),{healthy:!1,issues:r,latencyMs:Date.now()-e}}}async send(e){let r=e.messageId||crypto.randomUUID(),t={...e,messageId:r};return ae(this.getRuntimeContext(),t)}async listKakaoChannels(e){return te(this.getRuntimeContext(),e)}async listKakaoChannelCategories(){return ne(this.getRuntimeContext())}async requestKakaoChannelAuth(e){return ie(this.getRuntimeContext(),e)}async addKakaoChannel(e){return oe(this.getRuntimeContext(),e)}}var Ze=(e)=>new S(e),be=()=>{let e=Q();if(!e.apiKey||!e.userId)throw Error("ALIGO_API_KEY and ALIGO_USER_ID are required");return new S(e)};class Re{static create(e){return new S(e)}static createDefault(){return be()}}class _ extends S{async createTemplate(e,r){return J(this.getRuntimeContext(),e,r)}async updateTemplate(e,r,t){return z(this.getRuntimeContext(),e,r,t)}async deleteTemplate(e,r){return X(this.getRuntimeContext(),e,r)}async getTemplate(e,r){return L(this.getRuntimeContext(),e,r)}async listTemplates(e,r){return Z(this.getRuntimeContext(),e,r)}async requestTemplateInspection(e,r){return x(this.getRuntimeContext(),e,r)}}var se=(e)=>new _(e),j=()=>{let e=Q();return new _(e)};class H{static create(e){return new _(e)}static createDefault(){return j()}}function de(){}
3
3
 
4
- //# debugId=C790C7C50E6B04EA64756E2164756E21
4
+ //# debugId=17B1DEE2779A7C6B64756E2164756E21
5
5
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
- import{readRuntimeEnv as T}from"@k-msg/core";var Y={iwinv:{providerId:"iwinv",providerName:"IWINV Messaging Provider",channelOnboarding:"manual",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"unsupported",liveTestSupport:"supported",checks:[{id:"channel_registered_in_console",title:"Kakao channel is registered in IWINV console",description:"IWINV channel onboarding is manual. Confirm channel registration and approval in console.",kind:"manual",severity:"blocker",scopes:["doctor","preflight"]},{id:"iwinv_config_required",title:"IWINV config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey"]},{id:"template_capability_available",title:"Template lifecycle APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate","updateTemplate","deleteTemplate"]},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}],notes:["Channel add/auth is not available via IWINV public API in current integration.","Template APIs are available and can be probed."]},aligo:{providerId:"aligo",providerName:"Aligo Smart SMS",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"required_if_no_inference",plusIdInference:"supported",liveTestSupport:"supported",checks:[{id:"aligo_config_required",title:"Aligo config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","userId"]},{id:"channel_api_capability_available",title:"Kakao channel APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listKakaoChannels","requestKakaoChannelAuth","addKakaoChannel"]},{id:"channel_list_probe",title:"Kakao channel list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_kakao_channels"},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}]},solapi:{providerId:"solapi",providerName:"SOLAPI Messaging Provider",channelOnboarding:"none",templateLifecycleApi:"unavailable",plusIdPolicy:"required_if_no_inference",plusIdInference:"unsupported",liveTestSupport:"partial",checks:[{id:"solapi_config_required",title:"SOLAPI config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","apiSecret"]}],notes:["SOLAPI ALIMTALK requires kakao profileId/pfId, but plusId inference is not available in current integration."]},mock:{providerId:"mock",providerName:"Mock Provider",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"supported",liveTestSupport:"none",checks:[{id:"mock_template_capability_available",title:"Mock template APIs are available",kind:"capability",severity:"info",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate"]}]}};function G(e){return Y[e]}function Ee(){return Object.values(Y)}import{fail as A,KMsgError as F,KMsgErrorCode as V,ok as Q}from"@k-msg/core";function m(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}import{KMsgError as D,KMsgErrorCode as h}from"@k-msg/core";function I(e,r){if(e instanceof D)return e;return new D(h.PROVIDER_ERROR,e instanceof Error?e.message:String(e),{providerId:r})}function M(e,r){if(e instanceof D)return e;let t=m(e)?e:{},i=t.result_code,n=i!==void 0&&i!==null?String(i):"UNKNOWN",a=typeof t.message==="string"&&t.message.length>0?t.message:typeof t.msg==="string"&&t.msg.length>0?t.msg:e instanceof Error?e.message:"Unknown Aligo error",s=h.PROVIDER_ERROR;switch(n){case"-100":case"-101":s=h.AUTHENTICATION_FAILED;break;case"-102":case"-201":s=h.INSUFFICIENT_BALANCE;break;case"-103":case"-105":s=h.INVALID_REQUEST;break;case"-501":s=h.TEMPLATE_NOT_FOUND;break;default:s=h.PROVIDER_ERROR}return new D(s,`${a} (code: ${n})`,{providerId:r,resultCode:n})}import{KMsgError as J,KMsgErrorCode as z}from"@k-msg/core";import{ButtonParser as Ie,interpolate as ye}from"@k-msg/template";function H(e){let r=typeof e.imageUrl==="string"&&e.imageUrl.trim().length>0?e.imageUrl.trim():void 0;if(r)return r;let t=e.media?.image;if(!t)return;if("ref"in t){let i=t.ref.trim();return i.length>0?i:void 0}throw new J(z.INVALID_REQUEST,"Aligo MMS/FriendTalk image requires `options.imageUrl` or `options.media.image.ref` (url/path).",{providerId:e.providerId})}function L(e,r){switch(e){case"sendSMS":return"/send/";case"sendAlimTalk":return"/akv10/alimtalk/send/";case"sendFriendTalk":return r.friendtalkEndpoint||"/akv10/friendtalk/send/";default:return"/"}}function U(e){let r=e.getFullYear(),t=String(e.getMonth()+1).padStart(2,"0"),i=String(e.getDate()).padStart(2,"0"),n=String(e.getHours()).padStart(2,"0"),a=String(e.getMinutes()).padStart(2,"0");return{date:`${r}${t}${i}`,time:`${n}${a}`}}function X(e){if(typeof e==="number"&&Number.isFinite(e))return e;if(typeof e==="string"){let r=e.trim();if(!r)return;let t=Number(r);if(Number.isFinite(t))return t}return}function S(e,r){let t=(typeof r?.kakaoChannelSenderKey==="string"&&r.kakaoChannelSenderKey.trim().length>0?r.kakaoChannelSenderKey.trim():e.config.senderKey)||"";if(!t)throw new J(z.INVALID_REQUEST,"kakao channel senderKey is required (ctx.kakaoChannelSenderKey or config.senderKey)",{providerId:e.providerId});return t}function B(e){if(!Array.isArray(e)||e.length===0)return;let r=JSON.parse(Ie.serializeButtons(e));return JSON.stringify({button:r})}function q(e){switch(typeof e.inspStatus==="string"?e.inspStatus.trim().toUpperCase():""){case"APR":return"APPROVED";case"REJ":return"REJECTED";case"REQ":case"REG":return"INSPECTION";default:return"PENDING"}}function g(e){if(typeof e!=="string")return;let r=e.trim();if(!r)return;let t=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/.exec(r);if(!t)return;let i=Number(t[1]),n=Number(t[2]),a=Number(t[3]),s=Number(t[4]),l=Number(t[5]),d=Number(t[6]),o=new Date(i,n-1,a,s,l,d);return Number.isNaN(o.getTime())?void 0:o}function Z(e,r){if(!e)return"";let t=e._full_text;if(t!==void 0&&t!==null)return String(t);if(!r)return Object.values(e).map(String).join(`
2
- `);return ye(r,e)}import{fail as ve,KMsgError as x,KMsgErrorCode as $,ok as ke}from"@k-msg/core";async function u(e){let r=new FormData;for(let[i,n]of Object.entries(e.data))if(n!==void 0&&n!==null)r.append(i,String(n));let t=await fetch(`${e.host}${e.endpoint}`,{method:"POST",body:r});if(!t.ok)throw new x($.NETWORK_ERROR,`HTTP error! status: ${t.status}`,{providerId:e.providerId});return await t.json()}function y(e){let{providerId:r,response:t,fallbackMessage:i}=e,n=t.code,a=X(n);if(a===0)return ke(void 0);let s=typeof t.message==="string"&&t.message.length>0?t.message:i,l=a===509||a===-99?$.INVALID_REQUEST:$.PROVIDER_ERROR;return ve(new x(l,s,{providerId:r,originalCode:n,raw:t}))}async function ee(e,r){try{let t={apikey:e.config.apiKey,userid:e.config.userId,...typeof r?.plusId==="string"&&r.plusId.trim().length>0?{plusid:r.plusId.trim()}:{},...typeof r?.senderKey==="string"&&r.senderKey.trim().length>0?{senderkey:r.senderKey.trim()}:{}},i=await u({host:e.alimtalkHost,endpoint:"/akv10/profile/list/",data:t,providerId:e.providerId}),n=y({providerId:e.providerId,response:i,fallbackMessage:"channel list failed"});if(n.isFailure)return n;let a=i.list,l=(Array.isArray(a)?a:[]).filter(m).map((d)=>({providerId:e.providerId,senderKey:String(d.senderKey??""),plusId:typeof d.uuid==="string"?d.uuid:void 0,name:typeof d.name==="string"?d.name:void 0,status:typeof d.status==="string"?d.status:void 0,createdAt:g(d.cdate),updatedAt:g(d.udate),raw:d})).filter((d)=>d.senderKey.length>0);return Q(l)}catch(t){return A(I(t,e.providerId))}}async function re(e){try{let r=await u({host:e.alimtalkHost,endpoint:"/akv10/category/",data:{apikey:e.config.apiKey,userid:e.config.userId},providerId:e.providerId}),t=y({providerId:e.providerId,response:r,fallbackMessage:"category list failed"});if(t.isFailure)return t;let i=m(r.data)?r.data:{},n=(a)=>{return(Array.isArray(a)?a:[]).filter(m).map((l)=>({code:String(l.code??""),name:String(l.name??""),parentCode:typeof l.parentCode==="string"&&l.parentCode.length>0?l.parentCode:void 0})).filter((l)=>l.code.length>0)};return Q({first:n(i.firstBusinessType),second:n(i.secondBusinessType),third:n(i.thirdBusinessType)})}catch(r){return A(I(r,e.providerId))}}async function te(e,r){try{let t=r.plusId.trim(),i=r.phoneNumber.trim();if(!t||!i)return A(new F(V.INVALID_REQUEST,"plusId and phoneNumber are required",{providerId:e.providerId}));let n=await u({host:e.alimtalkHost,endpoint:"/akv10/profile/auth/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:t,phonenumber:i},providerId:e.providerId}),a=y({providerId:e.providerId,response:n,fallbackMessage:"channel auth failed"});if(a.isFailure)return a;return Q(void 0)}catch(t){return A(I(t,e.providerId))}}async function ne(e,r){try{let t=r.plusId.trim(),i=r.authNum.trim(),n=r.phoneNumber.trim(),a=r.categoryCode.trim();if(!t||!i||!n||!a)return A(new F(V.INVALID_REQUEST,"plusId, authNum, phoneNumber, categoryCode are required",{providerId:e.providerId}));let s=await u({host:e.alimtalkHost,endpoint:"/akv10/profile/add/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:t,authnum:i,phonenumber:n,categorycode:a},providerId:e.providerId}),l=y({providerId:e.providerId,response:s,fallbackMessage:"channel add failed"});if(l.isFailure)return l;let d=s.data,o=Array.isArray(d)?d.find(m):m(d)?d:void 0;if(!o)return A(new F(V.PROVIDER_ERROR,"channel add returned empty data",{providerId:e.providerId,raw:s}));let p=String(o.senderKey??"");if(!p)return A(new F(V.PROVIDER_ERROR,"channel add did not return senderKey",{providerId:e.providerId,raw:o}));return Q({providerId:e.providerId,senderKey:p,plusId:typeof o.uuid==="string"?o.uuid:t,name:typeof o.name==="string"?o.name:void 0,status:typeof o.status==="string"?o.status:void 0,createdAt:g(o.cdate),updatedAt:g(o.udate),raw:o})}catch(t){return A(I(t,e.providerId))}}import{fail as v,KMsgError as b,KMsgErrorCode as R,ok as W}from"@k-msg/core";function Ae(e,r){if(e.type!=="ALIMTALK")return;if(e.failover?.enabled!==!0)return;return[{code:"FAILOVER_PARTIAL_PROVIDER",message:"Aligo failover mapping is partial. API-level fallback may be attempted for non-Kakao-user failures.",details:{providerId:r,mappedFields:["failover","fmessage_1","fsubject_1"],unsupportedFields:["fallbackChannel"]}}]}async function be(e,r){let t=r.from||e.config.sender||"";if(!t)return v(new b(R.INVALID_REQUEST,"from is required for SMS/LMS/MMS (options.from or config.sender)",{providerId:e.providerId}));let i={key:e.config.apiKey,user_id:e.config.userId,sender:t,receiver:r.to,msg:r.text,msg_type:r.type,title:r.subject,testmode_yn:e.config.testMode?"Y":"N"},n=r.options?.scheduledAt;if(n instanceof Date&&!Number.isNaN(n.getTime())){let{date:s,time:l}=U(n);i.rdate=s,i.rtime=l}if(r.type==="MMS"){let s=H({imageUrl:r.imageUrl,media:r.media,providerId:e.providerId});if(!s)return v(new b(R.INVALID_REQUEST,"image is required for MMS (options.imageUrl or options.media.image.ref)",{providerId:e.providerId}));i.image=s}let a=await u({host:e.smsHost,endpoint:L("sendSMS",e.config),data:i,providerId:e.providerId});if(a.result_code!=="1")return v(M(a,e.providerId));return W({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:a.msg_id,status:"PENDING",type:r.type,to:r.to,raw:a})}async function Re(e,r){let t=Ae(r,e.providerId),i=(typeof r.kakao?.profileId==="string"?r.kakao.profileId:e.config.senderKey)||"";if(!i)return v(new b(R.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let n=r.from||e.config.sender||"";if(!n)return v(new b(R.INVALID_REQUEST,"from is required for ALIMTALK (options.from or config.sender)",{providerId:e.providerId}));let{variables:a,templateId:s}=r;if(!s||s.length===0)return v(new b(R.INVALID_REQUEST,"templateId is required for ALIMTALK",{providerId:e.providerId}));let l=typeof r.providerOptions?.templateContent==="string"?r.providerOptions.templateContent:void 0,d={apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:s,sender:n,receiver_1:r.to,subject_1:"알림톡",message_1:Z(a,l),testMode:e.config.testMode?"Y":"N"},o=typeof r.providerOptions?.failover==="string"?r.providerOptions.failover.trim().toUpperCase():"",p=o==="Y"||o==="N"?o:void 0,c=r.failover?.enabled===!0?"Y":r.failover?.enabled===!1?"N":void 0,k=p??c,O=typeof r.providerOptions?.fsubject_1==="string"&&r.providerOptions.fsubject_1.trim().length>0?r.providerOptions.fsubject_1.trim():typeof r.failover?.fallbackTitle==="string"&&r.failover.fallbackTitle.trim().length>0?r.failover.fallbackTitle.trim():void 0,C=typeof r.providerOptions?.fmessage_1==="string"&&r.providerOptions.fmessage_1.trim().length>0?r.providerOptions.fmessage_1.trim():typeof r.failover?.fallbackContent==="string"&&r.failover.fallbackContent.trim().length>0?r.failover.fallbackContent.trim():void 0;if(k)d.failover=k;if(O)d.fsubject_1=O;if(C)d.fmessage_1=C;let _=r.options?.scheduledAt;if(_ instanceof Date&&!Number.isNaN(_.getTime())){let{date:ce,time:me}=U(_);d.reserve="Y",d.reserve_date=ce,d.reserve_time=me}let P=await u({host:e.alimtalkHost,endpoint:L("sendAlimTalk",e.config),data:d,providerId:e.providerId});if(P.result_code!=="0")return v(M(P,e.providerId));return W({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:P.msg_id,status:"PENDING",type:r.type,to:r.to,...Array.isArray(t)&&t.length>0?{warnings:t}:{},raw:P})}async function he(e,r){let t=(typeof r.kakao?.profileId==="string"?r.kakao.profileId:e.config.senderKey)||"";if(!t)return v(new b(R.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let i=r.from||e.config.sender||"";if(!i)return v(new b(R.INVALID_REQUEST,"from is required for FRIENDTALK (options.from or config.sender)",{providerId:e.providerId}));let n={apikey:e.config.apiKey,userid:e.config.userId,senderkey:t,sender:i,receiver_1:r.to,subject_1:"친구톡",message_1:r.text,testMode:e.config.testMode?"Y":"N"},a=H({imageUrl:r.imageUrl,media:r.media,providerId:e.providerId});if(a)n.image_1=a;let s=Array.isArray(r.kakao?.buttons)?r.kakao.buttons:r.buttons;if(s)n.button_1=JSON.stringify(s);let l=r.options?.scheduledAt;if(l instanceof Date&&!Number.isNaN(l.getTime())){let{date:o,time:p}=U(l);n.reserve="Y",n.reserve_date=o,n.reserve_time=p}let d=await u({host:e.alimtalkHost,endpoint:L("sendFriendTalk",e.config),data:n,providerId:e.providerId});if(d.result_code!=="0")return v(M(d,e.providerId));return W({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:d.msg_id,status:"PENDING",type:r.type,to:r.to,raw:d})}async function ie(e,r){try{switch(r.type){case"ALIMTALK":return await Re(e,r);case"FRIENDTALK":return await he(e,r);case"SMS":case"LMS":case"MMS":return await be(e,r);default:return v(new b(R.INVALID_REQUEST,`AligoProvider does not support type ${r.type}`,{providerId:e.providerId,type:r.type}))}}catch(t){return v(M(t,e.providerId))}}import{fail as f,KMsgError as K,KMsgErrorCode as w,ok as E}from"@k-msg/core";import{validateTemplatePayload as oe}from"@k-msg/template";function ae(e,r){return new K(e.code,e.message,{providerId:r,...e.details??{}})}async function se(e,r,t){try{let i=S(e,t),n=oe(r,{requireName:!0,requireContent:!0});if(n.isFailure)return f(ae(n.error,e.providerId));let a={apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_name:n.value.name??r.name,tpl_content:n.value.content??r.content},s=B(n.value.buttons);if(s)a.tpl_button=s;let l=await u({host:e.alimtalkHost,endpoint:"/akv10/template/add/",data:a,providerId:e.providerId}),d=y({providerId:e.providerId,response:l,fallbackMessage:"template create failed"});if(d.isFailure)return d;let o=m(l.data)?l.data:{},p=String(o.templtCode??"");if(!p)return f(new K(w.PROVIDER_ERROR,"template create did not return templtCode",{providerId:e.providerId,raw:l}));let c=g(o.cdate)??new Date,k=g(o.udate)??g(o.cdate)??c;return E({id:p,code:p,name:String(o.templtName??n.value.name??r.name),content:String(o.templtContent??n.value.content??r.content),category:r.category,status:q(o),buttons:Array.isArray(o.buttons)?o.buttons:n.value.buttons,variables:r.variables,createdAt:c,updatedAt:k})}catch(i){return f(I(i,e.providerId))}}async function j(e,r,t){try{let i=S(e,t),n=r.trim();if(!n)return f(new K(w.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let a=await u({host:e.alimtalkHost,endpoint:"/akv10/template/list/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:n},providerId:e.providerId}),s=y({providerId:e.providerId,response:a,fallbackMessage:"template get failed"});if(s.isFailure)return s;let l=a.list,o=(Array.isArray(l)?l:[]).find(m);if(!o)return f(new K(w.TEMPLATE_NOT_FOUND,"Template not found",{providerId:e.providerId,templateCode:n}));let p=String(o.templtCode??n),c=g(o.cdate)??new Date,k=g(o.udate)??g(o.cdate)??c;return E({id:p,code:p,name:String(o.templtName??""),content:String(o.templtContent??""),status:q(o),buttons:Array.isArray(o.buttons)?o.buttons:void 0,createdAt:c,updatedAt:k})}catch(i){return f(I(i,e.providerId))}}async function de(e,r,t,i){try{let n=S(e,i),a=r.trim();if(!a)return f(new K(w.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let s=await j(e,a,{kakaoChannelSenderKey:n});if(s.isFailure)return s;let l=s.value,d=typeof t.name==="string"&&t.name.trim().length>0?t.name.trim():l.name,o=typeof t.content==="string"&&t.content.trim().length>0?t.content:l.content,p=oe({name:d,content:o,buttons:t.buttons!==void 0?t.buttons:l.buttons},{requireName:!0,requireContent:!0});if(p.isFailure)return f(ae(p.error,e.providerId));let c={apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_code:a,tpl_name:p.value.name??d,tpl_content:p.value.content??o},k=B(p.value.buttons);if(k)c.tpl_button=k;let O=await u({host:e.alimtalkHost,endpoint:"/akv10/template/modify/",data:c,providerId:e.providerId}),C=y({providerId:e.providerId,response:O,fallbackMessage:"template update failed"});if(C.isFailure)return C;let _=await j(e,a,{kakaoChannelSenderKey:n});if(_.isSuccess)return _;return E({...l,name:p.value.name??d,content:p.value.content??o,...t.category!==void 0?{category:t.category}:{},...t.variables!==void 0?{variables:t.variables}:{},...t.buttons!==void 0?{buttons:p.value.buttons}:{},updatedAt:new Date})}catch(n){return f(I(n,e.providerId))}}async function le(e,r,t){try{let i=S(e,t),n=r.trim();if(!n)return f(new K(w.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let a=await u({host:e.alimtalkHost,endpoint:"/akv10/template/del/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:n},providerId:e.providerId}),s=y({providerId:e.providerId,response:a,fallbackMessage:"template delete failed"});if(s.isFailure)return s;return E(void 0)}catch(i){return f(I(i,e.providerId))}}async function pe(e,r,t){try{let i=S(e,t),n=await u({host:e.alimtalkHost,endpoint:"/akv10/template/list/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i},providerId:e.providerId}),a=y({providerId:e.providerId,response:n,fallbackMessage:"template list failed"});if(a.isFailure)return a;let s=n.list,d=(Array.isArray(s)?s:[]).filter(m).map((o)=>{let p=String(o.templtCode??""),c=g(o.cdate)??new Date,k=g(o.udate)??g(o.cdate)??c;return{id:p,code:p,name:String(o.templtName??""),content:String(o.templtContent??""),status:q(o),buttons:Array.isArray(o.buttons)?o.buttons:void 0,createdAt:c,updatedAt:k}}).filter((o)=>o.code.length>0);if(r?.status){let o=r.status.trim().toUpperCase();return E(d.filter((p)=>p.status===o))}return E(d)}catch(i){return f(I(i,e.providerId))}}async function ue(e,r,t){try{let i=S(e,t),n=r.trim();if(!n)return f(new K(w.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let a=await u({host:e.alimtalkHost,endpoint:"/akv10/template/request/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:n},providerId:e.providerId}),s=y({providerId:e.providerId,response:a,fallbackMessage:"template inspection request failed"});if(s.isFailure)return s;return E(void 0)}catch(i){return f(I(i,e.providerId))}}class N{config;id="aligo";name="Aligo Smart SMS";supportedTypes=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS"];smsHost;alimtalkHost;getOnboardingSpec(){let e=G(this.id);if(!e)throw Error(`Onboarding spec missing for provider: ${this.id}`);return e}constructor(e){this.config=e;if(!e||typeof e!=="object")throw Error("AligoProvider requires a config object");if(!e.apiKey||e.apiKey.length===0)throw Error("AligoProvider requires `apiKey`");if(!e.userId||e.userId.length===0)throw Error("AligoProvider requires `userId`");this.smsHost=e.smsBaseUrl||"https://apis.aligo.in",this.alimtalkHost=e.alimtalkBaseUrl||"https://kakaoapi.aligo.in"}getRuntimeContext(){return{providerId:this.id,config:this.config,smsHost:this.smsHost,alimtalkHost:this.alimtalkHost}}async healthCheck(){let e=Date.now(),r=[];try{if(!this.config.apiKey)r.push("Missing apiKey");if(!this.config.userId)r.push("Missing userId");if(!this.config.sender)r.push("Missing sender (default from)");try{new URL(this.smsHost)}catch{r.push("Invalid smsBaseUrl")}try{new URL(this.alimtalkHost)}catch{r.push("Invalid alimtalkBaseUrl")}return{healthy:r.length===0,issues:r,latencyMs:Date.now()-e,data:{provider:this.id,smsBaseUrl:this.smsHost,alimtalkBaseUrl:this.alimtalkHost}}}catch(t){return r.push(t instanceof Error?t.message:String(t)),{healthy:!1,issues:r,latencyMs:Date.now()-e}}}async send(e){let r=e.messageId||crypto.randomUUID(),t={...e,messageId:r};return ie(this.getRuntimeContext(),t)}async listKakaoChannels(e){return ee(this.getRuntimeContext(),e)}async listKakaoChannelCategories(){return re(this.getRuntimeContext())}async requestKakaoChannelAuth(e){return te(this.getRuntimeContext(),e)}async addKakaoChannel(e){return ne(this.getRuntimeContext(),e)}async createTemplate(e,r){return se(this.getRuntimeContext(),e,r)}async updateTemplate(e,r,t){return de(this.getRuntimeContext(),e,r,t)}async deleteTemplate(e,r){return le(this.getRuntimeContext(),e,r)}async getTemplate(e,r){return j(this.getRuntimeContext(),e,r)}async listTemplates(e,r){return pe(this.getRuntimeContext(),e,r)}async requestTemplateInspection(e,r){return ue(this.getRuntimeContext(),e,r)}}var Se=(e)=>new N(e),ge=()=>{let e={apiKey:T("ALIGO_API_KEY")||"",userId:T("ALIGO_USER_ID")||"",senderKey:T("ALIGO_SENDER_KEY")||"",sender:T("ALIGO_SENDER")||"",friendtalkEndpoint:T("ALIGO_FRIENDTALK_ENDPOINT"),testMode:T("NODE_ENV")!=="production",debug:T("NODE_ENV")==="development"};if(!e.apiKey||!e.userId)throw Error("ALIGO_API_KEY and ALIGO_USER_ID are required");return new N(e)};class fe{static create(e){return new N(e)}static createDefault(){return ge()}}function Ke(){}export{Ke as initializeAligo,ge as createDefaultAligoProvider,Se as createAligoProvider,fe as AligoProviderFactory,N as AligoProvider};
1
+ import{fail as g,KMsgError as E,KMsgErrorCode as w,ok as T}from"@k-msg/core";import{validateTemplatePayload as ee}from"@k-msg/template/send";function c(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}import{KMsgError as L,KMsgErrorCode as h}from"@k-msg/core";function I(e,r){if(e instanceof L)return e;return new L(h.PROVIDER_ERROR,e instanceof Error?e.message:String(e),{providerId:r})}function N(e,r){if(e instanceof L)return e;let t=c(e)?e:{},i=t.result_code,n=i!==void 0&&i!==null?String(i):"UNKNOWN",a=typeof t.message==="string"&&t.message.length>0?t.message:typeof t.msg==="string"&&t.msg.length>0?t.msg:e instanceof Error?e.message:"Unknown Aligo error",s=h.PROVIDER_ERROR;switch(n){case"-100":case"-101":s=h.AUTHENTICATION_FAILED;break;case"-102":case"-201":s=h.INSUFFICIENT_BALANCE;break;case"-103":case"-105":s=h.INVALID_REQUEST;break;case"-501":s=h.TEMPLATE_NOT_FOUND;break;default:s=h.PROVIDER_ERROR}return new L(s,`${a} (code: ${n})`,{providerId:r,resultCode:n})}import{fail as ke,KMsgError as x,KMsgErrorCode as $,ok as Ae}from"@k-msg/core";import{KMsgError as J,KMsgErrorCode as z}from"@k-msg/core";function ve(e,r){if(!e)return"";return e.replace(/#\{([^}]+)\}/g,(t,i)=>{let n=r[i];return n===void 0||n===null?t:String(n)})}function B(e){let r=typeof e.imageUrl==="string"&&e.imageUrl.trim().length>0?e.imageUrl.trim():void 0;if(r)return r;let t=e.media?.image;if(!t)return;if("ref"in t){let i=t.ref.trim();return i.length>0?i:void 0}throw new J(z.INVALID_REQUEST,"Aligo MMS/FriendTalk image requires `options.imageUrl` or `options.media.image.ref` (url/path).",{providerId:e.providerId})}function U(e,r){switch(e){case"sendSMS":return"/send/";case"sendAlimTalk":return"/akv10/alimtalk/send/";case"sendFriendTalk":return r.friendtalkEndpoint||"/akv10/friendtalk/send/";default:return"/"}}function q(e){let r=e.getFullYear(),t=String(e.getMonth()+1).padStart(2,"0"),i=String(e.getDate()).padStart(2,"0"),n=String(e.getHours()).padStart(2,"0"),a=String(e.getMinutes()).padStart(2,"0");return{date:`${r}${t}${i}`,time:`${n}${a}`}}function X(e){if(typeof e==="number"&&Number.isFinite(e))return e;if(typeof e==="string"){let r=e.trim();if(!r)return;let t=Number(r);if(Number.isFinite(t))return t}return}function K(e,r){let t=(typeof r?.kakaoChannelSenderKey==="string"&&r.kakaoChannelSenderKey.trim().length>0?r.kakaoChannelSenderKey.trim():e.config.senderKey)||"";if(!t)throw new J(z.INVALID_REQUEST,"kakao channel senderKey is required (ctx.kakaoChannelSenderKey or config.senderKey)",{providerId:e.providerId});return t}function F(e){switch(typeof e.inspStatus==="string"?e.inspStatus.trim().toUpperCase():""){case"APR":return"APPROVED";case"REJ":return"REJECTED";case"REQ":case"REG":return"INSPECTION";default:return"PENDING"}}function f(e){if(typeof e!=="string")return;let r=e.trim();if(!r)return;let t=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/.exec(r);if(!t)return;let i=Number(t[1]),n=Number(t[2]),a=Number(t[3]),s=Number(t[4]),l=Number(t[5]),d=Number(t[6]),o=new Date(i,n-1,a,s,l,d);return Number.isNaN(o.getTime())?void 0:o}function Z(e,r){if(!e)return"";let t=e._full_text;if(t!==void 0&&t!==null)return String(t);if(!r)return Object.values(e).map(String).join(`
2
+ `);return ve(r,e)}async function u(e){let r=new FormData;for(let[i,n]of Object.entries(e.data))if(n!==void 0&&n!==null)r.append(i,String(n));let t=await fetch(`${e.host}${e.endpoint}`,{method:"POST",body:r});if(!t.ok)throw new x($.NETWORK_ERROR,`HTTP error! status: ${t.status}`,{providerId:e.providerId});return await t.json()}function y(e){let{providerId:r,response:t,fallbackMessage:i}=e,n=t.code,a=X(n);if(a===0)return Ae(void 0);let s=typeof t.message==="string"&&t.message.length>0?t.message:i,l=a===509||a===-99?$.INVALID_REQUEST:$.PROVIDER_ERROR;return ke(new x(l,s,{providerId:r,originalCode:n,raw:t}))}import{ButtonParser as be}from"@k-msg/template/send";function W(e){if(!Array.isArray(e)||e.length===0)return;let r=JSON.parse(be.serializeButtons(e));return JSON.stringify({button:r})}function re(e,r){return new E(e.code,e.message,{providerId:r,...e.details??{}})}async function te(e,r,t){try{let i=K(e,t),n=ee(r,{requireName:!0,requireContent:!0});if(n.isFailure)return g(re(n.error,e.providerId));let a={apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_name:n.value.name??r.name,tpl_content:n.value.content??r.content},s=W(n.value.buttons);if(s)a.tpl_button=s;let l=await u({host:e.alimtalkHost,endpoint:"/akv10/template/add/",data:a,providerId:e.providerId}),d=y({providerId:e.providerId,response:l,fallbackMessage:"template create failed"});if(d.isFailure)return d;let o=c(l.data)?l.data:{},p=String(o.templtCode??"");if(!p)return g(new E(w.PROVIDER_ERROR,"template create did not return templtCode",{providerId:e.providerId,raw:l}));let m=f(o.cdate)??new Date,k=f(o.udate)??f(o.cdate)??m;return T({id:p,code:p,name:String(o.templtName??n.value.name??r.name),content:String(o.templtContent??n.value.content??r.content),category:r.category,status:F(o),buttons:Array.isArray(o.buttons)?o.buttons:n.value.buttons,variables:r.variables,createdAt:m,updatedAt:k})}catch(i){return g(I(i,e.providerId))}}async function V(e,r,t){try{let i=K(e,t),n=r.trim();if(!n)return g(new E(w.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let a=await u({host:e.alimtalkHost,endpoint:"/akv10/template/list/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:n},providerId:e.providerId}),s=y({providerId:e.providerId,response:a,fallbackMessage:"template get failed"});if(s.isFailure)return s;let l=a.list,o=(Array.isArray(l)?l:[]).find(c);if(!o)return g(new E(w.TEMPLATE_NOT_FOUND,"Template not found",{providerId:e.providerId,templateCode:n}));let p=String(o.templtCode??n),m=f(o.cdate)??new Date,k=f(o.udate)??f(o.cdate)??m;return T({id:p,code:p,name:String(o.templtName??""),content:String(o.templtContent??""),status:F(o),buttons:Array.isArray(o.buttons)?o.buttons:void 0,createdAt:m,updatedAt:k})}catch(i){return g(I(i,e.providerId))}}async function ne(e,r,t,i){try{let n=K(e,i),a=r.trim();if(!a)return g(new E(w.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let s=await V(e,a,{kakaoChannelSenderKey:n});if(s.isFailure)return s;let l=s.value,d=typeof t.name==="string"&&t.name.trim().length>0?t.name.trim():l.name,o=typeof t.content==="string"&&t.content.trim().length>0?t.content:l.content,p=ee({name:d,content:o,buttons:t.buttons!==void 0?t.buttons:l.buttons},{requireName:!0,requireContent:!0});if(p.isFailure)return g(re(p.error,e.providerId));let m={apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_code:a,tpl_name:p.value.name??d,tpl_content:p.value.content??o},k=W(p.value.buttons);if(k)m.tpl_button=k;let D=await u({host:e.alimtalkHost,endpoint:"/akv10/template/modify/",data:m,providerId:e.providerId}),C=y({providerId:e.providerId,response:D,fallbackMessage:"template update failed"});if(C.isFailure)return C;let _=await V(e,a,{kakaoChannelSenderKey:n});if(_.isSuccess)return _;return T({...l,name:p.value.name??d,content:p.value.content??o,...t.category!==void 0?{category:t.category}:{},...t.variables!==void 0?{variables:t.variables}:{},...t.buttons!==void 0?{buttons:p.value.buttons}:{},updatedAt:new Date})}catch(n){return g(I(n,e.providerId))}}async function ie(e,r,t){try{let i=K(e,t),n=r.trim();if(!n)return g(new E(w.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let a=await u({host:e.alimtalkHost,endpoint:"/akv10/template/del/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:n},providerId:e.providerId}),s=y({providerId:e.providerId,response:a,fallbackMessage:"template delete failed"});if(s.isFailure)return s;return T(void 0)}catch(i){return g(I(i,e.providerId))}}async function oe(e,r,t){try{let i=K(e,t),n=await u({host:e.alimtalkHost,endpoint:"/akv10/template/list/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i},providerId:e.providerId}),a=y({providerId:e.providerId,response:n,fallbackMessage:"template list failed"});if(a.isFailure)return a;let s=n.list,d=(Array.isArray(s)?s:[]).filter(c).map((o)=>{let p=String(o.templtCode??""),m=f(o.cdate)??new Date,k=f(o.udate)??f(o.cdate)??m;return{id:p,code:p,name:String(o.templtName??""),content:String(o.templtContent??""),status:F(o),buttons:Array.isArray(o.buttons)?o.buttons:void 0,createdAt:m,updatedAt:k}}).filter((o)=>o.code.length>0);if(r?.status){let o=r.status.trim().toUpperCase();return T(d.filter((p)=>p.status===o))}return T(d)}catch(i){return g(I(i,e.providerId))}}async function ae(e,r,t){try{let i=K(e,t),n=r.trim();if(!n)return g(new E(w.INVALID_REQUEST,"code is required",{providerId:e.providerId}));let a=await u({host:e.alimtalkHost,endpoint:"/akv10/template/request/",data:{apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:n},providerId:e.providerId}),s=y({providerId:e.providerId,response:a,fallbackMessage:"template inspection request failed"});if(s.isFailure)return s;return T(void 0)}catch(i){return g(I(i,e.providerId))}}import{readRuntimeEnv as S}from"@k-msg/core";var se={iwinv:{providerId:"iwinv",providerName:"IWINV Messaging Provider",channelOnboarding:"manual",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"unsupported",liveTestSupport:"supported",checks:[{id:"channel_registered_in_console",title:"Kakao channel is registered in IWINV console",description:"IWINV channel onboarding is manual. Confirm channel registration and approval in console.",kind:"manual",severity:"blocker",scopes:["doctor","preflight"]},{id:"iwinv_config_required",title:"IWINV config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey"]},{id:"template_capability_available",title:"Template lifecycle APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate","updateTemplate","deleteTemplate"]},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}],notes:["Channel add/auth is not available via IWINV public API in current integration.","Template APIs are available and can be probed."]},aligo:{providerId:"aligo",providerName:"Aligo Smart SMS",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"required_if_no_inference",plusIdInference:"supported",liveTestSupport:"supported",checks:[{id:"aligo_config_required",title:"Aligo config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","userId"]},{id:"channel_api_capability_available",title:"Kakao channel APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listKakaoChannels","requestKakaoChannelAuth","addKakaoChannel"]},{id:"channel_list_probe",title:"Kakao channel list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_kakao_channels"},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}]},solapi:{providerId:"solapi",providerName:"SOLAPI Messaging Provider",channelOnboarding:"none",templateLifecycleApi:"unavailable",plusIdPolicy:"required_if_no_inference",plusIdInference:"unsupported",liveTestSupport:"partial",checks:[{id:"solapi_config_required",title:"SOLAPI config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","apiSecret"]}],notes:["SOLAPI ALIMTALK requires kakao profileId/pfId, but plusId inference is not available in current integration."]},mock:{providerId:"mock",providerName:"Mock Provider",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"supported",liveTestSupport:"none",checks:[{id:"mock_template_capability_available",title:"Mock template APIs are available",kind:"capability",severity:"info",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate"]}]}};function de(e){return se[e]}function Je(){return Object.values(se)}import{fail as A,KMsgError as Q,KMsgErrorCode as j,ok as H}from"@k-msg/core";async function le(e,r){try{let t={apikey:e.config.apiKey,userid:e.config.userId,...typeof r?.plusId==="string"&&r.plusId.trim().length>0?{plusid:r.plusId.trim()}:{},...typeof r?.senderKey==="string"&&r.senderKey.trim().length>0?{senderkey:r.senderKey.trim()}:{}},i=await u({host:e.alimtalkHost,endpoint:"/akv10/profile/list/",data:t,providerId:e.providerId}),n=y({providerId:e.providerId,response:i,fallbackMessage:"channel list failed"});if(n.isFailure)return n;let a=i.list,l=(Array.isArray(a)?a:[]).filter(c).map((d)=>({providerId:e.providerId,senderKey:String(d.senderKey??""),plusId:typeof d.uuid==="string"?d.uuid:void 0,name:typeof d.name==="string"?d.name:void 0,status:typeof d.status==="string"?d.status:void 0,createdAt:f(d.cdate),updatedAt:f(d.udate),raw:d})).filter((d)=>d.senderKey.length>0);return H(l)}catch(t){return A(I(t,e.providerId))}}async function pe(e){try{let r=await u({host:e.alimtalkHost,endpoint:"/akv10/category/",data:{apikey:e.config.apiKey,userid:e.config.userId},providerId:e.providerId}),t=y({providerId:e.providerId,response:r,fallbackMessage:"category list failed"});if(t.isFailure)return t;let i=c(r.data)?r.data:{},n=(a)=>{return(Array.isArray(a)?a:[]).filter(c).map((l)=>({code:String(l.code??""),name:String(l.name??""),parentCode:typeof l.parentCode==="string"&&l.parentCode.length>0?l.parentCode:void 0})).filter((l)=>l.code.length>0)};return H({first:n(i.firstBusinessType),second:n(i.secondBusinessType),third:n(i.thirdBusinessType)})}catch(r){return A(I(r,e.providerId))}}async function ue(e,r){try{let t=r.plusId.trim(),i=r.phoneNumber.trim();if(!t||!i)return A(new Q(j.INVALID_REQUEST,"plusId and phoneNumber are required",{providerId:e.providerId}));let n=await u({host:e.alimtalkHost,endpoint:"/akv10/profile/auth/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:t,phonenumber:i},providerId:e.providerId}),a=y({providerId:e.providerId,response:n,fallbackMessage:"channel auth failed"});if(a.isFailure)return a;return H(void 0)}catch(t){return A(I(t,e.providerId))}}async function fe(e,r){try{let t=r.plusId.trim(),i=r.authNum.trim(),n=r.phoneNumber.trim(),a=r.categoryCode.trim();if(!t||!i||!n||!a)return A(new Q(j.INVALID_REQUEST,"plusId, authNum, phoneNumber, categoryCode are required",{providerId:e.providerId}));let s=await u({host:e.alimtalkHost,endpoint:"/akv10/profile/add/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:t,authnum:i,phonenumber:n,categorycode:a},providerId:e.providerId}),l=y({providerId:e.providerId,response:s,fallbackMessage:"channel add failed"});if(l.isFailure)return l;let d=s.data,o=Array.isArray(d)?d.find(c):c(d)?d:void 0;if(!o)return A(new Q(j.PROVIDER_ERROR,"channel add returned empty data",{providerId:e.providerId,raw:s}));let p=String(o.senderKey??"");if(!p)return A(new Q(j.PROVIDER_ERROR,"channel add did not return senderKey",{providerId:e.providerId,raw:o}));return H({providerId:e.providerId,senderKey:p,plusId:typeof o.uuid==="string"?o.uuid:t,name:typeof o.name==="string"?o.name:void 0,status:typeof o.status==="string"?o.status:void 0,createdAt:f(o.cdate),updatedAt:f(o.udate),raw:o})}catch(t){return A(I(t,e.providerId))}}import{fail as v,KMsgError as b,KMsgErrorCode as R,ok as Y}from"@k-msg/core";function Re(e,r){if(e.type!=="ALIMTALK")return;if(e.failover?.enabled!==!0)return;return[{code:"FAILOVER_PARTIAL_PROVIDER",message:"Aligo failover mapping is partial. API-level fallback may be attempted for non-Kakao-user failures.",details:{providerId:r,mappedFields:["failover","fmessage_1","fsubject_1"],unsupportedFields:["fallbackChannel"]}}]}async function he(e,r){let t=r.from||e.config.sender||"";if(!t)return v(new b(R.INVALID_REQUEST,"from is required for SMS/LMS/MMS (options.from or config.sender)",{providerId:e.providerId}));let i={key:e.config.apiKey,user_id:e.config.userId,sender:t,receiver:r.to,msg:r.text,msg_type:r.type,title:r.subject,testmode_yn:e.config.testMode?"Y":"N"},n=r.options?.scheduledAt;if(n instanceof Date&&!Number.isNaN(n.getTime())){let{date:s,time:l}=q(n);i.rdate=s,i.rtime=l}if(r.type==="MMS"){let s=B({imageUrl:r.imageUrl,media:r.media,providerId:e.providerId});if(!s)return v(new b(R.INVALID_REQUEST,"image is required for MMS (options.imageUrl or options.media.image.ref)",{providerId:e.providerId}));i.image=s}let a=await u({host:e.smsHost,endpoint:U("sendSMS",e.config),data:i,providerId:e.providerId});if(a.result_code!=="1")return v(N(a,e.providerId));return Y({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:a.msg_id,status:"PENDING",type:r.type,to:r.to,raw:a})}async function Ke(e,r){let t=Re(r,e.providerId),i=(typeof r.kakao?.profileId==="string"?r.kakao.profileId:e.config.senderKey)||"";if(!i)return v(new b(R.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let n=r.from||e.config.sender||"";if(!n)return v(new b(R.INVALID_REQUEST,"from is required for ALIMTALK (options.from or config.sender)",{providerId:e.providerId}));let{variables:a,templateId:s}=r;if(!s||s.length===0)return v(new b(R.INVALID_REQUEST,"templateId is required for ALIMTALK",{providerId:e.providerId}));let l=typeof r.providerOptions?.templateContent==="string"?r.providerOptions.templateContent:void 0,d={apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:s,sender:n,receiver_1:r.to,subject_1:"알림톡",message_1:Z(a,l),testMode:e.config.testMode?"Y":"N"},o=typeof r.providerOptions?.failover==="string"?r.providerOptions.failover.trim().toUpperCase():"",p=o==="Y"||o==="N"?o:void 0,m=r.failover?.enabled===!0?"Y":r.failover?.enabled===!1?"N":void 0,k=p??m,D=typeof r.providerOptions?.fsubject_1==="string"&&r.providerOptions.fsubject_1.trim().length>0?r.providerOptions.fsubject_1.trim():typeof r.failover?.fallbackTitle==="string"&&r.failover.fallbackTitle.trim().length>0?r.failover.fallbackTitle.trim():void 0,C=typeof r.providerOptions?.fmessage_1==="string"&&r.providerOptions.fmessage_1.trim().length>0?r.providerOptions.fmessage_1.trim():typeof r.failover?.fallbackContent==="string"&&r.failover.fallbackContent.trim().length>0?r.failover.fallbackContent.trim():void 0;if(k)d.failover=k;if(D)d.fsubject_1=D;if(C)d.fmessage_1=C;let _=r.options?.scheduledAt;if(_ instanceof Date&&!Number.isNaN(_.getTime())){let{date:Ie,time:ye}=q(_);d.reserve="Y",d.reserve_date=Ie,d.reserve_time=ye}let P=await u({host:e.alimtalkHost,endpoint:U("sendAlimTalk",e.config),data:d,providerId:e.providerId});if(P.result_code!=="0")return v(N(P,e.providerId));return Y({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:P.msg_id,status:"PENDING",type:r.type,to:r.to,...Array.isArray(t)&&t.length>0?{warnings:t}:{},raw:P})}async function Ee(e,r){let t=(typeof r.kakao?.profileId==="string"?r.kakao.profileId:e.config.senderKey)||"";if(!t)return v(new b(R.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let i=r.from||e.config.sender||"";if(!i)return v(new b(R.INVALID_REQUEST,"from is required for FRIENDTALK (options.from or config.sender)",{providerId:e.providerId}));let n={apikey:e.config.apiKey,userid:e.config.userId,senderkey:t,sender:i,receiver_1:r.to,subject_1:"친구톡",message_1:r.text,testMode:e.config.testMode?"Y":"N"},a=B({imageUrl:r.imageUrl,media:r.media,providerId:e.providerId});if(a)n.image_1=a;let s=Array.isArray(r.kakao?.buttons)?r.kakao.buttons:r.buttons;if(s)n.button_1=JSON.stringify(s);let l=r.options?.scheduledAt;if(l instanceof Date&&!Number.isNaN(l.getTime())){let{date:o,time:p}=q(l);n.reserve="Y",n.reserve_date=o,n.reserve_time=p}let d=await u({host:e.alimtalkHost,endpoint:U("sendFriendTalk",e.config),data:n,providerId:e.providerId});if(d.result_code!=="0")return v(N(d,e.providerId));return Y({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:d.msg_id,status:"PENDING",type:r.type,to:r.to,raw:d})}async function ge(e,r){try{switch(r.type){case"ALIMTALK":return await Ke(e,r);case"FRIENDTALK":return await Ee(e,r);case"SMS":case"LMS":case"MMS":return await he(e,r);default:return v(new b(R.INVALID_REQUEST,`AligoProvider does not support type ${r.type}`,{providerId:e.providerId,type:r.type}))}}catch(t){return v(N(t,e.providerId))}}function G(){return{apiKey:S("ALIGO_API_KEY")||"",userId:S("ALIGO_USER_ID")||"",senderKey:S("ALIGO_SENDER_KEY")||"",sender:S("ALIGO_SENDER")||"",friendtalkEndpoint:S("ALIGO_FRIENDTALK_ENDPOINT"),testMode:S("NODE_ENV")!=="production",debug:S("NODE_ENV")==="development"}}class M{id="aligo";name="Aligo Smart SMS";supportedTypes=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS"];config;smsHost;alimtalkHost;getOnboardingSpec(){let e=de(this.id);if(!e)throw Error(`Onboarding spec missing for provider: ${this.id}`);return e}constructor(e){if(!e||typeof e!=="object")throw Error("AligoProvider requires a config object");if(!e.apiKey||e.apiKey.length===0)throw Error("AligoProvider requires `apiKey`");if(!e.userId||e.userId.length===0)throw Error("AligoProvider requires `userId`");this.config=e,this.smsHost=e.smsBaseUrl||"https://apis.aligo.in",this.alimtalkHost=e.alimtalkBaseUrl||"https://kakaoapi.aligo.in"}getRuntimeContext(){return{providerId:this.id,config:this.config,smsHost:this.smsHost,alimtalkHost:this.alimtalkHost}}async healthCheck(){let e=Date.now(),r=[];try{if(!this.config.apiKey)r.push("Missing apiKey");if(!this.config.userId)r.push("Missing userId");if(!this.config.sender)r.push("Missing sender (default from)");try{new URL(this.smsHost)}catch{r.push("Invalid smsBaseUrl")}try{new URL(this.alimtalkHost)}catch{r.push("Invalid alimtalkBaseUrl")}return{healthy:r.length===0,issues:r,latencyMs:Date.now()-e,data:{provider:this.id,smsBaseUrl:this.smsHost,alimtalkBaseUrl:this.alimtalkHost}}}catch(t){return r.push(t instanceof Error?t.message:String(t)),{healthy:!1,issues:r,latencyMs:Date.now()-e}}}async send(e){let r=e.messageId||crypto.randomUUID(),t={...e,messageId:r};return ge(this.getRuntimeContext(),t)}async listKakaoChannels(e){return le(this.getRuntimeContext(),e)}async listKakaoChannelCategories(){return pe(this.getRuntimeContext())}async requestKakaoChannelAuth(e){return ue(this.getRuntimeContext(),e)}async addKakaoChannel(e){return fe(this.getRuntimeContext(),e)}}var fr=(e)=>new M(e),Te=()=>{let e=G();if(!e.apiKey||!e.userId)throw Error("ALIGO_API_KEY and ALIGO_USER_ID are required");return new M(e)};class Se{static create(e){return new M(e)}static createDefault(){return Te()}}class O extends M{async createTemplate(e,r){return te(this.getRuntimeContext(),e,r)}async updateTemplate(e,r,t){return ne(this.getRuntimeContext(),e,r,t)}async deleteTemplate(e,r){return ie(this.getRuntimeContext(),e,r)}async getTemplate(e,r){return V(this.getRuntimeContext(),e,r)}async listTemplates(e,r){return oe(this.getRuntimeContext(),e,r)}async requestTemplateInspection(e,r){return ae(this.getRuntimeContext(),e,r)}}var _e=(e)=>new O(e),me=()=>{let e=G();return new O(e)};class ce{static create(e){return new O(e)}static createDefault(){return me()}}function we(){}export{we as initializeAligo,me as createDefaultAligoProvider,_e as createAligoProvider,ce as AligoProviderFactory,O as AligoProvider};
3
3
 
4
- //# debugId=712B4D075ED82CEB64756E2164756E21
4
+ //# debugId=78204922659EE28C64756E2164756E21
5
5
  //# sourceMappingURL=index.mjs.map
@@ -1,32 +1,7 @@
1
- import { type KakaoChannel, type KakaoChannelCategories, type KakaoChannelProvider, type KMsgError, type MessageType, type Provider, type ProviderHealthStatus, type Result, type SendOptions, type SendResult, type Template, type TemplateContext, type TemplateCreateInput, type TemplateInspectionProvider, type TemplateProvider, type TemplateUpdateInput } from "@k-msg/core";
1
+ import type { KMsgError, Result, Template, TemplateContext, TemplateCreateInput, TemplateInspectionProvider, TemplateProvider, TemplateUpdateInput } from "@k-msg/core";
2
+ import { AligoSendProvider } from "./provider.send";
2
3
  import type { AligoConfig } from "./types/aligo";
3
- export declare class AligoProvider implements Provider, TemplateProvider, TemplateInspectionProvider, KakaoChannelProvider {
4
- private readonly config;
5
- readonly id = "aligo";
6
- readonly name = "Aligo Smart SMS";
7
- readonly supportedTypes: readonly MessageType[];
8
- private readonly smsHost;
9
- private readonly alimtalkHost;
10
- getOnboardingSpec(): import("@k-msg/core").ProviderOnboardingSpec;
11
- constructor(config: AligoConfig);
12
- private getRuntimeContext;
13
- healthCheck(): Promise<ProviderHealthStatus>;
14
- send(options: SendOptions): Promise<Result<SendResult, KMsgError>>;
15
- listKakaoChannels(params?: {
16
- plusId?: string;
17
- senderKey?: string;
18
- }): Promise<Result<KakaoChannel[], KMsgError>>;
19
- listKakaoChannelCategories(): Promise<Result<KakaoChannelCategories, KMsgError>>;
20
- requestKakaoChannelAuth(params: {
21
- plusId: string;
22
- phoneNumber: string;
23
- }): Promise<Result<void, KMsgError>>;
24
- addKakaoChannel(params: {
25
- plusId: string;
26
- authNum: string;
27
- phoneNumber: string;
28
- categoryCode: string;
29
- }): Promise<Result<KakaoChannel, KMsgError>>;
4
+ export declare class AligoProvider extends AligoSendProvider implements TemplateProvider, TemplateInspectionProvider {
30
5
  createTemplate(input: TemplateCreateInput, ctx?: TemplateContext): Promise<Result<Template, KMsgError>>;
31
6
  updateTemplate(code: string, patch: TemplateUpdateInput, ctx?: TemplateContext): Promise<Result<Template, KMsgError>>;
32
7
  deleteTemplate(code: string, ctx?: TemplateContext): Promise<Result<void, KMsgError>>;
@@ -0,0 +1,38 @@
1
+ import { type KakaoChannel, type KakaoChannelCategories, type KakaoChannelProvider, type KMsgError, type MessageType, type Provider, type ProviderHealthStatus, type Result, type SendOptions, type SendResult } from "@k-msg/core";
2
+ import type { AligoRuntimeContext } from "./aligo.internal.types";
3
+ import type { AligoConfig } from "./types/aligo";
4
+ export declare function resolveDefaultAligoConfig(): AligoConfig;
5
+ export declare class AligoSendProvider implements Provider, KakaoChannelProvider {
6
+ readonly id = "aligo";
7
+ readonly name = "Aligo Smart SMS";
8
+ readonly supportedTypes: readonly MessageType[];
9
+ protected readonly config: AligoConfig;
10
+ protected readonly smsHost: string;
11
+ protected readonly alimtalkHost: string;
12
+ getOnboardingSpec(): import("@k-msg/core").ProviderOnboardingSpec;
13
+ constructor(config: AligoConfig);
14
+ protected getRuntimeContext(): AligoRuntimeContext;
15
+ healthCheck(): Promise<ProviderHealthStatus>;
16
+ send(options: SendOptions): Promise<Result<SendResult, KMsgError>>;
17
+ listKakaoChannels(params?: {
18
+ plusId?: string;
19
+ senderKey?: string;
20
+ }): Promise<Result<KakaoChannel[], KMsgError>>;
21
+ listKakaoChannelCategories(): Promise<Result<KakaoChannelCategories, KMsgError>>;
22
+ requestKakaoChannelAuth(params: {
23
+ plusId: string;
24
+ phoneNumber: string;
25
+ }): Promise<Result<void, KMsgError>>;
26
+ addKakaoChannel(params: {
27
+ plusId: string;
28
+ authNum: string;
29
+ phoneNumber: string;
30
+ categoryCode: string;
31
+ }): Promise<Result<KakaoChannel, KMsgError>>;
32
+ }
33
+ export declare const createAligoSendProvider: (config: AligoConfig) => AligoSendProvider;
34
+ export declare const createDefaultAligoSendProvider: () => AligoSendProvider;
35
+ export declare class AligoSendProviderFactory {
36
+ static create(config: AligoConfig): AligoSendProvider;
37
+ static createDefault(): AligoSendProvider;
38
+ }
@@ -0,0 +1,26 @@
1
+ import type { KMsgError, Result, Template, TemplateContext, TemplateCreateInput, TemplateInspectionProvider, TemplateProvider, TemplateUpdateInput } from "@k-msg/core";
2
+ import type { AligoConfig } from "./types/aligo";
3
+ export declare class AligoTemplateProvider implements TemplateProvider, TemplateInspectionProvider {
4
+ readonly id = "aligo";
5
+ private readonly config;
6
+ private readonly smsHost;
7
+ private readonly alimtalkHost;
8
+ constructor(config: AligoConfig);
9
+ private getRuntimeContext;
10
+ createTemplate(input: TemplateCreateInput, ctx?: TemplateContext): Promise<Result<Template, KMsgError>>;
11
+ updateTemplate(code: string, patch: TemplateUpdateInput, ctx?: TemplateContext): Promise<Result<Template, KMsgError>>;
12
+ deleteTemplate(code: string, ctx?: TemplateContext): Promise<Result<void, KMsgError>>;
13
+ getTemplate(code: string, ctx?: TemplateContext): Promise<Result<Template, KMsgError>>;
14
+ listTemplates(params?: {
15
+ status?: string;
16
+ page?: number;
17
+ limit?: number;
18
+ }, ctx?: TemplateContext): Promise<Result<Template[], KMsgError>>;
19
+ requestTemplateInspection(code: string, ctx?: TemplateContext): Promise<Result<void, KMsgError>>;
20
+ }
21
+ export declare const createAligoTemplateProvider: (config: AligoConfig) => AligoTemplateProvider;
22
+ export declare const createDefaultAligoTemplateProvider: () => AligoTemplateProvider;
23
+ export declare class AligoTemplateProviderFactory {
24
+ static create(config: AligoConfig): AligoTemplateProvider;
25
+ static createDefault(): AligoTemplateProvider;
26
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Aligo send/channel focused entrypoint.
3
+ */
4
+ export { AligoSendProvider as AligoProvider, AligoSendProvider, AligoSendProviderFactory, createAligoSendProvider as createAligoProvider, createAligoSendProvider, createDefaultAligoSendProvider as createDefaultAligoProvider, createDefaultAligoSendProvider, } from "./provider.send";
5
+ export type { AligoConfig } from "./types/aligo";
@@ -0,0 +1,5 @@
1
+ var{defineProperty:T,getOwnPropertyNames:J,getOwnPropertyDescriptor:z}=Object,X=Object.prototype.hasOwnProperty;var L=new WeakMap,Z=(e)=>{var r=L.get(e),t;if(r)return r;if(r=T({},"__esModule",{value:!0}),e&&typeof e==="object"||typeof e==="function")J(e).map((n)=>!X.call(r,n)&&T(r,n,{get:()=>e[n],enumerable:!(t=z(e,n))||t.enumerable}));return L.set(e,r),r};var x=(e,r)=>{for(var t in r)T(e,t,{get:r[t],enumerable:!0,configurable:!0,set:(n)=>r[t]=()=>n})};var ae={};x(ae,{createDefaultAligoSendProvider:()=>K,createDefaultAligoProvider:()=>K,createAligoSendProvider:()=>w,createAligoProvider:()=>w,AligoSendProviderFactory:()=>O,AligoSendProvider:()=>y,AligoProvider:()=>y});module.exports=Z(ae);var I=require("@k-msg/core");var U={iwinv:{providerId:"iwinv",providerName:"IWINV Messaging Provider",channelOnboarding:"manual",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"unsupported",liveTestSupport:"supported",checks:[{id:"channel_registered_in_console",title:"Kakao channel is registered in IWINV console",description:"IWINV channel onboarding is manual. Confirm channel registration and approval in console.",kind:"manual",severity:"blocker",scopes:["doctor","preflight"]},{id:"iwinv_config_required",title:"IWINV config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey"]},{id:"template_capability_available",title:"Template lifecycle APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate","updateTemplate","deleteTemplate"]},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}],notes:["Channel add/auth is not available via IWINV public API in current integration.","Template APIs are available and can be probed."]},aligo:{providerId:"aligo",providerName:"Aligo Smart SMS",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"required_if_no_inference",plusIdInference:"supported",liveTestSupport:"supported",checks:[{id:"aligo_config_required",title:"Aligo config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","userId"]},{id:"channel_api_capability_available",title:"Kakao channel APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listKakaoChannels","requestKakaoChannelAuth","addKakaoChannel"]},{id:"channel_list_probe",title:"Kakao channel list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_kakao_channels"},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}]},solapi:{providerId:"solapi",providerName:"SOLAPI Messaging Provider",channelOnboarding:"none",templateLifecycleApi:"unavailable",plusIdPolicy:"required_if_no_inference",plusIdInference:"unsupported",liveTestSupport:"partial",checks:[{id:"solapi_config_required",title:"SOLAPI config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","apiSecret"]}],notes:["SOLAPI ALIMTALK requires kakao profileId/pfId, but plusId inference is not available in current integration."]},mock:{providerId:"mock",providerName:"Mock Provider",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"supported",liveTestSupport:"none",checks:[{id:"mock_template_capability_available",title:"Mock template APIs are available",kind:"capability",severity:"info",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate"]}]}};function V(e){return U[e]}function se(){return Object.values(U)}var p=require("@k-msg/core");function m(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}var g=require("@k-msg/core");function A(e,r){if(e instanceof g.KMsgError)return e;return new g.KMsgError(g.KMsgErrorCode.PROVIDER_ERROR,e instanceof Error?e.message:String(e),{providerId:r})}function h(e,r){if(e instanceof g.KMsgError)return e;let t=m(e)?e:{},n=t.result_code,i=n!==void 0&&n!==null?String(n):"UNKNOWN",d=typeof t.message==="string"&&t.message.length>0?t.message:typeof t.msg==="string"&&t.msg.length>0?t.msg:e instanceof Error?e.message:"Unknown Aligo error",s=g.KMsgErrorCode.PROVIDER_ERROR;switch(i){case"-100":case"-101":s=g.KMsgErrorCode.AUTHENTICATION_FAILED;break;case"-102":case"-201":s=g.KMsgErrorCode.INSUFFICIENT_BALANCE;break;case"-103":case"-105":s=g.KMsgErrorCode.INVALID_REQUEST;break;case"-501":s=g.KMsgErrorCode.TEMPLATE_NOT_FOUND;break;default:s=g.KMsgErrorCode.PROVIDER_ERROR}return new g.KMsgError(s,`${d} (code: ${i})`,{providerId:r,resultCode:i})}var f=require("@k-msg/core");var k=require("@k-msg/core");function ee(e,r){if(!e)return"";return e.replace(/#\{([^}]+)\}/g,(t,n)=>{let i=r[n];return i===void 0||i===null?t:String(i)})}function N(e){let r=typeof e.imageUrl==="string"&&e.imageUrl.trim().length>0?e.imageUrl.trim():void 0;if(r)return r;let t=e.media?.image;if(!t)return;if("ref"in t){let n=t.ref.trim();return n.length>0?n:void 0}throw new k.KMsgError(k.KMsgErrorCode.INVALID_REQUEST,"Aligo MMS/FriendTalk image requires `options.imageUrl` or `options.media.image.ref` (url/path).",{providerId:e.providerId})}function E(e,r){switch(e){case"sendSMS":return"/send/";case"sendAlimTalk":return"/akv10/alimtalk/send/";case"sendFriendTalk":return r.friendtalkEndpoint||"/akv10/friendtalk/send/";default:return"/"}}function _(e){let r=e.getFullYear(),t=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0"),i=String(e.getHours()).padStart(2,"0"),d=String(e.getMinutes()).padStart(2,"0");return{date:`${r}${t}${n}`,time:`${i}${d}`}}function q(e){if(typeof e==="number"&&Number.isFinite(e))return e;if(typeof e==="string"){let r=e.trim();if(!r)return;let t=Number(r);if(Number.isFinite(t))return t}return}function fe(e,r){let t=(typeof r?.kakaoChannelSenderKey==="string"&&r.kakaoChannelSenderKey.trim().length>0?r.kakaoChannelSenderKey.trim():e.config.senderKey)||"";if(!t)throw new k.KMsgError(k.KMsgErrorCode.INVALID_REQUEST,"kakao channel senderKey is required (ctx.kakaoChannelSenderKey or config.senderKey)",{providerId:e.providerId});return t}function ce(e){switch(typeof e.inspStatus==="string"?e.inspStatus.trim().toUpperCase():""){case"APR":return"APPROVED";case"REJ":return"REJECTED";case"REQ":case"REG":return"INSPECTION";default:return"PENDING"}}function b(e){if(typeof e!=="string")return;let r=e.trim();if(!r)return;let t=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/.exec(r);if(!t)return;let n=Number(t[1]),i=Number(t[2]),d=Number(t[3]),s=Number(t[4]),l=Number(t[5]),a=Number(t[6]),u=new Date(n,i-1,d,s,l,a);return Number.isNaN(u.getTime())?void 0:u}function F(e,r){if(!e)return"";let t=e._full_text;if(t!==void 0&&t!==null)return String(t);if(!r)return Object.values(e).map(String).join(`
2
+ `);return ee(r,e)}async function c(e){let r=new FormData;for(let[n,i]of Object.entries(e.data))if(i!==void 0&&i!==null)r.append(n,String(i));let t=await fetch(`${e.host}${e.endpoint}`,{method:"POST",body:r});if(!t.ok)throw new f.KMsgError(f.KMsgErrorCode.NETWORK_ERROR,`HTTP error! status: ${t.status}`,{providerId:e.providerId});return await t.json()}function R(e){let{providerId:r,response:t,fallbackMessage:n}=e,i=t.code,d=q(i);if(d===0)return f.ok(void 0);let s=typeof t.message==="string"&&t.message.length>0?t.message:n,l=d===509||d===-99?f.KMsgErrorCode.INVALID_REQUEST:f.KMsgErrorCode.PROVIDER_ERROR;return f.fail(new f.KMsgError(l,s,{providerId:r,originalCode:i,raw:t}))}async function j(e,r){try{let t={apikey:e.config.apiKey,userid:e.config.userId,...typeof r?.plusId==="string"&&r.plusId.trim().length>0?{plusid:r.plusId.trim()}:{},...typeof r?.senderKey==="string"&&r.senderKey.trim().length>0?{senderkey:r.senderKey.trim()}:{}},n=await c({host:e.alimtalkHost,endpoint:"/akv10/profile/list/",data:t,providerId:e.providerId}),i=R({providerId:e.providerId,response:n,fallbackMessage:"channel list failed"});if(i.isFailure)return i;let d=n.list,l=(Array.isArray(d)?d:[]).filter(m).map((a)=>({providerId:e.providerId,senderKey:String(a.senderKey??""),plusId:typeof a.uuid==="string"?a.uuid:void 0,name:typeof a.name==="string"?a.name:void 0,status:typeof a.status==="string"?a.status:void 0,createdAt:b(a.cdate),updatedAt:b(a.udate),raw:a})).filter((a)=>a.senderKey.length>0);return p.ok(l)}catch(t){return p.fail(A(t,e.providerId))}}async function Q(e){try{let r=await c({host:e.alimtalkHost,endpoint:"/akv10/category/",data:{apikey:e.config.apiKey,userid:e.config.userId},providerId:e.providerId}),t=R({providerId:e.providerId,response:r,fallbackMessage:"category list failed"});if(t.isFailure)return t;let n=m(r.data)?r.data:{},i=(d)=>{return(Array.isArray(d)?d:[]).filter(m).map((l)=>({code:String(l.code??""),name:String(l.name??""),parentCode:typeof l.parentCode==="string"&&l.parentCode.length>0?l.parentCode:void 0})).filter((l)=>l.code.length>0)};return p.ok({first:i(n.firstBusinessType),second:i(n.secondBusinessType),third:i(n.thirdBusinessType)})}catch(r){return p.fail(A(r,e.providerId))}}async function $(e,r){try{let t=r.plusId.trim(),n=r.phoneNumber.trim();if(!t||!n)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"plusId and phoneNumber are required",{providerId:e.providerId}));let i=await c({host:e.alimtalkHost,endpoint:"/akv10/profile/auth/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:t,phonenumber:n},providerId:e.providerId}),d=R({providerId:e.providerId,response:i,fallbackMessage:"channel auth failed"});if(d.isFailure)return d;return p.ok(void 0)}catch(t){return p.fail(A(t,e.providerId))}}async function H(e,r){try{let t=r.plusId.trim(),n=r.authNum.trim(),i=r.phoneNumber.trim(),d=r.categoryCode.trim();if(!t||!n||!i||!d)return p.fail(new p.KMsgError(p.KMsgErrorCode.INVALID_REQUEST,"plusId, authNum, phoneNumber, categoryCode are required",{providerId:e.providerId}));let s=await c({host:e.alimtalkHost,endpoint:"/akv10/profile/add/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:t,authnum:n,phonenumber:i,categorycode:d},providerId:e.providerId}),l=R({providerId:e.providerId,response:s,fallbackMessage:"channel add failed"});if(l.isFailure)return l;let a=s.data,u=Array.isArray(a)?a.find(m):m(a)?a:void 0;if(!u)return p.fail(new p.KMsgError(p.KMsgErrorCode.PROVIDER_ERROR,"channel add returned empty data",{providerId:e.providerId,raw:s}));let v=String(u.senderKey??"");if(!v)return p.fail(new p.KMsgError(p.KMsgErrorCode.PROVIDER_ERROR,"channel add did not return senderKey",{providerId:e.providerId,raw:u}));return p.ok({providerId:e.providerId,senderKey:v,plusId:typeof u.uuid==="string"?u.uuid:t,name:typeof u.name==="string"?u.name:void 0,status:typeof u.status==="string"?u.status:void 0,createdAt:b(u.cdate),updatedAt:b(u.udate),raw:u})}catch(t){return p.fail(A(t,e.providerId))}}var o=require("@k-msg/core");function re(e,r){if(e.type!=="ALIMTALK")return;if(e.failover?.enabled!==!0)return;return[{code:"FAILOVER_PARTIAL_PROVIDER",message:"Aligo failover mapping is partial. API-level fallback may be attempted for non-Kakao-user failures.",details:{providerId:r,mappedFields:["failover","fmessage_1","fsubject_1"],unsupportedFields:["fallbackChannel"]}}]}async function te(e,r){let t=r.from||e.config.sender||"";if(!t)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"from is required for SMS/LMS/MMS (options.from or config.sender)",{providerId:e.providerId}));let n={key:e.config.apiKey,user_id:e.config.userId,sender:t,receiver:r.to,msg:r.text,msg_type:r.type,title:r.subject,testmode_yn:e.config.testMode?"Y":"N"},i=r.options?.scheduledAt;if(i instanceof Date&&!Number.isNaN(i.getTime())){let{date:s,time:l}=_(i);n.rdate=s,n.rtime=l}if(r.type==="MMS"){let s=N({imageUrl:r.imageUrl,media:r.media,providerId:e.providerId});if(!s)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"image is required for MMS (options.imageUrl or options.media.image.ref)",{providerId:e.providerId}));n.image=s}let d=await c({host:e.smsHost,endpoint:E("sendSMS",e.config),data:n,providerId:e.providerId});if(d.result_code!=="1")return o.fail(h(d,e.providerId));return o.ok({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:d.msg_id,status:"PENDING",type:r.type,to:r.to,raw:d})}async function ne(e,r){let t=re(r,e.providerId),n=(typeof r.kakao?.profileId==="string"?r.kakao.profileId:e.config.senderKey)||"";if(!n)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let i=r.from||e.config.sender||"";if(!i)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"from is required for ALIMTALK (options.from or config.sender)",{providerId:e.providerId}));let{variables:d,templateId:s}=r;if(!s||s.length===0)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"templateId is required for ALIMTALK",{providerId:e.providerId}));let l=typeof r.providerOptions?.templateContent==="string"?r.providerOptions.templateContent:void 0,a={apikey:e.config.apiKey,userid:e.config.userId,senderkey:n,tpl_code:s,sender:i,receiver_1:r.to,subject_1:"알림톡",message_1:F(d,l),testMode:e.config.testMode?"Y":"N"},u=typeof r.providerOptions?.failover==="string"?r.providerOptions.failover.trim().toUpperCase():"",v=u==="Y"||u==="N"?u:void 0,Y=r.failover?.enabled===!0?"Y":r.failover?.enabled===!1?"N":void 0,C=v??Y,P=typeof r.providerOptions?.fsubject_1==="string"&&r.providerOptions.fsubject_1.trim().length>0?r.providerOptions.fsubject_1.trim():typeof r.failover?.fallbackTitle==="string"&&r.failover.fallbackTitle.trim().length>0?r.failover.fallbackTitle.trim():void 0,D=typeof r.providerOptions?.fmessage_1==="string"&&r.providerOptions.fmessage_1.trim().length>0?r.providerOptions.fmessage_1.trim():typeof r.failover?.fallbackContent==="string"&&r.failover.fallbackContent.trim().length>0?r.failover.fallbackContent.trim():void 0;if(C)a.failover=C;if(P)a.fsubject_1=P;if(D)a.fmessage_1=D;let M=r.options?.scheduledAt;if(M instanceof Date&&!Number.isNaN(M.getTime())){let{date:B,time:G}=_(M);a.reserve="Y",a.reserve_date=B,a.reserve_time=G}let S=await c({host:e.alimtalkHost,endpoint:E("sendAlimTalk",e.config),data:a,providerId:e.providerId});if(S.result_code!=="0")return o.fail(h(S,e.providerId));return o.ok({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:S.msg_id,status:"PENDING",type:r.type,to:r.to,...Array.isArray(t)&&t.length>0?{warnings:t}:{},raw:S})}async function ie(e,r){let t=(typeof r.kakao?.profileId==="string"?r.kakao.profileId:e.config.senderKey)||"";if(!t)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let n=r.from||e.config.sender||"";if(!n)return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,"from is required for FRIENDTALK (options.from or config.sender)",{providerId:e.providerId}));let i={apikey:e.config.apiKey,userid:e.config.userId,senderkey:t,sender:n,receiver_1:r.to,subject_1:"친구톡",message_1:r.text,testMode:e.config.testMode?"Y":"N"},d=N({imageUrl:r.imageUrl,media:r.media,providerId:e.providerId});if(d)i.image_1=d;let s=Array.isArray(r.kakao?.buttons)?r.kakao.buttons:r.buttons;if(s)i.button_1=JSON.stringify(s);let l=r.options?.scheduledAt;if(l instanceof Date&&!Number.isNaN(l.getTime())){let{date:u,time:v}=_(l);i.reserve="Y",i.reserve_date=u,i.reserve_time=v}let a=await c({host:e.alimtalkHost,endpoint:E("sendFriendTalk",e.config),data:i,providerId:e.providerId});if(a.result_code!=="0")return o.fail(h(a,e.providerId));return o.ok({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:a.msg_id,status:"PENDING",type:r.type,to:r.to,raw:a})}async function W(e,r){try{switch(r.type){case"ALIMTALK":return await ne(e,r);case"FRIENDTALK":return await ie(e,r);case"SMS":case"LMS":case"MMS":return await te(e,r);default:return o.fail(new o.KMsgError(o.KMsgErrorCode.INVALID_REQUEST,`AligoProvider does not support type ${r.type}`,{providerId:e.providerId,type:r.type}))}}catch(t){return o.fail(h(t,e.providerId))}}function oe(){return{apiKey:I.readRuntimeEnv("ALIGO_API_KEY")||"",userId:I.readRuntimeEnv("ALIGO_USER_ID")||"",senderKey:I.readRuntimeEnv("ALIGO_SENDER_KEY")||"",sender:I.readRuntimeEnv("ALIGO_SENDER")||"",friendtalkEndpoint:I.readRuntimeEnv("ALIGO_FRIENDTALK_ENDPOINT"),testMode:I.readRuntimeEnv("NODE_ENV")!=="production",debug:I.readRuntimeEnv("NODE_ENV")==="development"}}class y{id="aligo";name="Aligo Smart SMS";supportedTypes=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS"];config;smsHost;alimtalkHost;getOnboardingSpec(){let e=V(this.id);if(!e)throw Error(`Onboarding spec missing for provider: ${this.id}`);return e}constructor(e){if(!e||typeof e!=="object")throw Error("AligoProvider requires a config object");if(!e.apiKey||e.apiKey.length===0)throw Error("AligoProvider requires `apiKey`");if(!e.userId||e.userId.length===0)throw Error("AligoProvider requires `userId`");this.config=e,this.smsHost=e.smsBaseUrl||"https://apis.aligo.in",this.alimtalkHost=e.alimtalkBaseUrl||"https://kakaoapi.aligo.in"}getRuntimeContext(){return{providerId:this.id,config:this.config,smsHost:this.smsHost,alimtalkHost:this.alimtalkHost}}async healthCheck(){let e=Date.now(),r=[];try{if(!this.config.apiKey)r.push("Missing apiKey");if(!this.config.userId)r.push("Missing userId");if(!this.config.sender)r.push("Missing sender (default from)");try{new URL(this.smsHost)}catch{r.push("Invalid smsBaseUrl")}try{new URL(this.alimtalkHost)}catch{r.push("Invalid alimtalkBaseUrl")}return{healthy:r.length===0,issues:r,latencyMs:Date.now()-e,data:{provider:this.id,smsBaseUrl:this.smsHost,alimtalkBaseUrl:this.alimtalkHost}}}catch(t){return r.push(t instanceof Error?t.message:String(t)),{healthy:!1,issues:r,latencyMs:Date.now()-e}}}async send(e){let r=e.messageId||crypto.randomUUID(),t={...e,messageId:r};return W(this.getRuntimeContext(),t)}async listKakaoChannels(e){return j(this.getRuntimeContext(),e)}async listKakaoChannelCategories(){return Q(this.getRuntimeContext())}async requestKakaoChannelAuth(e){return $(this.getRuntimeContext(),e)}async addKakaoChannel(e){return H(this.getRuntimeContext(),e)}}var w=(e)=>new y(e),K=()=>{let e=oe();if(!e.apiKey||!e.userId)throw Error("ALIGO_API_KEY and ALIGO_USER_ID are required");return new y(e)};class O{static create(e){return new y(e)}static createDefault(){return K()}}
3
+
4
+ //# debugId=98371AFDEF46151964756E2164756E21
5
+ //# sourceMappingURL=send.js.map
@@ -0,0 +1,5 @@
1
+ import{readRuntimeEnv as y}from"@k-msg/core";var q={iwinv:{providerId:"iwinv",providerName:"IWINV Messaging Provider",channelOnboarding:"manual",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"unsupported",liveTestSupport:"supported",checks:[{id:"channel_registered_in_console",title:"Kakao channel is registered in IWINV console",description:"IWINV channel onboarding is manual. Confirm channel registration and approval in console.",kind:"manual",severity:"blocker",scopes:["doctor","preflight"]},{id:"iwinv_config_required",title:"IWINV config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey"]},{id:"template_capability_available",title:"Template lifecycle APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate","updateTemplate","deleteTemplate"]},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}],notes:["Channel add/auth is not available via IWINV public API in current integration.","Template APIs are available and can be probed."]},aligo:{providerId:"aligo",providerName:"Aligo Smart SMS",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"required_if_no_inference",plusIdInference:"supported",liveTestSupport:"supported",checks:[{id:"aligo_config_required",title:"Aligo config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","userId"]},{id:"channel_api_capability_available",title:"Kakao channel APIs are available",kind:"capability",severity:"warning",scopes:["doctor","preflight"],capabilityMethods:["listKakaoChannels","requestKakaoChannelAuth","addKakaoChannel"]},{id:"channel_list_probe",title:"Kakao channel list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_kakao_channels"},{id:"template_list_probe",title:"Template list API probe",kind:"api_probe",severity:"warning",scopes:["doctor","preflight"],probeOperation:"list_templates"}]},solapi:{providerId:"solapi",providerName:"SOLAPI Messaging Provider",channelOnboarding:"none",templateLifecycleApi:"unavailable",plusIdPolicy:"required_if_no_inference",plusIdInference:"unsupported",liveTestSupport:"partial",checks:[{id:"solapi_config_required",title:"SOLAPI config has required keys",kind:"config",severity:"blocker",scopes:["doctor","preflight"],configKeys:["apiKey","apiSecret"]}],notes:["SOLAPI ALIMTALK requires kakao profileId/pfId, but plusId inference is not available in current integration."]},mock:{providerId:"mock",providerName:"Mock Provider",channelOnboarding:"api",templateLifecycleApi:"available",plusIdPolicy:"optional",plusIdInference:"supported",liveTestSupport:"none",checks:[{id:"mock_template_capability_available",title:"Mock template APIs are available",kind:"capability",severity:"info",scopes:["doctor","preflight"],capabilityMethods:["listTemplates","getTemplate","createTemplate"]}]}};function F(e){return q[e]}function pe(){return Object.values(q)}import{fail as f,KMsgError as M,KMsgErrorCode as T,ok as N}from"@k-msg/core";function g(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}import{KMsgError as E,KMsgErrorCode as I}from"@k-msg/core";function A(e,r){if(e instanceof E)return e;return new E(I.PROVIDER_ERROR,e instanceof Error?e.message:String(e),{providerId:r})}function h(e,r){if(e instanceof E)return e;let t=g(e)?e:{},i=t.result_code,n=i!==void 0&&i!==null?String(i):"UNKNOWN",a=typeof t.message==="string"&&t.message.length>0?t.message:typeof t.msg==="string"&&t.msg.length>0?t.msg:e instanceof Error?e.message:"Unknown Aligo error",d=I.PROVIDER_ERROR;switch(n){case"-100":case"-101":d=I.AUTHENTICATION_FAILED;break;case"-102":case"-201":d=I.INSUFFICIENT_BALANCE;break;case"-103":case"-105":d=I.INVALID_REQUEST;break;case"-501":d=I.TEMPLATE_NOT_FOUND;break;default:d=I.PROVIDER_ERROR}return new E(d,`${a} (code: ${n})`,{providerId:r,resultCode:n})}import{fail as ne,KMsgError as W,KMsgErrorCode as C,ok as ie}from"@k-msg/core";import{KMsgError as j,KMsgErrorCode as Q}from"@k-msg/core";function te(e,r){if(!e)return"";return e.replace(/#\{([^}]+)\}/g,(t,i)=>{let n=r[i];return n===void 0||n===null?t:String(n)})}function O(e){let r=typeof e.imageUrl==="string"&&e.imageUrl.trim().length>0?e.imageUrl.trim():void 0;if(r)return r;let t=e.media?.image;if(!t)return;if("ref"in t){let i=t.ref.trim();return i.length>0?i:void 0}throw new j(Q.INVALID_REQUEST,"Aligo MMS/FriendTalk image requires `options.imageUrl` or `options.media.image.ref` (url/path).",{providerId:e.providerId})}function _(e,r){switch(e){case"sendSMS":return"/send/";case"sendAlimTalk":return"/akv10/alimtalk/send/";case"sendFriendTalk":return r.friendtalkEndpoint||"/akv10/friendtalk/send/";default:return"/"}}function K(e){let r=e.getFullYear(),t=String(e.getMonth()+1).padStart(2,"0"),i=String(e.getDate()).padStart(2,"0"),n=String(e.getHours()).padStart(2,"0"),a=String(e.getMinutes()).padStart(2,"0");return{date:`${r}${t}${i}`,time:`${n}${a}`}}function $(e){if(typeof e==="number"&&Number.isFinite(e))return e;if(typeof e==="string"){let r=e.trim();if(!r)return;let t=Number(r);if(Number.isFinite(t))return t}return}function ye(e,r){let t=(typeof r?.kakaoChannelSenderKey==="string"&&r.kakaoChannelSenderKey.trim().length>0?r.kakaoChannelSenderKey.trim():e.config.senderKey)||"";if(!t)throw new j(Q.INVALID_REQUEST,"kakao channel senderKey is required (ctx.kakaoChannelSenderKey or config.senderKey)",{providerId:e.providerId});return t}function ve(e){switch(typeof e.inspStatus==="string"?e.inspStatus.trim().toUpperCase():""){case"APR":return"APPROVED";case"REJ":return"REJECTED";case"REQ":case"REG":return"INSPECTION";default:return"PENDING"}}function b(e){if(typeof e!=="string")return;let r=e.trim();if(!r)return;let t=/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/.exec(r);if(!t)return;let i=Number(t[1]),n=Number(t[2]),a=Number(t[3]),d=Number(t[4]),s=Number(t[5]),o=Number(t[6]),l=new Date(i,n-1,a,d,s,o);return Number.isNaN(l.getTime())?void 0:l}function H(e,r){if(!e)return"";let t=e._full_text;if(t!==void 0&&t!==null)return String(t);if(!r)return Object.values(e).map(String).join(`
2
+ `);return te(r,e)}async function u(e){let r=new FormData;for(let[i,n]of Object.entries(e.data))if(n!==void 0&&n!==null)r.append(i,String(n));let t=await fetch(`${e.host}${e.endpoint}`,{method:"POST",body:r});if(!t.ok)throw new W(C.NETWORK_ERROR,`HTTP error! status: ${t.status}`,{providerId:e.providerId});return await t.json()}function R(e){let{providerId:r,response:t,fallbackMessage:i}=e,n=t.code,a=$(n);if(a===0)return ie(void 0);let d=typeof t.message==="string"&&t.message.length>0?t.message:i,s=a===509||a===-99?C.INVALID_REQUEST:C.PROVIDER_ERROR;return ne(new W(s,d,{providerId:r,originalCode:n,raw:t}))}async function Y(e,r){try{let t={apikey:e.config.apiKey,userid:e.config.userId,...typeof r?.plusId==="string"&&r.plusId.trim().length>0?{plusid:r.plusId.trim()}:{},...typeof r?.senderKey==="string"&&r.senderKey.trim().length>0?{senderkey:r.senderKey.trim()}:{}},i=await u({host:e.alimtalkHost,endpoint:"/akv10/profile/list/",data:t,providerId:e.providerId}),n=R({providerId:e.providerId,response:i,fallbackMessage:"channel list failed"});if(n.isFailure)return n;let a=i.list,s=(Array.isArray(a)?a:[]).filter(g).map((o)=>({providerId:e.providerId,senderKey:String(o.senderKey??""),plusId:typeof o.uuid==="string"?o.uuid:void 0,name:typeof o.name==="string"?o.name:void 0,status:typeof o.status==="string"?o.status:void 0,createdAt:b(o.cdate),updatedAt:b(o.udate),raw:o})).filter((o)=>o.senderKey.length>0);return N(s)}catch(t){return f(A(t,e.providerId))}}async function B(e){try{let r=await u({host:e.alimtalkHost,endpoint:"/akv10/category/",data:{apikey:e.config.apiKey,userid:e.config.userId},providerId:e.providerId}),t=R({providerId:e.providerId,response:r,fallbackMessage:"category list failed"});if(t.isFailure)return t;let i=g(r.data)?r.data:{},n=(a)=>{return(Array.isArray(a)?a:[]).filter(g).map((s)=>({code:String(s.code??""),name:String(s.name??""),parentCode:typeof s.parentCode==="string"&&s.parentCode.length>0?s.parentCode:void 0})).filter((s)=>s.code.length>0)};return N({first:n(i.firstBusinessType),second:n(i.secondBusinessType),third:n(i.thirdBusinessType)})}catch(r){return f(A(r,e.providerId))}}async function G(e,r){try{let t=r.plusId.trim(),i=r.phoneNumber.trim();if(!t||!i)return f(new M(T.INVALID_REQUEST,"plusId and phoneNumber are required",{providerId:e.providerId}));let n=await u({host:e.alimtalkHost,endpoint:"/akv10/profile/auth/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:t,phonenumber:i},providerId:e.providerId}),a=R({providerId:e.providerId,response:n,fallbackMessage:"channel auth failed"});if(a.isFailure)return a;return N(void 0)}catch(t){return f(A(t,e.providerId))}}async function J(e,r){try{let t=r.plusId.trim(),i=r.authNum.trim(),n=r.phoneNumber.trim(),a=r.categoryCode.trim();if(!t||!i||!n||!a)return f(new M(T.INVALID_REQUEST,"plusId, authNum, phoneNumber, categoryCode are required",{providerId:e.providerId}));let d=await u({host:e.alimtalkHost,endpoint:"/akv10/profile/add/",data:{apikey:e.config.apiKey,userid:e.config.userId,plusid:t,authnum:i,phonenumber:n,categorycode:a},providerId:e.providerId}),s=R({providerId:e.providerId,response:d,fallbackMessage:"channel add failed"});if(s.isFailure)return s;let o=d.data,l=Array.isArray(o)?o.find(g):g(o)?o:void 0;if(!l)return f(new M(T.PROVIDER_ERROR,"channel add returned empty data",{providerId:e.providerId,raw:d}));let v=String(l.senderKey??"");if(!v)return f(new M(T.PROVIDER_ERROR,"channel add did not return senderKey",{providerId:e.providerId,raw:l}));return N({providerId:e.providerId,senderKey:v,plusId:typeof l.uuid==="string"?l.uuid:t,name:typeof l.name==="string"?l.name:void 0,status:typeof l.status==="string"?l.status:void 0,createdAt:b(l.cdate),updatedAt:b(l.udate),raw:l})}catch(t){return f(A(t,e.providerId))}}import{fail as p,KMsgError as c,KMsgErrorCode as m,ok as P}from"@k-msg/core";function oe(e,r){if(e.type!=="ALIMTALK")return;if(e.failover?.enabled!==!0)return;return[{code:"FAILOVER_PARTIAL_PROVIDER",message:"Aligo failover mapping is partial. API-level fallback may be attempted for non-Kakao-user failures.",details:{providerId:r,mappedFields:["failover","fmessage_1","fsubject_1"],unsupportedFields:["fallbackChannel"]}}]}async function ae(e,r){let t=r.from||e.config.sender||"";if(!t)return p(new c(m.INVALID_REQUEST,"from is required for SMS/LMS/MMS (options.from or config.sender)",{providerId:e.providerId}));let i={key:e.config.apiKey,user_id:e.config.userId,sender:t,receiver:r.to,msg:r.text,msg_type:r.type,title:r.subject,testmode_yn:e.config.testMode?"Y":"N"},n=r.options?.scheduledAt;if(n instanceof Date&&!Number.isNaN(n.getTime())){let{date:d,time:s}=K(n);i.rdate=d,i.rtime=s}if(r.type==="MMS"){let d=O({imageUrl:r.imageUrl,media:r.media,providerId:e.providerId});if(!d)return p(new c(m.INVALID_REQUEST,"image is required for MMS (options.imageUrl or options.media.image.ref)",{providerId:e.providerId}));i.image=d}let a=await u({host:e.smsHost,endpoint:_("sendSMS",e.config),data:i,providerId:e.providerId});if(a.result_code!=="1")return p(h(a,e.providerId));return P({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:a.msg_id,status:"PENDING",type:r.type,to:r.to,raw:a})}async function de(e,r){let t=oe(r,e.providerId),i=(typeof r.kakao?.profileId==="string"?r.kakao.profileId:e.config.senderKey)||"";if(!i)return p(new c(m.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let n=r.from||e.config.sender||"";if(!n)return p(new c(m.INVALID_REQUEST,"from is required for ALIMTALK (options.from or config.sender)",{providerId:e.providerId}));let{variables:a,templateId:d}=r;if(!d||d.length===0)return p(new c(m.INVALID_REQUEST,"templateId is required for ALIMTALK",{providerId:e.providerId}));let s=typeof r.providerOptions?.templateContent==="string"?r.providerOptions.templateContent:void 0,o={apikey:e.config.apiKey,userid:e.config.userId,senderkey:i,tpl_code:d,sender:n,receiver_1:r.to,subject_1:"알림톡",message_1:H(a,s),testMode:e.config.testMode?"Y":"N"},l=typeof r.providerOptions?.failover==="string"?r.providerOptions.failover.trim().toUpperCase():"",v=l==="Y"||l==="N"?l:void 0,x=r.failover?.enabled===!0?"Y":r.failover?.enabled===!1?"N":void 0,L=v??x,U=typeof r.providerOptions?.fsubject_1==="string"&&r.providerOptions.fsubject_1.trim().length>0?r.providerOptions.fsubject_1.trim():typeof r.failover?.fallbackTitle==="string"&&r.failover.fallbackTitle.trim().length>0?r.failover.fallbackTitle.trim():void 0,V=typeof r.providerOptions?.fmessage_1==="string"&&r.providerOptions.fmessage_1.trim().length>0?r.providerOptions.fmessage_1.trim():typeof r.failover?.fallbackContent==="string"&&r.failover.fallbackContent.trim().length>0?r.failover.fallbackContent.trim():void 0;if(L)o.failover=L;if(U)o.fsubject_1=U;if(V)o.fmessage_1=V;let w=r.options?.scheduledAt;if(w instanceof Date&&!Number.isNaN(w.getTime())){let{date:ee,time:re}=K(w);o.reserve="Y",o.reserve_date=ee,o.reserve_time=re}let S=await u({host:e.alimtalkHost,endpoint:_("sendAlimTalk",e.config),data:o,providerId:e.providerId});if(S.result_code!=="0")return p(h(S,e.providerId));return P({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:S.msg_id,status:"PENDING",type:r.type,to:r.to,...Array.isArray(t)&&t.length>0?{warnings:t}:{},raw:S})}async function se(e,r){let t=(typeof r.kakao?.profileId==="string"?r.kakao.profileId:e.config.senderKey)||"";if(!t)return p(new c(m.INVALID_REQUEST,"kakao profileId is required (options.kakao.profileId or config.senderKey)",{providerId:e.providerId}));let i=r.from||e.config.sender||"";if(!i)return p(new c(m.INVALID_REQUEST,"from is required for FRIENDTALK (options.from or config.sender)",{providerId:e.providerId}));let n={apikey:e.config.apiKey,userid:e.config.userId,senderkey:t,sender:i,receiver_1:r.to,subject_1:"친구톡",message_1:r.text,testMode:e.config.testMode?"Y":"N"},a=O({imageUrl:r.imageUrl,media:r.media,providerId:e.providerId});if(a)n.image_1=a;let d=Array.isArray(r.kakao?.buttons)?r.kakao.buttons:r.buttons;if(d)n.button_1=JSON.stringify(d);let s=r.options?.scheduledAt;if(s instanceof Date&&!Number.isNaN(s.getTime())){let{date:l,time:v}=K(s);n.reserve="Y",n.reserve_date=l,n.reserve_time=v}let o=await u({host:e.alimtalkHost,endpoint:_("sendFriendTalk",e.config),data:n,providerId:e.providerId});if(o.result_code!=="0")return p(h(o,e.providerId));return P({messageId:r.messageId||crypto.randomUUID(),providerId:e.providerId,providerMessageId:o.msg_id,status:"PENDING",type:r.type,to:r.to,raw:o})}async function z(e,r){try{switch(r.type){case"ALIMTALK":return await de(e,r);case"FRIENDTALK":return await se(e,r);case"SMS":case"LMS":case"MMS":return await ae(e,r);default:return p(new c(m.INVALID_REQUEST,`AligoProvider does not support type ${r.type}`,{providerId:e.providerId,type:r.type}))}}catch(t){return p(h(t,e.providerId))}}function le(){return{apiKey:y("ALIGO_API_KEY")||"",userId:y("ALIGO_USER_ID")||"",senderKey:y("ALIGO_SENDER_KEY")||"",sender:y("ALIGO_SENDER")||"",friendtalkEndpoint:y("ALIGO_FRIENDTALK_ENDPOINT"),testMode:y("NODE_ENV")!=="production",debug:y("NODE_ENV")==="development"}}class k{id="aligo";name="Aligo Smart SMS";supportedTypes=["ALIMTALK","FRIENDTALK","SMS","LMS","MMS"];config;smsHost;alimtalkHost;getOnboardingSpec(){let e=F(this.id);if(!e)throw Error(`Onboarding spec missing for provider: ${this.id}`);return e}constructor(e){if(!e||typeof e!=="object")throw Error("AligoProvider requires a config object");if(!e.apiKey||e.apiKey.length===0)throw Error("AligoProvider requires `apiKey`");if(!e.userId||e.userId.length===0)throw Error("AligoProvider requires `userId`");this.config=e,this.smsHost=e.smsBaseUrl||"https://apis.aligo.in",this.alimtalkHost=e.alimtalkBaseUrl||"https://kakaoapi.aligo.in"}getRuntimeContext(){return{providerId:this.id,config:this.config,smsHost:this.smsHost,alimtalkHost:this.alimtalkHost}}async healthCheck(){let e=Date.now(),r=[];try{if(!this.config.apiKey)r.push("Missing apiKey");if(!this.config.userId)r.push("Missing userId");if(!this.config.sender)r.push("Missing sender (default from)");try{new URL(this.smsHost)}catch{r.push("Invalid smsBaseUrl")}try{new URL(this.alimtalkHost)}catch{r.push("Invalid alimtalkBaseUrl")}return{healthy:r.length===0,issues:r,latencyMs:Date.now()-e,data:{provider:this.id,smsBaseUrl:this.smsHost,alimtalkBaseUrl:this.alimtalkHost}}}catch(t){return r.push(t instanceof Error?t.message:String(t)),{healthy:!1,issues:r,latencyMs:Date.now()-e}}}async send(e){let r=e.messageId||crypto.randomUUID(),t={...e,messageId:r};return z(this.getRuntimeContext(),t)}async listKakaoChannels(e){return Y(this.getRuntimeContext(),e)}async listKakaoChannelCategories(){return B(this.getRuntimeContext())}async requestKakaoChannelAuth(e){return G(this.getRuntimeContext(),e)}async addKakaoChannel(e){return J(this.getRuntimeContext(),e)}}var X=(e)=>new k(e),D=()=>{let e=le();if(!e.apiKey||!e.userId)throw Error("ALIGO_API_KEY and ALIGO_USER_ID are required");return new k(e)};class Z{static create(e){return new k(e)}static createDefault(){return D()}}export{D as createDefaultAligoSendProvider,D as createDefaultAligoProvider,X as createAligoSendProvider,X as createAligoProvider,Z as AligoSendProviderFactory,k as AligoSendProvider,k as AligoProvider};
3
+
4
+ //# debugId=83CE9FBB558A992064756E2164756E21
5
+ //# sourceMappingURL=send.mjs.map
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Aligo template CRUD focused entrypoint.
3
+ */
4
+ export { createTemplate, deleteTemplate, getTemplate, listTemplates, requestTemplateInspection, updateTemplate, } from "./aligo.template";
5
+ export { AligoTemplateProvider, AligoTemplateProviderFactory, createAligoTemplateProvider, createDefaultAligoTemplateProvider, } from "./provider.template";
6
+ export type { AligoConfig } from "./types/aligo";