1
0
mirror of https://github.com/chatopera/cosin.git synced 2025-08-01 16:38:02 +08:00

Merge branch 'develop' into feature/#58

This commit is contained in:
Kyle 2018-09-07 11:00:13 +08:00
commit db2a252972
No known key found for this signature in database
GPG Key ID: E9D96D736A2D3F3C
6 changed files with 957 additions and 3 deletions

View File

@ -0,0 +1,22 @@
/*
* Copyright (C) 2018 Chatopera Inc, <https://www.chatopera.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.chatopera.cc.util.exception;
public class CSKefuRestException extends Exception {
public CSKefuRestException(String msg){
super(msg);
}
}

View File

@ -0,0 +1,94 @@
package com.chatopera.cc.util.json;
/*
* Copyright (C) 2018 Chatopera Inc, <https://www.chatopera.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.util.Map;
public class GsonTools {
public static enum ConflictStrategy {
THROW_EXCEPTION, PREFER_FIRST_OBJ, PREFER_SECOND_OBJ, PREFER_NON_NULL;
}
public static class JsonObjectExtensionConflictException extends Exception {
public JsonObjectExtensionConflictException(String message) {
super(message);
}
}
public static void extendJsonObject(JsonObject destinationObject, ConflictStrategy conflictResolutionStrategy, JsonObject... objs)
throws JsonObjectExtensionConflictException {
for (JsonObject obj : objs) {
extendJsonObject(destinationObject, obj, conflictResolutionStrategy);
}
}
private static void extendJsonObject(JsonObject leftObj, JsonObject rightObj, ConflictStrategy conflictStrategy)
throws JsonObjectExtensionConflictException {
for (Map.Entry<String, JsonElement> rightEntry : rightObj.entrySet()) {
String rightKey = rightEntry.getKey();
JsonElement rightVal = rightEntry.getValue();
if (leftObj.has(rightKey)) {
//conflict
JsonElement leftVal = leftObj.get(rightKey);
if (leftVal.isJsonArray() && rightVal.isJsonArray()) {
JsonArray leftArr = leftVal.getAsJsonArray();
JsonArray rightArr = rightVal.getAsJsonArray();
//concat the arrays -- there cannot be a conflict in an array, it's just a collection of stuff
for (int i = 0; i < rightArr.size(); i++) {
leftArr.add(rightArr.get(i));
}
} else if (leftVal.isJsonObject() && rightVal.isJsonObject()) {
//recursive merging
extendJsonObject(leftVal.getAsJsonObject(), rightVal.getAsJsonObject(), conflictStrategy);
} else {//not both arrays or objects, normal merge with conflict resolution
handleMergeConflict(rightKey, leftObj, leftVal, rightVal, conflictStrategy);
}
} else {//no conflict, add to the object
leftObj.add(rightKey, rightVal);
}
}
}
private static void handleMergeConflict(String key, JsonObject leftObj, JsonElement leftVal, JsonElement rightVal, ConflictStrategy conflictStrategy)
throws JsonObjectExtensionConflictException {
{
switch (conflictStrategy) {
case PREFER_FIRST_OBJ:
break;//do nothing, the right val gets thrown out
case PREFER_SECOND_OBJ:
leftObj.add(key, rightVal);//right side auto-wins, replace left val with its val
break;
case PREFER_NON_NULL:
//check if right side is not null, and left side is null, in which case we use the right val
if (leftVal.isJsonNull() && !rightVal.isJsonNull()) {
leftObj.add(key, rightVal);
}//else do nothing since either the left value is non-null or the right value is null
break;
case THROW_EXCEPTION:
throw new JsonObjectExtensionConflictException("Key " + key + " exists in both objects and the conflict resolution strategy is " + conflictStrategy);
default:
throw new UnsupportedOperationException("The conflict strategy " + conflictStrategy + " is unknown and cannot be processed");
}
}
}
}

View File

@ -17,8 +17,10 @@
package com.chatopera.cc.webim.service.es;
import com.chatopera.cc.webim.web.model.ContactNotes;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface ContactNotesRepository extends ElasticsearchRepository<ContactNotes, String> {
public Page<ContactNotes> findByContactidAndOrgiOrderByCreatetimeDesc(String contactid, String q, Pageable page);
}

View File

@ -15,22 +15,305 @@
*/
package com.chatopera.cc.webim.web.handler.api.rest;
import com.chatopera.cc.core.UKDataContext;
import com.chatopera.cc.util.Constants;
import com.chatopera.cc.util.Menu;
import com.chatopera.cc.util.exception.CSKefuRestException;
import com.chatopera.cc.util.json.GsonTools;
import com.chatopera.cc.webim.service.es.ContactNotesRepository;
import com.chatopera.cc.webim.service.es.ContactsRepository;
import com.chatopera.cc.webim.service.repository.OrganRepository;
import com.chatopera.cc.webim.service.repository.UserRepository;
import com.chatopera.cc.webim.web.handler.Handler;
import com.chatopera.cc.webim.web.handler.api.request.RestUtils;
import com.chatopera.cc.webim.web.model.ContactNotes;
import com.chatopera.cc.webim.web.model.Contacts;
import com.chatopera.cc.webim.web.model.Organ;
import com.chatopera.cc.webim.web.model.User;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/**
* 联系人笔记
*/
@RestController
@RequestMapping("/api/contactnotes")
@RequestMapping("/api/contacts/notes")
@Api(value = "联系人笔记", description = "管理联系人笔记")
public class ApiContactNotesController extends Handler {
private final static Logger logger = LoggerFactory.getLogger(ApiContactNotesController.class);
@Autowired
private ContactNotesRepository contactNotesRes;
@Autowired
private ContactsRepository contactsRes;
@Autowired
private UserRepository userRes;
@Autowired
private OrganRepository organRes;
/**
* 获取创建人
*
* @param creater
* @return
*/
private JsonObject creater(final String creater) {
JsonObject data = new JsonObject();
// 增加创建人
User u = userRes.findById(creater);
if (u != null) {
data.addProperty("creater", u.getId());
data.addProperty("creatername", u.getUname());
// 获取创建者部门
if (u.getOrgan() != null) {
Organ o = organRes.findOne(u.getOrgan());
if (o != null) {
data.addProperty("createrorgan", o.getName());
data.addProperty("createrorganid", o.getId());
}
}
} else {
logger.warn("[contact notes] detail [{}] 无法得到创建者。", creater);
}
return data;
}
/**
* 获取笔记详情
*
* @param j
* @return
*/
private JsonObject detail(final JsonObject j) throws GsonTools.JsonObjectExtensionConflictException {
logger.info("[contact note] detail {}] {}", j.toString());
JsonObject resp = new JsonObject();
// TODO 增加权限检查
if (j.has("id") && StringUtils.isNotBlank(j.get("id").getAsString())) {
ContactNotes cn = contactNotesRes.findOne(j.get("id").getAsString());
if (cn != null) {
JsonObject data = new JsonObject();
data.addProperty("contactid", cn.getContactid());
data.addProperty("category", cn.getCategory());
data.addProperty("createtime", Constants.DISPLAY_DATE_FORMATTER.format(cn.getCreatetime()));
data.addProperty("updatetime", Constants.DISPLAY_DATE_FORMATTER.format(cn.getUpdatetime()));
data.addProperty("content", cn.getContent());
data.addProperty("agentuser", cn.getAgentuser());
data.addProperty("onlineuser", cn.getOnlineuser());
GsonTools.extendJsonObject(data, GsonTools.ConflictStrategy.PREFER_FIRST_OBJ, creater(cn.getCreater()));
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC);
resp.add(RestUtils.RESP_KEY_DATA, data);
} else {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_2);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不存在该联系人笔记。");
}
}
return resp;
}
/**
* 创建联系人笔记
*
* @param payload
* @return
*/
private JsonObject create(final JsonObject payload) {
logger.info("[contact note] create {}", payload.toString());
JsonObject resp = new JsonObject();
// validate parameters
String invalid = validateCreatePayload(payload);
if (invalid != null) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_2);
resp.addProperty(RestUtils.RESP_KEY_ERROR, invalid);
return resp;
}
ContactNotes cn = new ContactNotes();
cn.setCategory(payload.get("category").getAsString());
cn.setContent(payload.get("content").getAsString());
cn.setCreater(payload.get("creater").getAsString());
cn.setOrgi(payload.get("orgi").getAsString());
cn.setContactid(payload.get("contactid").getAsString());
cn.setDatastatus(false);
Date dt = new Date();
cn.setCreatetime(dt);
cn.setUpdatetime(dt);
if (payload.has("agentuser")) {
cn.setAgentuser(payload.get("agentuser").getAsString());
}
if (payload.has("onlineuser")) {
cn.setOnlineuser(payload.get("onlineuser").getAsString());
}
contactNotesRes.save(cn);
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC);
JsonObject data = new JsonObject();
data.addProperty("id", cn.getId());
data.addProperty("updatetime", Constants.DISPLAY_DATE_FORMATTER.format(dt));
resp.add("data", data);
return resp;
}
/**
* 验证创建数据
*
* @param payload
* @return
*/
private String validateCreatePayload(JsonObject payload) {
if (!payload.has("category")) {
return "参数传递不合法,没有[category]。";
}
if ((!payload.has("content")) || StringUtils.isBlank(payload.get("content").getAsString())) {
return "参数传递不合法,没有[content]。";
}
if ((!payload.has("contactid")) || StringUtils.isBlank(payload.get("contactid").getAsString())) {
return "参数传递不合法,没有[contactid]。";
} else {
Contacts c = contactsRes.findOne(payload.get("contactid").getAsString());
if (c == null)
return "参数不合法,不存在该联系人。";
}
return null;
}
/**
* Build query string
*
* @param j
* @return
*/
private String querybuilder(final JsonObject j) {
StringBuffer sb = new StringBuffer();
if (j.has("orgi")) {
sb.append("orgi:");
sb.append(j.get("orgi").getAsString());
sb.append(" ");
}
return sb.toString();
}
/**
* 根据联系人ID获取联系人笔记列表
*
* @param j
* @param request
* @return
*/
private JsonObject fetch(final JsonObject j, final HttpServletRequest request) throws GsonTools.JsonObjectExtensionConflictException {
logger.info("[contact note] fetch [{}]", j.toString());
JsonObject resp = new JsonObject();
if ((!j.has("contactid")) || StringUtils.isBlank(j.get("contactid").getAsString())) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_2);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "参数传递不合法,没有[contactid]。");
return resp;
}
final String cid = j.get("contactid").getAsString();
Contacts c = contactsRes.findOne(cid);
if (c == null) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_4);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不存在该联系人。");
return resp;
}
String q = querybuilder(j);
Page<ContactNotes> cns = contactNotesRes.findByContactidAndOrgiOrderByCreatetimeDesc(cid,
q, new PageRequest(super.getP(request), super.getPs(request)));
resp.addProperty("size", cns.getSize());
resp.addProperty("number", cns.getNumber());
resp.addProperty("totalPage", cns.getTotalPages());
resp.addProperty("totalElements", cns.getTotalElements());
// 转化 page json
JsonArray data = new JsonArray();
for (ContactNotes cn : cns) {
if (cn != null) {
JsonObject x = new JsonObject();
x.addProperty("contactid", cn.getContactid());
x.addProperty("category", cn.getCategory());
x.addProperty("createtime", Constants.DISPLAY_DATE_FORMATTER.format(cn.getCreatetime()));
x.addProperty("updatetime", Constants.DISPLAY_DATE_FORMATTER.format(cn.getUpdatetime()));
x.addProperty("content", cn.getContent());
x.addProperty("agentuser", cn.getAgentuser());
x.addProperty("onlineuser", cn.getOnlineuser());
GsonTools.extendJsonObject(x, GsonTools.ConflictStrategy.PREFER_FIRST_OBJ, creater(cn.getCreater()));
data.add(x);
}
}
resp.add("data", data);
return resp;
}
@RequestMapping(method = RequestMethod.POST)
@Menu(type = "apps", subtype = "contactnotes", access = true)
@ApiOperation("联系人笔记")
public ResponseEntity<String> operations(HttpServletRequest request, @RequestBody final String body) throws CSKefuRestException, GsonTools.JsonObjectExtensionConflictException {
final JsonObject j = (new JsonParser()).parse(body).getAsJsonObject();
logger.info("[contact note] operations payload {}", j.toString());
JsonObject json = new JsonObject();
HttpHeaders headers = RestUtils.header();
j.addProperty("creater", super.getUser(request).getId());
j.addProperty("orgi", UKDataContext.SYSTEM_ORGI);
if (!j.has("ops")) {
json.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_1);
json.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的请求参数。");
} else {
switch (StringUtils.lowerCase(j.get("ops").getAsString())) {
case "create":
json = create(j);
break;
case "detail":
json = detail(j);
break;
case "fetch":
json = fetch(j, request);
break;
default:
json.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
json.addProperty(RestUtils.RESP_KEY_ERROR, "不支持的操作。");
break;
}
}
return new ResponseEntity<String>(json.toString(), headers, HttpStatus.OK);
}
}

