--- title: "CLOVA Chatbot API 예제" slug: "ai-application-service-chatbot-chatbotexample" tags: ["CLOVA Chatbot"] updated: 2026-09-17T09:15:53Z published: 2026-09-17T09:15:53Z canonical: "api.ncloud-docs.com/ai-application-service-chatbot-chatbotexample" --- > ## Documentation Index > Fetch the complete documentation index at: https://api.ncloud-docs.com/llms.txt > Use this file to discover all available pages before exploring further. # CLOVA Chatbot API 예제 Classic/VPC 환경에서 이용 가능합니다. CLOVA Chatbot 예제를 소개합니다. ## CLOVA Chatbot 사용자의 질문을 입력 받고, 그에 맞는 답변을 다양한 방식으로 반환하는 CLOVA Chatbot API 예제를 설명합니다. ### Java Java 기반의 API 예제 코드는 다음과 같습니다. - CLOVA Chatbot Custom API 호출 ``` package com.ncp.ai.demo.process; import android.media.MediaPlayer; import android.os.Environment; import android.util.Base64; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.security.Timestamp; import java.util.Date; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import android.util.Base64; import org.json.JSONArray; import org.json.JSONObject; public class ChatbotProc { public static String main(String voiceMessage, String apiURL, String secretKey) { String chatbotMessage = ""; try { //String apiURL = "https://ex9av8bv0e.apigw.ntruss.com/custom_chatbot/prod/"; URL url = new URL(apiURL); String message = getReqMessage(voiceMessage); System.out.println("##" + message); String encodeBase64String = makeSignature(message, secretKey); HttpURLConnection con = (HttpURLConnection)url.openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("Content-Type", "application/json;UTF-8"); con.setRequestProperty("X-NCP-CHATBOT_SIGNATURE", encodeBase64String); // post request con.setDoOutput(true); DataOutputStream wr = new DataOutputStream(con.getOutputStream()); wr.write(message.getBytes("UTF-8")); wr.flush(); wr.close(); int responseCode = con.getResponseCode(); BufferedReader br; if(responseCode==200) { // Normal call System.out.println(con.getResponseMessage()); BufferedReader in = new BufferedReader( new InputStreamReader( con.getInputStream())); String decodedString; while ((decodedString = in.readLine()) != null) { chatbotMessage = decodedString; } //chatbotMessage = decodedString; in.close(); } else { // Error occurred chatbotMessage = con.getResponseMessage(); } } catch (Exception e) { System.out.println(e); } return chatbotMessage; } public static String makeSignature(String message, String secretKey) { String encodeBase64String = ""; try { byte[] secrete_key_bytes = secretKey.getBytes("UTF-8"); SecretKeySpec signingKey = new SecretKeySpec(secrete_key_bytes, "HmacSHA256"); Mac mac = Mac.getInstance("HmacSHA256"); mac.init(signingKey); byte[] rawHmac = mac.doFinal(message.getBytes("UTF-8")); encodeBase64String = Base64.encodeToString(rawHmac, Base64.NO_WRAP); return encodeBase64String; } catch (Exception e){ System.out.println(e); } return encodeBase64String; } public static String getReqMessage(String voiceMessage) { String requestBody = ""; try { JSONObject obj = new JSONObject(); long timestamp = new Date().getTime(); System.out.println("##"+timestamp); obj.put("version", "v2"); obj.put("userId", "U47b00b58c90f8e47428af8b7bddc1231heo2"); //=> userId is a unique code for each chat user, not a fixed value, recommend use UUID. use different id for each user could help you to split chat history for users. obj.put("timestamp", timestamp); JSONObject bubbles_obj = new JSONObject(); bubbles_obj.put("type", "text"); JSONObject data_obj = new JSONObject(); data_obj.put("description", voiceMessage); bubbles_obj.put("type", "text"); bubbles_obj.put("data", data_obj); JSONArray bubbles_array = new JSONArray(); bubbles_array.put(bubbles_obj); obj.put("bubbles", bubbles_array); obj.put("event", "send"); requestBody = obj.toString(); } catch (Exception e){ System.out.println("## Exception : " + e); } return requestBody; } } ``` - UI 단계에서 `ChatbotProc.java` 호출 ``` package com.example.user.ncpaidemo; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.speech.tts.Voice; import android.util.Log; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.naver.speech.clientapi.SpeechRecognitionResult; import com.ncp.ai.demo.process.ChatbotProc; import com.ncp.ai.demo.process.CsrProc; import com.ncp.ai.demo.process.CssProc; import com.ncp.ai.utils.AudioWriterPCM; import org.json.JSONArray; import org.json.JSONObject; import java.lang.ref.WeakReference; import java.util.List; public class VoiceChatbotActivity extends BaseActivity { private static final String TAG = VoiceChatbotActivity.class.getSimpleName(); private RecognitionHandler handler; private CsrProc naverRecognizer; private TextView txtResult; private Button btnStart; private String mResult; private AudioWriterPCM writer; private String clientId; private String clientSecret; // Handle speech recognition Messages. private void handleMessage(Message msg) { switch (msg.what) { case R.id.clientReady: // Voice recognition ready txtResult.setText("Connected"); writer = new AudioWriterPCM(Environment.getExternalStorageDirectory().getAbsolutePath() + "/NaverSpeechTest"); writer.open("Test"); break; case R.id.audioRecording: writer.write((short[]) msg.obj); break; case R.id.partialResult: mResult = (String) (msg.obj); mResult += mResult; txtResult.setText(mResult); break; case R.id.finalResult: // Final recognition result SpeechRecognitionResult speechRecognitionResult1 = (SpeechRecognitionResult) msg.obj; List results1 = speechRecognitionResult1.getResults(); StringBuilder strBuf1 = new StringBuilder(); for(String result : results1) { strBuf1.append(result); //strBuf.append("\n"); break; } mResult = strBuf1.toString(); txtResult.setText(mResult); requestChatbot(); break; case R.id.recognitionError: if (writer != null) { writer.close(); } mResult = "Error code : " + msg.obj.toString(); txtResult.setText(mResult); btnStart.setText(R.string.str_start); btnStart.setEnabled(true); break; case R.id.clientInactive: if (writer != null) { writer.close(); } btnStart.setText(R.string.str_start); btnStart.setEnabled(true); break; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_voice_chatbot); SharedPreferences sharedPref = getSharedPreferences("PREF", Context.MODE_PRIVATE); clientId = sharedPref.getString("application_client_id", ""); clientSecret = sharedPref.getString("application_client_secret", ""); txtResult = (TextView) findViewById(R.id.textViewVoiceChatbotResult); btnStart = (Button) findViewById(R.id.btn_voice_chatbot1); handler = new RecognitionHandler(this); //naverRecognizer = new CsrProc(this, handler, clientId); naverRecognizer = CsrProc.getCsrProc(this, clientId); naverRecognizer.setHandler(handler); btnStart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!naverRecognizer.getSpeechRecognizer().isRunning()) { mResult = ""; txtResult.setText("Connecting..."); btnStart.setText(R.string.str_stop); naverRecognizer.recognize(); } else { Log.d(TAG, "stop and wait Final Result"); btnStart.setEnabled(false); naverRecognizer.getSpeechRecognizer().stop(); } } }); Button voiceChatbotReplay; voiceChatbotReplay = (Button) findViewById(R.id.btn_voice_chatbot_replay); voiceChatbotReplay.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { TextView txtResult = (TextView) findViewById(R.id.text_voice_chatbot_replay); CSSExecute(txtResult.getText().toString()); } }); } private void requestChatbot() { SharedPreferences sharedPref = getSharedPreferences("PREF", Context.MODE_PRIVATE); String chatbotApiGwUrl = sharedPref.getString("chatbot_api_gw_url", ""); String chatbotSecretKey = sharedPref.getString("chatbot_secret_key", ""); TextView csrSourceText = (TextView)findViewById(R.id.textViewVoiceChatbotResult); String text = csrSourceText.getText().toString(); VoiceChatbotActivity.VoiceChatbotTask task = new VoiceChatbotActivity.VoiceChatbotTask(); task.execute(text, chatbotApiGwUrl, chatbotSecretKey); } @Override protected void onStart() { super.onStart(); // Voice recognition server initialization is here naverRecognizer.getSpeechRecognizer().initialize(); } @Override protected void onResume() { super.onResume(); mResult = ""; txtResult.setText(""); btnStart.setText(R.string.str_start); btnStart.setEnabled(true); } // @Override // protected void onStop() { // System.out.println("voice chatbot End!!!"); // super.onStop(); // terminate voice recognition server // naverRecognizer.getSpeechRecognizer().release(); // } // Declare handler for handling SpeechRecognizer thread's Messages. static class RecognitionHandler extends Handler { private final WeakReference mActivity; RecognitionHandler(VoiceChatbotActivity activity) { mActivity = new WeakReference(activity); } @Override public void handleMessage(Message msg) { VoiceChatbotActivity activity = mActivity.get(); if (activity != null) { activity.handleMessage(msg); } } } public class VoiceChatbotTask extends AsyncTask { @Override public String doInBackground(String... strings) { return ChatbotProc.main(strings[0], strings[1], strings[2]); } @Override protected void onPostExecute(String result) { ReturnThreadResult(result); } } public String ReturnThreadResult(String result) { //{"version":"v2","userId":"U47b00b58c90f8e47428af8b7bddc1231heo2","sessionId":"617666","timestamp":1546593912020, // "bubbles":[{"type":"template","data":{"cover":{"type":"text","data":{"description":"b"}},"contentTable":[[{"rowSpan":1,"colSpan":1,"data":{"type":"button","title":"b","data":{"type":"basic","action":{"type":"link","data":{"url":"https://www.ncloud.com/product"}}}}}],[{"rowSpan":1,"colSpan":1,"data":{"type":"button","title": "b","data":{"type":"basic","action":{"type":"link","data":{"url":"https://www.ncloud.com/product"}}}}}]]}}],"event":"send"} //{"version":"v2","userId":"U47b00b58c90f8e47428af8b7bddc1231heo2","sessionId":"641799","timestamp":1546777198124, // "bubbles":[{"type":"text","data":{"description":"b"}}],"event":"send"} String chatbotMessage = ""; String rlt = result; try{ JSONObject jsonObject = new JSONObject(rlt); JSONArray bubbles = jsonObject.getJSONArray("bubbles"); for (int i =0; i < bubbles.length(); i++){ JSONObject bubble = bubbles.getJSONObject(i); String chatType = bubble.getString("type"); if (chatType.equals("text")){ chatbotMessage = bubble.getJSONObject("data").getString("description"); }else if (chatType.equals("template")) { chatbotMessage = bubble.getJSONObject("data").getJSONObject("cover").getJSONObject("data").getString("description"); }else { chatbotMessage = ""; } TextView txtResult = (TextView) findViewById(R.id.text_voice_chatbot_replay); txtResult.setText(chatbotMessage); break; } } catch (Exception e) { System.out.println(e); } CSSExecute(chatbotMessage); return chatbotMessage; } private void CSSExecute(String message) { VoiceChatbotActivity.NaverTTSTask tts = new VoiceChatbotActivity.NaverTTSTask(); tts.execute(message, "mijin", clientId, clientSecret); } public class NaverTTSTask extends AsyncTask { @Override public String doInBackground(String... strings) { System.out.println(strings[1]); CssProc.main(strings[0], strings[1], strings[2], strings[3]); return null; } } } ``` ### Python Python 기반의 API 예제 코드는 다음과 같습니다. ``` import hashlib import hmac import base64 import time import requests import json class ChatbotMessageSender: # chatbot api gateway url ep_path = '' # chatbot custom secret key secret_key = '' def req_message_send(self): timestamp = self.get_timestamp() request_body = { 'version': 'v2', 'userId': 'U47b00b58c90f8e47428af8b7bddcda3d1111111', 'timestamp': timestamp, 'bubbles': [ { 'type': 'text', 'data': { 'description': 'About Me' } } ], 'event': 'send' } ## Request body encode_request_body = json.dumps(request_body).encode('UTF-8') ## make signature signature = self.make_signature(self.secret_key, encode_request_body) ## headers custom_headers = { 'Content-Type': 'application/json;UTF-8', 'X-NCP-CHATBOT_SIGNATURE': signature } print("## Timestamp : ", timestamp) print("## Signature : ", signature) print("## headers ", custom_headers) print("## Request Body : ", encode_request_body) ## POST Request response = requests.post(headers=custom_headers, url=self.ep_path, data=encode_request_body) return response @staticmethod def get_timestamp(): timestamp = int(time.time() * 1000) return timestamp @staticmethod def make_signature(secret_key, request_body): secret_key_bytes = bytes(secret_key, 'UTF-8') signing_key = base64.b64encode(hmac.new(secret_key_bytes, request_body, digestmod=hashlib.sha256).digest()) return signing_key if __name__ == '__main__': res = ChatbotMessageSender().req_message_send() print(res.status_code) if(res.status_code == 200): print(res.text) #print(res.read().decode("UTF-8")) ``` ### PHP PHP 기반의 API 예제 코드는 다음과 같습니다. ``` function makeSignature($secretKey, $requestBody) { $signautue = base64_encode(hash_hmac('sha256', $requestBody, $secretKey,true)); //echo "this is signiture : ".$signautue."\n"; return $signautue; } try { // User IP if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']) { $clientIpAddress = $_SERVER['HTTP_X_FORWARDED_FOR']; } else { $clientIpAddress = $_SERVER['HTTP_X_FORWARDED_FOR']; } $timestamp = ""; $microtime = ""; list($microtime,$timestamp) = explode(' ',microtime()); $timestamp = $timestamp.substr($microtime, 2, 3); $url = "https://xi3mfpym2x.apigw.ntruss.com/send/beta/"; $requestBody= '{ "version": "v2", "userId": "U47b00b58c90f8e47428af8b7bddcda3d231", "userIp": "'.$clientIpAddress.'", "timestamp": '.$timestamp.', "bubbles": [ { "type": "text", "data" : { "description" : "postback text of welcome action" } } ], "event": "open" }'; $secretKey = "YnVFTWZDemt3bUZhaEJlalN1Z3ZNY2pzeVp0aVRjd04=12"; $signautue = makeSignature($secretKey,$requestBody); $is_post = true; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody); $headers = array(); $headers[] = "Content-Type:application/json; charset=utf-8"; $headers[] = "X-NCP-CHATBOT_SIGNATURE: " .$signautue; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $response = curl_exec($ch); $err = curl_error($ch); curl_close ($ch); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; } } catch(Exception $E) { echo "Response: ". $E->lastResponse . "\n"; } ?> ``` ### Swift Swift 기반의 API 예제 코드는 다음과 같습니다. ``` import UIKit import CommonCrypto // chatbot custom secret key let secret_key = ""; // chatbot api gateway url let invoke_url = ""; class ViewController: UIViewController, URLSessionDelegate { override func viewDidLoad() { super.viewDidLoad() demo() } func demo() { let timeInterval: TimeInterval = NSDate().timeIntervalSince1970 let millisecond = CLongLong(round(timeInterval*1000)) let body = ["bubbles":[["data": ["description":"test"], "type":"text"]], "event":"send", "timestamp":millisecond, "userId":"test", "version":"v2"] as NSDictionary do { let jsonDataFromBody = try JSONSerialization.data(withJSONObject: body, options: JSONSerialization.WritingOptions.prettyPrinted) let jsonBytes = [CUnsignedChar](jsonDataFromBody) let jsonBytesPointer = UnsafePointer(jsonBytes) //UnsafeRawPointer let cKey = secret_key.cString(using: String.Encoding.utf8) let digestLen = Int(CC_SHA256_DIGEST_LENGTH) let sha256 = UnsafeMutablePointer.allocate(capacity: digestLen) CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), cKey, secret_key.lengthOfBytes(using: String.Encoding.utf8), jsonBytesPointer, jsonBytes.count, sha256) let base64_sha256 = Data.init(bytes: sha256, count: Int(CC_SHA256_DIGEST_LENGTH)).base64EncodedString() httpsRequest("X-NCP-CHATBOT_SIGNATURE", base64_sha256, body: jsonDataFromBody) sha256.deallocate() } catch { print(error) } } func httpsRequest(_ signHeaderKey:String, _ signature:String, body:Data) { let url = URL.init(string: invoke_url)! var request = URLRequest.init(url: url) request.addValue(signature, forHTTPHeaderField: signHeaderKey) request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" request.httpBody = body let session = URLSession.shared let task = session.dataTask(with: request) { (data:Data?, response:URLResponse?, error:Error?) in print(String.init(data:data!, encoding: .utf8)!) } task.resume() } func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { if challenge.protectionSpace.authenticationMethod != NSURLAuthenticationMethodServerTrust { return } let credential = URLCredential.init(trust: challenge.protectionSpace.serverTrust!) completionHandler(URLSession.AuthChallengeDisposition.useCredential, credential) } } ``` ### Objective-C Objective-C 기반의 API 예제 코드는 다음과 같습니다. ``` #import "ViewController.h" #import #import // chatbot custom secret key static NSString *secret_key = @""; // chatbot api gateway url static NSString *invoke_url = @""; @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self demo]; } - (void)demo { NSTimeInterval time = [[NSDate date] timeIntervalSince1970]*1000; long long millisecond = [[NSNumber numberWithDouble:time] longLongValue]; NSDictionary *body = @{@"bubbles":@[@{@"data":@{@"description":@"test"}, @"type":@"text"}], @"event":@"send", @"timestamp":millisecond, @"userId":@"U47b00b58c90f8e47428af8b7bddcda3d1111111", @"version":@"v2" }; NSError *error; NSData *jsondataFrombody = [NSJSONSerialization dataWithJSONObject:body options:0 error:&error]; const char *cKey = [secret_key cStringUsingEncoding:NSUTF8StringEncoding]; NSMutableData* sha256 = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH]; CCHmac(kCCHmacAlgSHA256, cKey, secret_key.length, jsondataFrombody.bytes, jsondataFrombody.length, sha256.mutableBytes); NSString *base64_sha256 = [sha256 base64EncodedStringWithOptions:0]; [self httpsRequest:@"X-NCP-CHATBOT_SIGNATURE" signature:base64_sha256 bodyData:jsondataFrombody]; } - (void)httpsRequest:(NSString *)signHeaderKey signature:(NSString *)sign bodyData:(NSData *)bodyData { NSURL *url = [NSURL URLWithString:invoke_url]; NSMutableURLRequest *mRequest = [NSMutableURLRequest requestWithURL:url]; [mRequest setValue:sign forHTTPHeaderField:signHeaderKey]; [mRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; mRequest.HTTPMethod = @"POST"; mRequest.HTTPBody = bodyData; NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];//replace delegateQueue with your workingQueue NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:mRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSLog(@"response: %@", [response description]); NSLog(@"response data:%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); }]; [dataTask resume]; } - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler { if (![challenge.protectionSpace.authenticationMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"]) { return; } NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust]; completionHandler(NSURLSessionAuthChallengeUseCredential,credential); } @end ```