简介
3CX 包含了一种与 CRM 整合的服务端整合,该整合将会匹配来电者。当 3CX 收到一通呼叫,3CX 会在 CRM 中查找该联系人是否存在,如果存在将该联系人添加到 3CX 中,并在来电显示中显示联系人信息。
3CX 系统中提供了很多种 CRM 的整合供用户使用。如果你们使用的 CRM 不在其中,我们也为这些用户提供了一种方式。只需要懂一些基础编程和 Web 知识的人就可以轻松创建一个模板或配置文件对接 3CX,前提是 CRM/ERP 需要支持 REST API。
我们使用的是基于 XML 配置文件的服务端整合系统。这些模板/配置文件定义了鉴权的方法,登录系统的链接以及查询联系人的步骤和方式。
在该教程中我们会演示如何安装和使用我们的模板生成工具(template generator tool),并一步一步为你的 CRM 创建新模板。在这里我们演示的 CRM 是 Freshdesk。
前提条件
整合 CRM 我们需要提前准备好以下事项:
- CRM 需要支持 RESTFul API 并具有不错的文档。
 - CRM 需要支持 Basic 或者 OAuth2 的鉴权方式。
 - 下载 3CX 模板生成器(Template Generator)。
 - 参考 3CX XML 模板详细描述。
 
1. 获取需要调用的 API 链接
打开 CRM 的 API 文档,并找到我们需要的 API 链接和需要的信息:
- 鉴权方式:在这里可以看到,我们需要使用 Basic 鉴权。 

 - 查找联系人的语句:
https://example.freshdesk.com/api/v2/contacts?phone=+15551234567https://example.freshdesk.com/api/v2/contacts?mobile=+15551234567 - 发送创建 Ticket 的 POST 请求以将呼叫记录为 Ticket:
https://example.freshdesk.com/api/v2/tickets - 当找不到联系人的时候我们需要创建联系人,创建联系人的 POST 请求链接:
https://example.freshdesk.com/api/v2/contacts 
2. 设置模板属性
打开 3CX 模板生成器(Template Generator)后,会自动创建一个新的空白模板。选择 “New Template” 标签并填入下列信息:
- Country:设置两个字母的国家代码,比如:CN
 - Name:在 3CX 服务端显示的集成名称,这里我们使用 Freshdesk
 - Version:版本号,这里设置为 1
 - InternationalPrefix:国家代码前缀,这里设置为 Zeros。意为使用 00 处理国家代码前缀
 - MaxLength:最大长度。留空,意味着 3CX 收到的所有号码都会送到 Freshdesk

 
3. 获取并配置所需的参数
这里的参数是指用户在 3CX 服务端输入的参数,点击 Parameters > Add 添加参数,Freshdesk 需要下列几个参数:
- 联系人查找
- API Key
- Name = APIKey
 - Title = API Key:
 - type = String
 
 - 域名
- Name = Domain
 - Title = Domain Part:
 - type = String
 
 
 - API Key
 - 呼叫记录
- 开启呼叫记录
- Name = ReportCallEnabled
 - Title = Enable Call Journaling
 - type = Boolean
 
 - 记录类型
- Name = Subject
 - Title = Ticket Subject:
 - type = String
 
 - 呼入通话显示文本
- Name = InboundCallText
 - Title = Missed Call:
 - type = String
 
 - 外呼通话显示文本
- Name = OutboundCallText
 - Title = Answered Outbound Call:
 - type = String
 
 - 未接外呼通话显示文本
- Name = NotAnweredOutboundCallText
 - Titile = Unanswered Outbound Call:
 - type = String
 
 
 - 开启呼叫记录
 - 创建联系人
- 开启联系人创建功能
- Name = CreateContactEnabled
 - Title = Enable Contact Creation
 - type = Boolean
 
 - 创建联系人的姓名
- CreateContactName
 - Title = New Contact Name:
 - type = String
 
 
 - 开启联系人创建功能
 
4. 配置鉴权
在这里我们使用 Basic 鉴权的方式,所以按照下列步骤:
- 点击 Authentication
 - Select Type = Basic
 - 在 Value 区域内填入 APIKey 的参数变量:[APIKey]:X
 
接下来,所有发往服务器的请求都会包含 Basic 鉴权验证值的 Authorization 标头。
5. 配置联系人匹配场景
添加一个场景(Scenario)执行查找 phone 字段的功能:
- 点击 Matching Scenario,并设置 Request Type 为 Get
 - 输入 URL:https://[Domain].freshdesk.com/api/v2/contacts?phone=[Number]
 - 将 response type 改为 JSON
 - 创建一个 Rule Group