View File

@ -280,7 +280,8 @@
// 参数连接
// 参数连接
var hostname = location.hostname ;
var socket = io.connect('${schema!'http'}://'+hostname+':${port}/im/user?userid=${userid!''}<#if aiid??>&aiid=${aiid}</#if>&orgi=${orgi!''}&session=${sessionid!''}&appid=${appid!''}&osname=${(osname!'')?url}&browser=${(browser!'')?url}<#if skill??>&skill=${skill}</#if><#if agent??>&agent=${agent}</#if>');
var protocol = window.location.protocol.replace(/:/g,'');
var socket = io.connect(protocol + '://'+hostname+':${port}/im/user?userid=${userid!''}<#if aiid??>&aiid=${aiid}</#if>&orgi=${orgi!''}&session=${sessionid!''}&appid=${appid!''}&osname=${(osname!'')?url}&browser=${(browser!'')?url}<#if skill??>&skill=${skill}</#if><#if agent??>&agent=${agent}</#if>');
socket.on('connect',function(){
//service.sendRequestMessage();
//output('<span id="callOutConnect-message">'+ new Date().format("yyyy-MM-dd hh:mm:ss") + ' 开始沟通' +'</span>' , 'message callOutConnect-message');

View File

@ -0,0 +1,552 @@
{
"info": {
"_postman_id": "845f31e9-eedd-4168-b2d7-f56e7ff40f58",
"name": "Chatopera_cc_v1",
"description": "Chatopera Contact Center API",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "http://{{IP}}:{{PORT}}/tokens",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "Accept",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/tokens?username=admin&password=admin1234",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"tokens"
],
"query": [
{
"key": "username",
"value": "admin"
},
{
"key": "password",
"value": "admin1234"
}
]
}
},
"response": []
},
{
"name": "http://{{IP}}:{{PORT}}/api/user",
"request": {
"method": "GET",
"header": [
{
"key": "authorization",
"value": "{{AUTH}}"
}
],
"body": {},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/user",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"user"
]
}
},
"response": []
},
{
"name": "启动呼叫计划",
"request": {
"method": "POST",
"header": [
{
"key": "authorization",
"value": "4ef6064932a04f7c87d431f1189392d6"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\"ops\": \"execute\", \"dialplanId\": \"402882516556801d016556db24e908de\"}"
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/callout/dialplan",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"callout",
"dialplan"
]
}
},
"response": []
},
{
"name": "暂停呼叫计划",
"request": {
"method": "POST",
"header": [
{
"key": "authorization",
"value": "75dc28487bb84fb59edbb7231fd6bfda"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\"ops\": \"pause\", \"dialplanId\": \"402882516546e777016546eeb00c0452\"}"
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/callout/dialplan",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"callout",
"dialplan"
]
}
},
"response": []
},
{
"name": "删除呼叫计划",
"request": {
"method": "POST",
"header": [
{
"key": "authorization",
"value": "098e0f79525d472a9beb4197f02ff8cb"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\"ops\": \"delete\", \"dialplanId\": \"402882516556801d016556db24e908de\"}"
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/callout/dialplan",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"callout",
"dialplan"
]
}
},
"response": []
},
{
"name": "通话记录查询",
"request": {
"method": "POST",
"header": [
{
"key": "authorization",
"value": "05f13a549bb04a2a9849563e38a60695"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\"ops\": \"query\", \"fromdate\": \"2018-08-21\", \"enddate\": \"2018-08-20\"}"
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/callout/records?p=1&ps=20",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"callout",
"records"
],
"query": [
{
"key": "p",
"value": "1"
},
{
"key": "ps",
"value": "20"
}
]
}
},
"response": []
},
{
"name": "获取语音渠道坐席监控数据",
"request": {
"method": "POST",
"header": [
{
"key": "authorization",
"value": "55d8348d753b432c9b9e42c39d35ccc8"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\"ops\": \"status\", \"channel\": \"bxzq\"}"
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/callout/monitor",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"callout",
"monitor"
]
}
},
"response": []
},
{
"name": "获取文件URL",
"request": {
"method": "POST",
"header": [
{
"key": "authorization",
"value": "6db1ae1e5f5740df98b7d54d38fdb89c"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\"ops\": \"wav\", \"file\": \"2018-08-22/63187a63-f2c8-4463-85a6-db5d49851945.wav\"}"
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/callout/records",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"callout",
"records"
]
}
},
"response": []
},
{
"name": "外呼日报查询",
"request": {
"method": "POST",
"header": [
{
"key": "authorization",
"value": "ad163116e63b4764ba0a741cf882ed23"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\"ops\": \"agg\", \"datestr\": \"2018-08-22\", \"channel\": \"bxzq\", \"direction\": \"out\"}"
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/callout/records",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"callout",
"records"
]
}
},
"response": []
},
{
"name": "坐席报表查询",
"request": {
"method": "POST",
"header": [
{
"key": "authorization",
"value": "ca8c28e459fd477b9ccc9f210a3a81ea"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"ops\": \"audit\",\n \"fromdate\": \"2018-08-22\",\n \"channel\": \"bxzq\",\n \"enddate\": \"2018-08-24\"\n}"
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/callout/records",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"callout",
"records"
]
}
},
"response": []
},
{
"name": "坐席监控",
"request": {
"method": "POST",
"header": [
{
"key": "authorization",
"value": "570d6bd5f37441af977ab7eceeb6951a"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"ops\": \"status\",\n \"channel\": \"bxzq\"\n}"
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/callout/monitor",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"callout",
"monitor"
]
}
},
"response": []
},
{
"name": "坐席监听",
"request": {
"method": "POST",
"header": [
{
"key": "authorization",
"value": "ea9639dd357941f4986b8d19d2a91496"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"ops\": \"dropin\",\n \"channel\": \"bxzq\",\n \"callid\": \"2523f480-9e16-4a7a-9c3d-318ea7624109\"\n}"
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/callout/monitor",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"callout",
"monitor"
]
}
},
"response": []
},
{
"name": "\b联系人笔记创建",
"request": {
"method": "POST",
"header": [
{
"key": "authorization",
"value": "1e597e76a338439ebc2411a4a69d7d9f"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\"ops\": \"create\", \"category\": \"外呼\", \"content\": \"xx\", \"contactid\": \"25d61fe78db54bec95c9d0f405d0b20b\"}"
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/contacts/notes",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"contacts",
"notes"
]
}
},
"response": []
},
{
"name": "\b联系人笔记详情",
"request": {
"method": "POST",
"header": [
{
"key": "authorization",
"value": "d6e1a25c36194b2ba501a01f6ab4aaae"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\"ops\": \"detail\", \"id\": \"xxx\"}"
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/contacts/notes",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"contacts",
"notes"
]
}
},
"response": []
},
{
"name": "\b联系人笔记获取联系人所有笔记",
"request": {
"method": "POST",
"header": [
{
"key": "authorization",
"value": "06d09745a0964d258d86c07cc4f7f838"
},
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\"ops\": \"fetch\", \"contactid\": \"xxx\"}"
},
"url": {
"raw": "http://{{IP}}:{{PORT}}/api/contacts/notes",
"protocol": "http",
"host": [
"{{IP}}"
],
"port": "{{PORT}}",
"path": [
"api",
"contacts",
"notes"
]
}
},
"response": []
}
],
"event": [
{
"listen": "prerequest",
"script": {
"id": "ee82d425-91be-4e85-b3da-7fbfd5d0da19",
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"id": "26cdde89-40b3-4b7f-85ad-09652137888c",
"type": "text/javascript",
"exec": [
""
]
}
}
]
}