diff options
| author | joonhoekim <26rote@gmail.com> | 2025-07-18 03:58:34 +0000 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-07-18 03:58:34 +0000 |
| commit | 3e59693e017742d971f490eb7c58870cb745a98d (patch) | |
| tree | f7f846613e40e4f058de70afca5809b8e6bd0e2d /lib/knox-api/realtime-notification | |
| parent | 2ef02e27dbe639876fa3b90c30307dda183545ec (diff) | |
(김준회) 결재 모듈 개발
Diffstat (limited to 'lib/knox-api/realtime-notification')
| -rw-r--r-- | lib/knox-api/realtime-notification/realtime-notification-guide.html | 764 | ||||
| -rw-r--r-- | lib/knox-api/realtime-notification/realtime-notification.ts | 333 |
2 files changed, 1097 insertions, 0 deletions
diff --git a/lib/knox-api/realtime-notification/realtime-notification-guide.html b/lib/knox-api/realtime-notification/realtime-notification-guide.html new file mode 100644 index 00000000..728df9c1 --- /dev/null +++ b/lib/knox-api/realtime-notification/realtime-notification-guide.html @@ -0,0 +1,764 @@ +<div class="body-content"> + <div class="sub-header margin"> + <h2 data-message-id="noti.subject">실시간알림</h2> + </div> + <div class="module-subsum"> + <p><span data-message-id="noti.guide.description">Knox Suite을 통해 토스트 알림을 전송합니다.</span></p> + </div><br><br> + <div class="module-font type03"><span data-message-id="noti.guide.policy01">[정책 및 제약사항]</span></div> + <div class="module-font type04"> + <dl> + <dt><span data-message-id="noti.guide.policy02">1. 토스트알림은 Knox Suite 로그인 사용자에게만 전송가능합니다.</span></dt> + <dt><span data-message-id="noti.guide.policy03">2. 토스트알림에 포함 된 링크는 호출 시 사전 확인 필요합니다.</span></dt> + <dt><span data-message-id="noti.guide.policy04">3. 토스트알림 최대 수신인은 100명을 초과할 수 없습니다.</span></dt> + </dl> + </div><br><br> + <div class="module-font type03"><span data-message-id="subject.api.list">[API 목록]</span> <a + target="blank" class="swagger-link" id="swaggerLinkStg" + href="http://developers.samsung.net/knoxcenter/wso2/swagger-ui/982ed416-88ed-4a6a-ba08-32de77173194"><span + data-message-id="subject.go.to.swagger">테스트 페이지로 이동(Swagger)</span></a><span + data-message-id="subject.go.to.swagger.chrome"><sub>*Chrome Browser만 이용 가능합니다.</sub></span></div> + <div class="tbl-list01 kc-tbl"> + <div class="tbl-list-head"> + <table> + <colgroup> + <col width="150px"> + <col width="300px"> + <col width="100px"> + <col style="width:"> + </colgroup> + <thead> + <tr> + <th>API</th> + <th>URI</th> + <th>Method</th> + <th>Description</th> + </tr> + </thead> + </table> + </div> + <div class="tbl-list-body"> + <table> + <colgroup> + <col width="150px"> + <col width="300px"> + <col width="100px"> + <col style="width:"> + </colgroup> + <tbody> + <tr> + <td><a href="#emp"><span data-message-id="noti.guide.api02">알림 전송</span></a></td> + <td>/sendnotification</td> + <td>POST</td> + <td align="left"><span data-message-id="noti.guide.api03">실시간 토스트 알림 전송</span></td> + </tr> + </tbody> + </table> + </div> + </div><br><br><br> + <div class="dan-border"></div><br><br> + <div class="module-font type01" id="emp"><span data-message-id="noti.guide.sendnotification">알림 전송</span></div> + <div class="module-font type02"> + <p>Request Parameter</p><span data-message-id="noti.guide.sendnotification.request.title">URL : + /notification/api/v2.0/sendnotification</span> + </div> + <div class="tbl-list01 kc-tbl text-full"> + <div class="tbl-list-head"> + <table> + <colgroup> + <col width="5%;"> + <col width="15%;"> + <col width="15%;"> + <col width="8%;"> + <col width="8%;"> + <col width="8%;"> + <col width="19%;"> + <col width="20%;"> + </colgroup> + <thead> + <tr> + <th>No.</th> + <th class="left">Properties</th> + <th class="left">Attribute</th> + <th>Mandatory</th> + <th>Parameter Type</th> + <th>Data Type</th> + <th class="left">Sample Data</th> + <th class="left">Note</th> + </tr> + </thead> + </table> + </div> + <div class="tbl-list-body"> + <table> + <colgroup> + <col width="5%;"> + <col width="15%;"> + <col width="15%;"> + <col width="8%;"> + <col width="8%;"> + <col width="8%;"> + <col width="19%;"> + <col width="20%;"> + </colgroup> + <tbody> + <tr> + <td title="1">1</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request01">연계 시스템 ID</span> + </td> + <td class="left"> System-ID</td> + <td>Y</td> + <td>Header</td> + <td>String</td> + <td class="left">C60REST0001</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description01">발급받은 + 연계 ID</span></td> + </tr> + <tr> + <td title="2">2</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request02">수신계정</span></td> + <td class="left"> targetAddress</td> + <td>Y</td> + <td>Body</td> + <td>String Array</td> + <td class="left">["knoxportal@samsung.com"]</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description02">알림수신인 + 메일계정</span></td> + </tr> + <tr> + <td title="3">3</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request03">이벤트속성</span></td> + <td class="left"> ntype</td> + <td>Y</td> + <td>Body</td> + <td>String</td> + <td class="left">NEW</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description03">이벤트의 + 속성</span></td> + </tr> + <tr> + <td title="4">4</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request04">시스템이름</span></td> + <td class="left"> systemname</td> + <td>Y</td> + <td>Body</td> + <td>String</td> + <td class="left">Push service</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description04">외부 + 시스템 식별 Name</span></td> + </tr> + <tr> + <td title="5">5</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request05">알림표시명</span></td> + <td class="left"> from</td> + <td>Y</td> + <td>Body</td> + <td>String</td> + <td class="left">녹스포털 테스트</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description05">외부 + 시스템 Toast 표시명(Local)</span></td> + </tr> + <tr> + <td title="6">6</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request06">알림표시명(영)</span> + </td> + <td class="left"> fromGlobal</td> + <td>Y</td> + <td>Body</td> + <td>String</td> + <td class="left">Knox Portal Test</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description06">외부 + 시스템 Toast 표시명(Global)</span></td> + </tr> + <tr> + <td title="7">7</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request07">Visual속성</span> + </td> + <td class="left"> exVisualVO</td> + <td>Y</td> + <td>Body</td> + <td>JsonString</td> + <td class="left">N/A</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description07">알림 + Visual 속성</span></td> + </tr> + <tr> + <td title="8">8</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request08">토스트이름</span></td> + <td class="left"> template</td> + <td>N</td> + <td>Body</td> + <td>String</td> + <td class="left">default template</td> + <td class="left"><span + data-message-id="noti.guide.sendnotification.request.description08">Pre-Defined된 Toast + 이름</span></td> + </tr> + <tr> + <td title="9">9</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request09">로고이미지</span></td> + <td class="left"> skin</td> + <td>N</td> + <td>Body</td> + <td>String</td> + <td class="left">default skin</td> + <td class="left"><span + data-message-id="noti.guide.sendnotification.request.description09">Background 와 기본제공 + Logo 이미지</span></td> + </tr> + <tr> + <td title="10">10</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request10">영문사용여부</span> + </td> + <td class="left"> global</td> + <td>N</td> + <td>Body</td> + <td>String</td> + <td class="left">N</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description10">Text에 + 설정된 global 사용여부</span></td> + </tr> + <tr> + <td title="11">11</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request11">로고표시여부</span> + </td> + <td class="left"> logo</td> + <td>N</td> + <td>Body</td> + <td>String</td> + <td class="left">Y</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description11">logo + 표시여부</span></td> + </tr> + <tr> + <td title="12">12</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request12">로고이미지URL</span> + </td> + <td class="left"> logourl</td> + <td>N</td> + <td>Query</td> + <td>String</td> + <td class="left">http://www.samsung.net/logo.jpg</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description12">불러올 + logo 표시 이미지 url</span></td> + </tr> + <tr> + <td title="13">13</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request13">Text속성</span> + </td> + <td class="left"> exTextVO</td> + <td>Y</td> + <td>Query</td> + <td>JsonStringArray</td> + <td class="left">N/A</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description13">알림 + Text 속성</span></td> + </tr> + <tr> + <td title="14">14</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request14">표시문자열</span></td> + <td class="left"> content</td> + <td>Y</td> + <td>Body</td> + <td>String</td> + <td class="left">한글기준 10자이내, 30byte 이내</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description14">표시 + 문자열</span></td> + </tr> + <tr> + <td title="15">15</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request15">표시문자열(영)</span> + </td> + <td class="left"> contentglobal</td> + <td>N</td> + <td>Body</td> + <td>String</td> + <td class="left">Toast Title</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description15">표시 + 문자열 Global</span></td> + </tr> + <tr> + <td title="16">16</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request16">표시문자크기</span> + </td> + <td class="left"> size</td> + <td>N</td> + <td>Body</td> + <td>Int</td> + <td class="left">512</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description16">표시 + 문자열 문자 크기</span></td> + </tr> + <tr> + <td title="17">17</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request17">표시문자위치</span> + </td> + <td class="left"> pos</td> + <td>Y</td> + <td>Body</td> + <td>Int</td> + <td class="left">2</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description17">표시 + 문자열 위치</span></td> + </tr> + <tr> + <td title="18">18</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request18">표시문자스타일</span> + </td> + <td class="left"> style</td> + <td>N</td> + <td>Body</td> + <td>String</td> + <td class="left">BOLD</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description18">표시 + 문자열 문자 스타일</span></td> + </tr> + <tr> + <td title="19">19</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request19">Color속성</span> + </td> + <td class="left"> exColorVO</td> + <td>N</td> + <td>Body</td> + <td>JsonString</td> + <td class="left">N/A</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description19">표시 + 문자열 문자 색상</span></td> + </tr> + <tr> + <td title="20">20</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request20">표시문자Red</span> + </td> + <td class="left"> r</td> + <td>Y</td> + <td>Body</td> + <td>Int</td> + <td class="left">255</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description20">RGB + 값중 red 값</span></td> + </tr> + <tr> + <td title="21">21</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request21">표시문자Green</span> + </td> + <td class="left"> g</td> + <td>Y</td> + <td>Body</td> + <td>Int</td> + <td class="left">255</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description21">RGB + 값중 green 값</span></td> + </tr> + <tr> + <td title="22">22</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request22">표시문자Blue</span> + </td> + <td class="left"> b</td> + <td>Y</td> + <td>Body</td> + <td>Int</td> + <td class="left">0</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description22">RGB + 값중 blue 값</span></td> + </tr> + <tr> + <td title="23">23</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request23">Action속성</span> + </td> + <td class="left"> exActionsVO</td> + <td>Y</td> + <td>Body</td> + <td>JsonString</td> + <td class="left">N/A</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description23">알림 + Action 속성</span></td> + </tr> + <tr> + <td title="24">24</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request24">팝업여부</span></td> + <td class="left"> popup</td> + <td>N</td> + <td>Body</td> + <td>String</td> + <td class="left">Y</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description24">Toast + 클릭 시 links 값 중 rel 이 popup인 href 호출</span></td> + </tr> + <tr> + <td title="25">25</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request25">클릭허용여부</span> + </td> + <td class="left"> clickable</td> + <td>N</td> + <td>Body</td> + <td>String</td> + <td class="left">Y</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description25">Toast + 영역 클릭 허용 여부</span></td> + </tr> + <tr> + <td title="26">26</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request26">Link속성</span> + </td> + <td class="left"> exLinksVO</td> + <td>N</td> + <td>Body</td> + <td>JsonString</td> + <td class="left">N/A</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description26">알림 + Link 속성</span></td> + </tr> + <tr> + <td title="27">27</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request27">링크속성값</span></td> + <td class="left"> rel</td> + <td>N</td> + <td>Body</td> + <td>String</td> + <td class="left">popup</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description27">링크 식별 + 값</span></td> + </tr> + <tr> + <td title="28">28</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request28">링크URL</span></td> + <td class="left"> href</td> + <td>N</td> + <td>Body</td> + <td>String</td> + <td class="left">http://www.samsung.net</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description28">link + URL</span></td> + </tr> + <tr> + <td title="29">29</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request29">부가 옵션</span></td> + <td class="left"> hint</td> + <td>Y</td> + <td>Header</td> + <td>String</td> + <td class="left">multibrowser</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.request.description29"><span + class="ellipsis">multibrowser값 지정 시 녹스포털을 로그인한 브라우저의 Tab으로 href URL을 로딩 + </span><br><span class="ellipsis">* IE 는 Popup으로 표시됨</span></span></td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="module-font type02"> + <p>Response Parameter</p> + </div><span data-message-id="noti.guide.sendnotification.response.title">호출 성공여부 및 알림의 키 값(UID)을 리턴합니다.</span> + <div class="tbl-list01 kc-tbl text-full"> + <div class="tbl-list-head"> + <table> + <colgroup> + <col width="4%;"> + <col width="16%;"> + <col width="15%;"> + <col width="10%;"> + <col width="20%;"> + <col width="35%;"> + </colgroup> + <thead> + <tr> + <th>No.</th> + <th class="left">Properties</th> + <th class="left">Attribute</th> + <th>Data Type</th> + <th class="left">Sample Data</th> + <th class="left">Note</th> + </tr> + </thead> + </table> + </div> + <div class="tbl-list-body"> + <table> + <colgroup> + <col width="4%;"> + <col width="16%;"> + <col width="15%;"> + <col width="10%;"> + <col width="20%;"> + <col width="35%;"> + </colgroup> + <tbody> + <tr> + <td title="1">1</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.response01">API 호출 + 성공여부</span></td> + <td class="left"> Result</td> + <td>String</td> + <td class="left">Success</td> + <td class="left"><span + data-message-id="noti.guide.sendnotification.response.description01">실시간알림 연계 + 성공여부</span></td> + </tr> + <tr> + <td title="2">2</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.response02">에러코드</span></td> + <td class="left"> ErrorCode</td> + <td>String</td> + <td class="left">null</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.response.description02">에러발생 + 시 코드 값</span></td> + </tr> + <tr> + <td title="3">3</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.response03">응답메시지 및 알림 + ID</span></td> + <td class="left"> Message and ID</td> + <td>String</td> + <td class="left">Alarm Created, uid : 3cd8085ff2c4420bb4cf1828d6369ea4</td> + <td class="left"><span data-message-id="noti.guide.sendnotification.response.description03">응답 + 메시지 및 알림 ID</span></td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="module-font type02"> + <p>Sample</p> + </div> + <div class="tbl-list01 kc-tbl"> + <div class="tbl-list-head"> + <table> + <colgroup> + <col width="50%;"> + <col width="50%;"> + </colgroup> + <thead> + <tr> + <th>Request</th> + <th>Response</th> + </tr> + </thead> + </table> + </div> + <div class="tbl-list-body"> + <table> + <colgroup> + <col width="50%;"> + <col width="50%;"> + </colgroup> + <tbody> + <tr> + <td> + <pre><span data-message-id="noti.guide.sendnotification.response.sample10"><span class="ellipsis">{</span><br><span class="ellipsis"> "targetAddress" : ["knoxportal@samsung.com"],</span><br><span class="ellipsis"> "ntype": "NEW", </span><br><span class="ellipsis"> "messageid": "EXT201804030305581008775022",</span><br><span class="ellipsis"> "systemname" : "push service", </span><br><span class="ellipsis"> "from" :"외부 알림 테스트", </span><br><span class="ellipsis"> "fromGlobal" : "External Notification Test ",</span><br><span class="ellipsis"> "exVisualVO": {</span><br><span class="ellipsis"> "template": "content",</span><br><span class="ellipsis"> "skin": "White",</span><br><span class="ellipsis"> "global": "N", </span><br><span class="ellipsis"> "logo": "Y",</span><br><span class="ellipsis"> "logourl": "",</span><br><span class="ellipsis"> "exTextVOList": [</span><br><span class="ellipsis"> {</span><br><span class="ellipsis"> "content": "제목", </span><br><span class="ellipsis"> "contentglobal": "Title", </span><br><span class="ellipsis"> "size": 14,</span><br><span class="ellipsis"> "pos": 1, </span><br><span class="ellipsis"> "exColorVO": { </span><br><span class="ellipsis"> "r": 0, </span><br><span class="ellipsis"> "g": 0,</span><br><span class="ellipsis"> "b": 0</span><br><span class="ellipsis"> },</span><br><span class="ellipsis"> "style": "BOLD"</span><br><span class="ellipsis"> }</span><br><span class="ellipsis"> ]</span><br><span class="ellipsis"> },</span><br><span class="ellipsis"> "exActionsVO": { </span><br><span class="ellipsis"> "popup": "Y", </span><br><span class="ellipsis"> "snooze": "N", </span><br><span class="ellipsis"> "clickable": "Y", </span><br><span class="ellipsis"> "hint": "multibrowser", </span><br><span class="ellipsis"> "exLinksVOList":</span><br><span class="ellipsis"> [</span><br><span class="ellipsis"> {</span><br><span class="ellipsis"> "rel": "popup", </span><br><span class="ellipsis"> "href": "http://naver.com", </span><br><span class="ellipsis"> "args" : ""</span><br><span class="ellipsis"> }</span><br><span class="ellipsis"> ]</span><br><span class="ellipsis"> }</span><br><span class="ellipsis">}</span></span> + </pre> + </td> + <td> + <pre><span data-message-id="noti.guide.sendnotification.response.sample11"><span class="ellipsis">{</span><br><span class="ellipsis"> "result": "OK",</span><br><span class="ellipsis"> "errorCode": null, </span><br><span class="ellipsis"> "message": "Alarm Created, uid : 3cd8085ff2c4420bb4cf1828d6369ea4"</span><br><span class="ellipsis">}</span></span> + </pre> + </td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="module-font type02"> + <p>Error Code</p> + </div> + <div class="tbl-list01 kc-tbl"> + <div class="tbl-list-head"> + <table> + <colgroup> + <col width="10%;"> + <col width="10%;"> + <col width="40%;"> + <col width="40%;"> + </colgroup> + <thead> + <tr> + <th><span data-message-id="common.type.message1">HTTP응답코드</span></th> + <th><span data-message-id="common.type.message2">에러코드</span></th> + <th><span data-message-id="common.type.message3">에러메시지</span></th> + <th><span data-message-id="common.type.message4">조치방안</span></th> + </tr> + </thead> + </table> + </div> + <div class="tbl-list-body"> + <table> + <colgroup> + <col width="10%;"> + <col width="10%;"> + <col width="40%;"> + <col width="40%;"> + </colgroup> + <tbody> + <tr> + <td>400</td> + <td>EX001</td> + <td class="left desc">Notification information is null.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage01">알림 인풋 + 전체가 NULL일 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX002</td> + <td class="left desc">[ntype] value is NEW or RECALL.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage02">ntype + 값이 NEW이거나 RECALL이지 않은 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX003</td> + <td class="left desc">[from] is mendentory.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage03">from값이 + 입력되지 않은 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX004</td> + <td class="left desc">[fromGlobal] is mendentory.</td> + <td class="left desc"><span + data-message-id="noti.guide.sendnotification.errormessage04">fromGlobal값이 입력되지 않은 경우 + 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX006</td> + <td class="left desc">[systemname] is mendentory.</td> + <td class="left desc"><span + data-message-id="noti.guide.sendnotification.errormessage05">systemname값이 입력되지 않은 경우 + 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX007</td> + <td class="left desc">[exVisualVO] is mendentory.</td> + <td class="left desc"><span + data-message-id="noti.guide.sendnotification.errormessage06">exVisualVO값이 입력되지 않은 경우 + 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX008</td> + <td class="left desc">[exActionsVO] is mendentory.</td> + <td class="left desc"><span + data-message-id="noti.guide.sendnotification.errormessage07">exActionsVO값이 입력되지 않은 경우 + 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX009</td> + <td class="left desc">The length of [template] is max 10 characters.</td> + <td class="left desc"><span + data-message-id="noti.guide.sendnotification.errormessage08">template 값이 10자 이상 입력될 경우 + 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX010</td> + <td class="left desc">The length of [skin] is max 10 characters.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage09">skin 값이 + 10자 이상 입력될 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX011</td> + <td class="left desc">The value of [global] value is not Y or N.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage10">global + 값이 Y혹은 N이 입력되지 않는 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX012</td> + <td class="left desc">The value of [logo] value is not Y or N.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage11">logo 값이 + Y 혹은 N이 입력되지 않는 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX013</td> + <td class="left desc">The value of [logourl] must start with url pattern(http://).</td> + <td class="left desc"><span + data-message-id="noti.guide.sendnotification.errormessage12">Logourl값이 정상적인 URL이 아닌 경우 + 발생(http://로 시작필요)</span></td> + </tr> + <tr> + <td>400</td> + <td>EX014</td> + <td class="left desc">[exTextVO] is mendentory.</td> + <td class="left desc"><span + data-message-id="noti.guide.sendnotification.errormessage13">exTextVO 값이 입력되지 않은 경우 + 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX015</td> + <td class="left desc">[content] is mendentory.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage14">content + 값이 입력되지 않은 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX016</td> + <td class="left desc">[R,G,B] value range is 0 to 255.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage15">R,G,B + 값이 0~255범위에서 벗어나는 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX017</td> + <td class="left desc">For the requested search conditions, paging is not possible.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage16">href 값이 + 정상적인 URL이 아닌 경우 발생(http://로 시작필요)</span></td> + </tr> + <tr> + <td>400</td> + <td>EX018</td> + <td class="left desc">The value of [template] encoding is supported UTF-8.</td> + <td class="left desc"><span + data-message-id="noti.guide.sendnotification.errormessage17">Template 값이 UTF-8로 인코딩 되지 + 않은 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX019</td> + <td class="left desc">The value of [skin] encoding is supported UTF-8.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage18">Skin 값이 + UTF-8로 인코딩 되지 않은 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX020</td> + <td class="left desc">The value of [rel] is max 10 characters.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage19">Rel 값이 + 10자 이상 입력될 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX021</td> + <td class="left desc">The value of [rel] encoding is supported UTF-8.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage20">rel 값이 + UTF-8로 인코딩 되지 않은 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX022</td> + <td class="left desc">[targetAddress] is invalid. Check if an on-leave or retired person.</td> + <td class="left desc"><span + data-message-id="noti.guide.sendnotification.errormessage21">targetAddress 값의 임직원 정보가 없는 + 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX023</td> + <td class="left desc">[size] value range is 0 to 1024.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage22">size 값이 + 0~1024범위에서 벗어나는 경우 발생</span></td> + </tr> + <tr> + <td>400</td> + <td>EX024</td> + <td class="left desc">[pos] value range is 1 to 3.</td> + <td class="left desc"><span data-message-id="noti.guide.sendnotification.errormessage23">pos 값이 + 1~3위에서 벗어나는 경우 발생</span></td> + </tr> + </tbody> + </table> + </div> + </div><br><br> +</div>
\ No newline at end of file diff --git a/lib/knox-api/realtime-notification/realtime-notification.ts b/lib/knox-api/realtime-notification/realtime-notification.ts new file mode 100644 index 00000000..a26f5b55 --- /dev/null +++ b/lib/knox-api/realtime-notification/realtime-notification.ts @@ -0,0 +1,333 @@ +"use server" + +import { z } from "zod" + +// 타입 정의 +const ColorSchema = z.object({ + r: z.number().min(0).max(255), + g: z.number().min(0).max(255), + b: z.number().min(0).max(255), +}) + +const TextSchema = z.object({ + content: z.string().min(1), + contentglobal: z.string().optional(), + size: z.number().min(0).max(1024).optional(), + pos: z.number().min(1).max(3), + exColorVO: ColorSchema.optional(), + style: z.string().optional(), +}) + +const LinkSchema = z.object({ + rel: z.string().max(10).optional(), + href: z.string().url().optional(), + args: z.string().optional(), +}) + +const VisualSchema = z.object({ + template: z.string().max(10).optional(), + skin: z.string().max(10).optional(), + global: z.enum(["Y", "N"]).optional(), + logo: z.enum(["Y", "N"]).optional(), + logourl: z.string().url().optional(), + exTextVOList: z.array(TextSchema), +}) + +const ActionsSchema = z.object({ + popup: z.enum(["Y", "N"]).optional(), + snooze: z.enum(["Y", "N"]).optional(), + clickable: z.enum(["Y", "N"]).optional(), + hint: z.string().optional(), + exLinksVOList: z.array(LinkSchema).optional(), +}) + +const NotificationRequestSchema = z.object({ + targetAddress: z.array(z.string().email()).max(100), + ntype: z.enum(["NEW", "RECALL"]), + messageid: z.string().optional(), + systemname: z.string().min(1), + from: z.string().min(1), + fromGlobal: z.string().min(1), + exVisualVO: VisualSchema, + exActionsVO: ActionsSchema, +}) + +export type NotificationRequest = z.infer<typeof NotificationRequestSchema> +export type NotificationColor = z.infer<typeof ColorSchema> +export type NotificationText = z.infer<typeof TextSchema> +export type NotificationLink = z.infer<typeof LinkSchema> +export type NotificationVisual = z.infer<typeof VisualSchema> +export type NotificationActions = z.infer<typeof ActionsSchema> + +// 응답 타입 +export interface NotificationResponse { + result: string + errorCode: string | null + message: string +} + +// 에러 타입 +export interface NotificationError { + httpStatus: number + errorCode: string + message: string +} + +// 환경 변수 검증 +const getApiConfig = () => { + const baseUrl = process.env.KNOX_API_BASE_URL + const systemId = process.env.KNOX_SYSTEM_ID + + if (!baseUrl || !systemId) { + throw new Error("Knox API configuration missing: KNOX_API_BASE_URL and KNOX_SYSTEM_ID are required") + } + + return { baseUrl, systemId } +} + +/** + * Knox Suite 실시간 토스트 알림 전송 + */ +export async function sendNotification( + request: NotificationRequest +): Promise<NotificationResponse> { + try { + // 요청 데이터 검증 + const validatedRequest = NotificationRequestSchema.parse(request) + + const { baseUrl, systemId } = getApiConfig() + + const response = await fetch(`${baseUrl}/notification/api/v2.0/sendnotification`, { + method: "POST", + headers: { + "Content-Type": "application/json", + "System-ID": systemId, + "hint": validatedRequest.exActionsVO.hint || "multibrowser", + }, + body: JSON.stringify(validatedRequest), + }) + + if (!response.ok) { + const errorData = await response.json() + throw new Error(`API Error: ${errorData.message || response.statusText}`) + } + + const result: NotificationResponse = await response.json() + return result + + } catch (error) { + console.error("Knox notification error:", error) + throw error + } +} + +/** + * 간단한 토스트 알림 전송 (기본 설정 사용) + */ +export async function sendSimpleNotification( + targetEmails: string[], + title: string, + titleGlobal: string, + systemName: string, + link?: string +): Promise<NotificationResponse> { + const notification: NotificationRequest = { + targetAddress: targetEmails, + ntype: "NEW", + systemname: systemName, + from: title, + fromGlobal: titleGlobal, + exVisualVO: { + template: "content", + skin: "White", + global: "N", + logo: "Y", + logourl: "", + exTextVOList: [ + { + content: title, + contentglobal: titleGlobal, + size: 14, + pos: 1, + exColorVO: { + r: 0, + g: 0, + b: 0, + }, + style: "BOLD", + }, + ], + }, + exActionsVO: { + popup: "Y", + clickable: "Y", + hint: "multibrowser", + exLinksVOList: link ? [ + { + rel: "popup", + href: link, + args: "", + }, + ] : [], + }, + } + + return await sendNotification(notification) +} + +/** + * 알림 취소 (RECALL) + */ +export async function recallNotification( + targetEmails: string[], + systemName: string, + messageId: string +): Promise<NotificationResponse> { + const notification: NotificationRequest = { + targetAddress: targetEmails, + ntype: "RECALL", + messageid: messageId, + systemname: systemName, + from: "알림 취소", + fromGlobal: "Notification Recall", + exVisualVO: { + template: "content", + skin: "White", + global: "N", + logo: "Y", + logourl: "", + exTextVOList: [ + { + content: "알림이 취소되었습니다", + contentglobal: "Notification has been recalled", + size: 14, + pos: 1, + exColorVO: { + r: 255, + g: 0, + b: 0, + }, + style: "BOLD", + }, + ], + }, + exActionsVO: { + popup: "N", + clickable: "N", + hint: "multibrowser", + }, + } + + return await sendNotification(notification) +} + +/** + * 사용자 정의 스타일 토스트 알림 + */ +export async function sendCustomNotification( + targetEmails: string[], + systemName: string, + title: string, + titleGlobal: string, + options: { + template?: string + skin?: string + logoUrl?: string + textColor?: NotificationColor + textSize?: number + textStyle?: string + link?: string + linkRel?: string + } = {} +): Promise<NotificationResponse> { + const notification: NotificationRequest = { + targetAddress: targetEmails, + ntype: "NEW", + systemname: systemName, + from: title, + fromGlobal: titleGlobal, + exVisualVO: { + template: options.template || "content", + skin: options.skin || "White", + global: "N", + logo: options.logoUrl ? "Y" : "Y", + logourl: options.logoUrl || "", + exTextVOList: [ + { + content: title, + contentglobal: titleGlobal, + size: options.textSize || 14, + pos: 1, + exColorVO: options.textColor || { + r: 0, + g: 0, + b: 0, + }, + style: options.textStyle || "BOLD", + }, + ], + }, + exActionsVO: { + popup: options.link ? "Y" : "N", + clickable: options.link ? "Y" : "N", + hint: "multibrowser", + exLinksVOList: options.link ? [ + { + rel: options.linkRel || "popup", + href: options.link, + args: "", + }, + ] : [], + }, + } + + return await sendNotification(notification) +} + +/** + * 헬퍼 함수: 알림 ID 추출 + */ +export async function extractNotificationId(response: NotificationResponse): Promise<string | null> { + if (response.result === "OK" && response.message) { + const match = response.message.match(/uid\s*:\s*([a-f0-9]+)/i) + return match ? match[1] : null + } + return null +} + +/** + * 헬퍼 함수: 여러 사용자에게 배치 알림 전송 + */ +export async function sendBatchNotifications( + notifications: Array<{ + targetEmails: string[] + title: string + titleGlobal: string + systemName: string + link?: string + }> +): Promise<NotificationResponse[]> { + const results: NotificationResponse[] = [] + + for (const notification of notifications) { + try { + const result = await sendSimpleNotification( + notification.targetEmails, + notification.title, + notification.titleGlobal, + notification.systemName, + notification.link + ) + results.push(result) + } catch (error) { + console.error("Batch notification error:", error) + results.push({ + result: "ERROR", + errorCode: "BATCH_ERROR", + message: error instanceof Error ? error.message : "Unknown error", + }) + } + } + + return results +} |