- Path = phone
 - Type = Number
 
这一步会将 “phone” 路径作为一个记录。
 - 增加五个变量(variables)
- Key = Id, Path = id
 - Key = Name, Path = name
 - Key = WorkPhone, Path = phone
 - Key = MobilePhone, Path = mobile
 - Key = Email, Path = email
 
 - 添加六个输入(outputs)
- Type = ContactId, Value = [Id]
 - Type = FirstName, Value = [Name]
 - Type = PhoneMobile, Value = [MobilePhone]
 - Type = PhoneBusiness, Value = [WorkPhone]
 - Type = Email, Value = [Email]
 - Type = ContactUrl, Value = https://[Domain].freshdesk.com/contacts/[Id]
 
 
添加另一个场景(Scenario)执行 mobile 字段的查找:
- 重复执行上述步骤,将 URL 替换为:https://[Domain].freshdesk.com/api/v2/contacts?mobile=[Number]
 - 将 Rule Group 的 Path 改为 mobile, Type 改为 Number
 
6. 配置呼叫记录场景
增加一个当通话结束后在 Freshdesk 创建记录的场景(Scenario):
- 将该 Scenario 的 Id 改为 ReportCall
 - 当该功能被关闭时我们需要跳过,将 SkipIf 的值设为:
[ReportCallEnabled]!=True - 将 Request 设为 Post
 - 填入链接:https://[Domain].freshdesk.com/api/v2/tickets
 - 将 request encoding type 设置为 JSON
 - 将 reponse type 设置为 JSON
 
现在我们需要指定 POST 的数据。这部分在该工具中无法修改,请保存文件,关闭软件,并使用文本编辑器打开 XML 模板文件。找到 Id = “ReportCall” 的场景,按照下面的方式进行修改:
<Scenario Id="ReportCall">
<Request SkipIf="[ReportCallEnabled]!=True" Url="https://[Domain].freshdesk.com/api/v2/tickets" RequestType="Post" RequestEncoding="Json" ResponseType="Json" >
<PostValues>
<Value Key="requester_id" Type="Integer">[Contact::ContactId]</Value>
<Value Key="phone">[Number]</Value>
<Value Key="subject" Passes="2">[[Subject]]</Value>
<Value Key="status" Type="Integer">2</Value>
<Value Key="priority" Type="Integer">1</Value>
<Value Key="description" Passes="2" If="[CallType]==Inbound">[[InboundCallText]]</Value>
<Value Key="description" Passes="2" If="[CallType]==Missed">[[MissedCallText]]</Value>
<Value Key="description" Passes="2" If="[CallType]==Outbound">[[OutboundCallText]]</Value>
<Value Key="description" Passes="2" If="[CallType]==Notanswered">[[NotAnweredOutboundCallText]]</Value>
<Value Key="source" Type="Integer">3</Value>
<Array Key="tags">
<Value>[CallType]</Value>
<Value>Call</Value>
<Value>[Agent]</Value>
</Array>
</PostValues>
</Request>
</Scenario>
<PostValues> 元素内的 XML 结构需要是 JSON 对象,即:
{
  requester_id: 1234,
  phone: "+15551234567",
  subject: "New Ticket",
  status: 2,
  priority: 1,
  description: "03/12/2018: Answered incoming call from +15551234567 John Doe to 100 (5:32)",
  source: 3,
  tags: [
    "Inbound",
    "Call",
    "100"
  ]
}
请注意以下细节:
requester_id的值取自变量[Contact::ContactId]。这里可以使用在查找联系人过程中输出的任何值。- “subject” 和 “description” 的值包含了一个 Passes=”2″ 的属性,而且变量 
[[Subject]]和[[InboundCallText]]是双括号的。这意味着这些表达式会被取两次值。第一次,引擎会从[Subject]和[InboundCallText]变量中获取值,接着当他们返回值的时候在取一次值。我们可以这么描述这个过程:- 第一次:
[[InboundCallText]]取到的值是[DateTime]: Answered incoming call from [Number] [Name] to [Agent] ([Duration]) - 第二次:
[DateTime]: Answered incoming call from [Number] [Name] to [Agent] ([Duration])取得的值为03/12/2018: Answered incoming call from +15551234567 John Doe to 100 (5:32) 
 - 第一次:
 - 值 “description” 出现了 4 次。不过我们使用 “If” 属性对它进行了选择,另外 3 种结果不会在输出中产生。
 
