CLOVA Chatbot APIのユースケース

Prev Next

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<String> 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<VoiceChatbotActivity> mActivity;
            RecognitionHandler(VoiceChatbotActivity activity) {
                mActivity = new WeakReference<VoiceChatbotActivity>(activity);
            }
            @Override
            public void handleMessage(Message msg) {
                VoiceChatbotActivity activity = mActivity.get();
                if (activity != null) {
                    activity.handleMessage(msg);
                }
            }
        }
    
        public class VoiceChatbotTask extends AsyncTask<String, String, String> {
    
            @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<String, String, String> {
    
            @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<CUnsignedChar>(jsonBytes) //UnsafeRawPointer

            let cKey = secret_key.cString(using: String.Encoding.utf8)
            let digestLen = Int(CC_SHA256_DIGEST_LENGTH)
            let sha256 = UnsafeMutablePointer<CUnsignedChar>.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 <UIKit/UIKit.h>
#import <CommonCrypto/CommonHMAC.h>

// chatbot custom secret key
static NSString *secret_key = @"";

// chatbot api gateway url
static NSString *invoke_url = @"";

@interface ViewController () <NSURLSessionDelegate>

@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