> For the complete documentation index, see [llms.txt](https://malgn.gitbook.io/cloud/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://malgn.gitbook.io/cloud/api/add-course-board-post.md).

# 과정게시판 게시물 등록

> **문서 정보**
>
> * **버전:** 1.0
> * **작성일:** 2026.06.05

### 1. 개요

* 맑은소프트 범용클라우드 LMS의 과정게시판에 게시물을 등록하는 API입니다.

#### 유의사항

* 회원 유형에 따라 등록이 제한됩니다.
* 최고관리자, 운영자는 모든 과정게시판에 게시물을 등록할 수 있습니다.
* 과정운영자는 '과정운영자'로 등록된 과정의 과정게시판에만 게시물을 등록할 수 있습니다.
* 소속운영자, 회원은 등록할 수 없습니다.<br>

### 2. Endpoint

<table><thead><tr><th width="156">구분</th><th width="374">내용</th></tr></thead><tbody><tr><td><strong>URL</strong></td><td><code>[domain]/api/classroom_post_insert.jsp</code></td></tr><tr><td><strong>메소드</strong></td><td>POST</td></tr><tr><td><strong>Content-Type</strong></td><td>application/x-www-form-urlencoded</td></tr><tr><td><strong>출력데이터</strong></td><td>application/json</td></tr><tr><td><strong>인코딩</strong></td><td>UTF-8</td></tr></tbody></table>

### 3. Parameter

<table><thead><tr><th width="188">파라미터</th><th width="90">필수</th><th width="100">포맷</th><th>정의</th></tr></thead><tbody><tr><td>ek</td><td>Y</td><td>string</td><td>회원 인증값</td></tr><tr><td>course_id</td><td>Y</td><td>integer</td><td>게시물을 등록할 과정아이디</td></tr><tr><td>board_cd</td><td>Y</td><td>string</td><td>게시판 코드 <em>[<code>notice</code>만 허용]</em></td></tr><tr><td>subject</td><td>Y</td><td>string</td><td>게시물의 제목 (최대 255자)</td></tr><tr><td>content</td><td>Y</td><td>string</td><td>게시물의 내용 (최대 60,000바이트)</td></tr><tr><td>html_yn</td><td>N</td><td>string</td><td>내용의 HTML 여부 (기본값 N)</td></tr><tr><td>• Y: HTML 원문 저장</td><td></td><td></td><td></td></tr><tr><td>• N: 평문</td><td></td><td></td><td></td></tr></tbody></table>

### 4. Request

#### 코드 예제

```bash
curl -X POST "<https://[domain]/api/classroom_post_insert.jsp>" \\
  -H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" \\
  --data-urlencode "ek=Base64AES암호화값" \\
  --data-urlencode "course_id=50" \\
  --data-urlencode "board_cd=notice" \\
  --data-urlencode "subject=공지사항 제목입니다" \\
  --data-urlencode "content=공지 내용입니다." \\
  --data-urlencode "html_yn=N"
```

#### 인증

* 회원 단위 암호화 인증값(`ek`)을 사용합니다.
* `ek`는 당일에만 유효합니다. 서버와 호출 측의 날짜(타임존)가 일치해야 합니다. (서버 기준 시각: KST)

<table><thead><tr><th width="152">값</th><th width="324">정의</th></tr></thead><tbody><tr><td><strong>api_key</strong></td><td>사전에 관리자가 회원에게 발급한 인증키</td></tr><tr><td><strong>api_aeskey</strong></td><td>AES 암호화 키(16byte) <em>[별도 안내]</em></td></tr></tbody></table>

#### ek 생성 규칙

* 원문은 \[`api_key` + 요청 시각(`yyyyMMddHHmmss`)]으로 구성합니다.
* 구성한 원문을 `api_aeskey`로 AES-128 암호화 후 Base64로 인코딩하여 `ek`값을 생성합니다.

#### ek 생성 코드 예제

* Java

  ```java
  import javax.crypto.Cipher;
  import javax.crypto.spec.SecretKeySpec;
  import java.util.Base64;
  import java.text.SimpleDateFormat;
  import java.util.Date;

  public static String makeEk(String apiKey, String aesKey) throws Exception {
      String now = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
      String plain = apiKey + now;
      SecretKeySpec spec = new SecretKeySpec(aesKey.getBytes("UTF-8"), "AES");
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
      cipher.init(Cipher.ENCRYPT_MODE, spec);
      return Base64.getEncoder().encodeToString(cipher.doFinal(plain.getBytes("UTF-8")));
  }
  ```
* PHP

  ```php
  function makeEk(string $apiKey, string $aesKey): string {
      $plain = $apiKey . date('YmdHis');
      $enc = openssl_encrypt($plain, 'AES-128-ECB', $aesKey, OPENSSL_RAW_DATA);
      return base64_encode($enc);
  }
  ```
* Python (pip install pycryptodome)

  ```python
  import base64
  from datetime import datetime
  from Crypto.Cipher import AES
  from Crypto.Util.Padding import pad

  def make_ek(api_key: str, aes_key: str) -> str:
      plain = api_key + datetime.now().strftime('%Y%m%d%H%M%S')
      cipher = AES.new(aes_key.encode('utf-8'), AES.MODE_ECB)
      enc = cipher.encrypt(pad(plain.encode('utf-8'), AES.block_size))
      return base64.b64encode(enc).decode('utf-8')
  ```
* Node.js

  ```jsx
  const crypto = require('crypto');

  function makeEk(apiKey, aesKey) {
      const now = new Date();
      const ts = now.getFullYear().toString()
          + String(now.getMonth() + 1).padStart(2, '0')
          + String(now.getDate()).padStart(2, '0')
          + String(now.getHours()).padStart(2, '0')
          + String(now.getMinutes()).padStart(2, '0')
          + String(now.getSeconds()).padStart(2, '0');
      const cipher = crypto.createCipheriv('aes-128-ecb', Buffer.from(aesKey, 'utf8'), null);
      return Buffer.concat([cipher.update(apiKey + ts, 'utf8'), cipher.final()]).toString('base64');
  }
  ```

### 5. Response

* 제공 값

  <table><thead><tr><th width="144">값</th><th width="145">포맷</th><th width="191">정의</th></tr></thead><tbody><tr><td>ret_code</td><td>string</td><td>호출 결과 코드</td></tr><tr><td>ret_msg</td><td>string</td><td>호출 결과 메시지</td></tr><tr><td>ret_size</td><td>integer</td><td>응답 데이터의 개수</td></tr><tr><td>list</td><td>array</td><td>응답 데이터</td></tr></tbody></table>

  ```
  • post_id: 생성된 게시물 ID |
  ```

#### 성공

* 다음 포맷으로 응답합니다.
* 모든 값들은 AES-128로 암호화 후 Base64로 인코딩되어 제공됩니다.

  ```json
  {
    "ret_code": "000",
    "ret_msg": "success",
    "ret_size": 1, //성공 시 1
    "list": [
      { "post_id": 12345 }
    ]
  }
  ```
* AES 암호화 방식

  | Mode     | ECB             |
  | -------- | --------------- |
  | Encoding | Base64          |
  | Padding  | PKCS5Padding    |
  | IV       | 사용 안 함 (ECB 모드) |
  | Charset  | UTF-8           |
  | Key      | *\[별도 제공]*      |

#### 실패

* 다음 포맷으로 응답합니다.

  ```json
  {
    "ret_code": "330",
    "ret_msg": "not valid auth"
  }
  ```

### 6. Return Code

<table><thead><tr><th width="112">코드</th><th width="255">정의</th></tr></thead><tbody><tr><td>000</td><td>성공</td></tr><tr><td>210</td><td>DB 등록 실패</td></tr><tr><td>310</td><td>필수 파라미터 누락</td></tr><tr><td>320</td><td>잘못된 요청 값</td></tr><tr><td>330</td><td>유효하지 않은 인증값(ek)</td></tr><tr><td>340</td><td>회원 정보 없음</td></tr><tr><td>350</td><td>등록 권한 없음</td></tr><tr><td>360</td><td>게시판 정보 없음</td></tr><tr><td>410</td><td>게시물 등록 실패 (DB 오류)</td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://malgn.gitbook.io/cloud/api/add-course-board-post.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