请注意该场景(scenario)不会增加任何变量(Variable)或者输出(Output)。因为 ReportCall 场景不需要返回任何信息给 3CX。
将我们做出的修改保存到 XML 文件,并重新打开 3CX 模板生成工具。
7. 配置联系人创建场景
添加当来电号码没有匹配时在 Freshdesk 创建联系人的场景(Scenario):
- 将场景(Scenario)的 Id 改为 CreateContactRecord
 - 当用户关闭该选项的时候我们需要跳过此场景,将 SkipIf 的表达式设置为 
[CreateContactEnabled]!=True - 将 Request Type 设为 Post
 - 在 URL 内填入:https://[Domain].freshdesk.com/api/v2/contacts
 - 将 request encoding type 设置为 JSON
 - 将 reponse type 设置为 JSON
 
现在我们需要指定 Post 的数据。这部分在该工具中无法修改,请保存文件,关闭软件,并使用文本编辑器打开 XML 模板文件。找到 Id = “CreateContactRecord” 的场景,按照下面的方式进行修改:
<Scenario Id="CreateContactRecord">
<Request SkipIf="[CreateContactEnabled]!=True" Url="https://[Domain].freshdesk.com/api/v2/contacts" RequestType="Post" RequestEncoding="Json" ResponseType="Json" >
<PostValues>
<Value Passes="2" Key="name">[[CreateContactName]]</Value>
<Value Passes="1" Key="phone">[Number]</Value>
</PostValues>
</Request>
<Rules>
<Rule Type="Any">id</Rule>
</Rules>
<Variables>
<Variable Name="Id" Path="id" />
</Variables>
<Outputs AllowEmpty="false">
<Output Type="ContactUrl" Value="https://[Domain].freshdesk.com/contacts/[Id]" />
<Output Type="FirstName" Value="[CreateContactName]" />
<Output Type="PhoneBusiness" Value="[Number]" />
<Output Type="ContactId" Value="[Id]" />
</Outputs>
</Scenario>
<PostValues> 元素内的 XML 结构需要是 JSON 对象,即:
{
  name: "John Doe",
  phone: "+15551234567"
}
需要注意以下细节:
- “name” 的值包含了一个 Passes=”2″ 的属性,而且变量 
[[CreateContactName]]是双括号的。这意味着这些表达式会被取两次值。第一次,引擎会从[[CreateContactName]]变量中获取值,接着当他们返回值的时候在取一次值。我们可以这么描述这个过程:- 第一次:
[[CreateContactName]]取完值后应为New 3CX Contact [Number] - 第二次:
New 3CX Contact [Number]取完值后应为New 3CX Contact +15551234567 
 - 第一次:
 
8. 测试
我们的工具允许用户在 Parameter 中输入 CRM 信息进行测试。点击 “Parameter Values” 输入 Freshdesk 账户信息即可:

- 我们需要设置一个号码模拟来电,在 Number 属性框中设置:

 - 右键 Parameter Values 并选择 “Contact Lookup” 模拟联系人查找场景
 - 在执行完毕之后,Parameter Values 下会有一个带有时间戳标记的节点,这就是运行的结果了

 - Request/Response 标签会显示我们发给 CRM 的请求,以及在下方会显示 CRM 返回的响应
 - 在下方的 Response Text 区域中我们可以看到联系人的名字是 “Joe Black“
 - Reponse Tree 标签中会显示 JSON 响应

 - 匹配上的值会加粗显示
 
为了执行联系人自动创建场景,我们需要使用一个 Freshdesk 中不存在的号码进行测试。在这种情况下,当在 CRM 侧找不到数据后软件会自动创建新联系人。
如果要测试 Call Journaling 功能,在 Parameter Values 节点中我们需要填写 Report Call 区域。然后右键 Parameter Values 选择 call report 即可。

9. 生成 XML 文件
- 在软件中点击 File > Save。并将文件重命名为 Freshdesk.xml
 - 在 3CX 管理控制台 > 设置 > CRM 集成 > 服务端集成 > 添加。将模板上传到 3CX。
 - 当有来电时,将在 CRM 中查询来电号码,如果匹配,则它将显示在3CX Web客户端中。
 
