コールトラッキング

最新のコールトラッキングソリューションを導入してキャンペーンの効果を測定し、コールを正確に分類し、発信者の感情を把握して営業チームが対話をパーソナライズできるようにします。

Customer calling to a company for a vacation plan while the call is being tracked to measure campaign effectiveness, accurately attribute the call, and help sales teams personalize interactions.

コールトラッキングの構築方法

既存のスタックと統合し、精度の高いコールトラッキングメトリックスの収集を開始します。

ステップ1
Twilioの電話番号を取得する
Twilioセルフサービスポータルまたは電話番号APIから電話番号プールを購入します。


ステップ2
電話番号をマッピングし、カウンターを実装する
電話番号をTwilio番号にマッピングし、着信をカウントするためのWebhookをセットアップします。


ステップ3
広告やWebサイトにTwilioの電話番号を掲載する
広告、Webサイト、ランディングページ、その他のコンテンツにTwilioの電話番号を追加します。


ステップ4
コールトラッキングを開始する
関心のある購買層がその番号に電話をかけると、コールトラッキングのメトリックスを収集し、キャンペーンの効果、ROI、顧客インサイトを把握することができます。

Diagram of how to build a call tracking system that is integrated with a customer existing stack to start collecting granular call tracking metrics.

Twilioを使用してコールトラッキングを構築するために必要なもの

年間500億分以上の音声通話を処理するプラットフォームに通話体験を構築します。

  • Twilio Programmable Voice logo
    Voice API

    TwilioのVoice APIを使用すると、通話体験をカスタマイズし、通話を効率的に転送し、パフォーマンスメトリックスを正確に追跡して、ROIに関する信頼性の高いインサイトを得ることができます。

  • Twilio Voice Insights logo
    Voice Insights

    通話量のピークを追跡することにより、人員を適宜配置し、通話パフォーマンスデータを監視して問題を迅速に発見、解決することができます。

  • 音声インテリジェンス

    着信から、コールサマリー、顧客感情、競合他社のインサイトなど、さらに多くのビジネスインテリジェンスを収集できます。 

  • Twilio Phone Numbers logo
    電話番号

    地域番号、国内番号、携帯電話番号、トールフリー番号など、200種類以上の電話番号からお好きな番号を選んでコールトラッキングを設定できます。

  • Twilio Task Router logo
    タスクルーター

    最適なスキルを持つオペレーターにコールを転送し、キャンペーンコールのトラフィックを最適なリソースにマッピングし、顧客体験を向上させます。

 Twilioコールトラッキングを始めましょう

Twilioアカウントにサインアップしてコールトラッキングを始めましょう。クイックスタートガイドを利用することにより、お好きなプログラミング言語を使用して始めることができます。

var twilio = require('twilio');
var config = require('../config');
var LeadSource = require('../models/LeadSource');

var client = twilio(config.apiKey, config.apiSecret, { accountSid: config.accountSid });

exports.create = function(request, response) {
  var phoneNumberToPurchase = request.body.phoneNumber;

  client.incomingPhoneNumbers.create({
    phoneNumber: phoneNumberToPurchase,
    voiceCallerIdLookup: 'true',
    voiceApplicationSid: config.appSid
  }).then(function(purchasedNumber) {
    var leadSource = new LeadSource({number: purchasedNumber.phoneNumber});
    return leadSource.save();
  }).then(function(savedLeadSource) {
    console.log('Saving lead source');
    response.redirect(303, '/lead-source/' + savedLeadSource._id + '/edit');
  }).catch(function(numberPurchaseFailure) {
    console.log('Could not purchase a number for lead source:');
    console.log(numberPurchaseFailure);
    response.status(500).send('Could not contact Twilio API');
  });
};

exports.edit = function(request, response) {
  var leadSourceId = request.params.id;
  LeadSource.findOne({_id: leadSourceId}).then(function(foundLeadSource) {
    return response.render('editLeadSource', {
      leadSourceId: foundLeadSource._id,
      leadSourcePhoneNumber: foundLeadSource.number,
      leadSourceForwardingNumber: foundLeadSource.forwardingNumber,
      leadSourceDescription: foundLeadSource.description,
      messages: request.flash('error')
    });
  }).catch(function() {
    return response.status(404).send('No such lead source');
  });
};

exports.update = function(request, response) {
  var leadSourceId = request.params.id;

  request.checkBody('description', 'Description cannot be empty').notEmpty();
  request.checkBody('forwardingNumber', 'Forwarding number cannot be empty')
    .notEmpty();

  if (request.validationErrors()) {
    request.flash('error', request.validationErrors());
    return response.redirect(303, '/lead-source/' + leadSourceId + '/edit');
  }

  LeadSource.findOne({_id: leadSourceId}).then(function(foundLeadSource) {
    foundLeadSource.description = request.body.description;
    foundLeadSource.forwardingNumber = request.body.forwardingNumber;

    return foundLeadSource.save();
  }).then(function(savedLeadSource) {
    return response.redirect(303, '/dashboard');
  }).catch(function(error) {
    return response.status(500).send('Could not save the lead source');
  });
};
using System.Net;
using System.Threading.Tasks;
using System.Web.Mvc;
using CallTracking.Web.Domain.Twilio;
using CallTracking.Web.Models;
using CallTracking.Web.Models.Repository;
using HttpStatusCodeResult = System.Web.Mvc.HttpStatusCodeResult;

namespace CallTracking.Web.Controllers
{
    public class LeadSourcesController : Controller
    {
        private readonly IRepository<LeadSource> _repository;
        private readonly IRestClient _restClient;

        public LeadSourcesController()
            : this(new LeadSourcesRepository(), new RestClient()) { }

        public LeadSourcesController(IRepository<LeadSource> repository, IRestClient restClient)
        {
            _repository = repository;
            _restClient = restClient;
        }

        // POST: LeadSources/Create
        [HttpPost]
        public async Task<ActionResult> Create(string phoneNumber)
        {
            var twiMLApplicationSid = Credentials.TwiMLApplicationSid ?? await _restClient.GetApplicationSidAsync();
            var twilioNumber = await _restClient.PurchasePhoneNumberAsync(phoneNumber, twiMLApplicationSid);

            var leadSource = new LeadSource
            {
                IncomingNumberNational = twilioNumber.FriendlyName,
                IncomingNumberInternational = twilioNumber.PhoneNumber?.ToString()
            };

            _repository.Create(leadSource);

            return RedirectToAction("Edit", new {id = leadSource.Id});
        }

        // GET: LeadSources/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var leadSource = _repository.Find(id.Value);
            if (leadSource == null)
            {
                return HttpNotFound();
            }

            return View(leadSource);
        }

        // POST: LeadSources/Edit/
        [HttpPost]
        public ActionResult Edit(
            [Bind(Include = "Id,Name,IncomingNumberNational,IncomingNumberInternational,ForwardingNumber")]
            LeadSource leadSource)
        {
            if (ModelState.IsValid)
            {
                _repository.Update(leadSource);
                return RedirectToAction("Index", new { Controller = "Dashboard" });
            }

            return View(leadSource);
        }
    }
}
class LeadSourcesController < ApplicationController
  before_filter :find_lead_source, only: [:edit, :update]

  def edit
  end

  def create
    phone_number = params[:format]
    twilio_number = TwilioClient.purchase_phone_number(phone_number)
    lead_source = LeadSource.create(name: '', incoming_number: twilio_number.friendly_name)

    message  = "Phone number #{twilio_number.friendly_name} has been purchased. Please add a name for this lead source"
    redirect_to edit_lead_source_path(lead_source), notice: message
  end

  def update
    if @lead_source.update_attributes(lead_sources_params)
      redirect_to root_url, notice: 'Lead source successfully updated.'
    end
  end

  private

  def find_lead_source
    @lead_source = LeadSource.find(params[:id])
  end

  def lead_sources_params
    params.require(:lead_source).permit(:name, :forwarding_number)
  end
end
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
from django.template.context_processors import csrf
from django.views.decorators.csrf import csrf_exempt
from django.views.generic.base import TemplateView
from django.views.generic.edit import UpdateView
from twilio.twiml.voice_response import VoiceResponse

from .forms import AreaCodeForm, PurchaseNumberForm
from .models import LeadSource, Lead
from .utils import search_phone_numbers, purchase_phone_number


# Home page view and JSON views to power the charts
def home(request):
    """Renders the home page"""
    context = {}

    # Add the area code form - default to 415
    context['form'] = AreaCodeForm({'area_code': '415'})

    # Add the list of lead sources
    context['lead_sources'] = LeadSource.objects.all()

    return render(request, 'index.html', context)


def leads_by_source(request):
    """Returns JSON data about the lead sources and how many leads they have"""
    # Invoke a LeadSource classmethod to get the data
    data = LeadSource.objects.get_leads_per_source()

    # Return it as JSON - use safe=False because we're sending a JSON array
    return JsonResponse(data, safe=False)


def leads_by_city(request):
    """Returns JSON data about the different cities leads come from"""
    # Invoke a Lead classmethod to get the data
    data = Lead.objects.get_leads_per_city()

    # Return it as JSON - use safe=False because we're sending a JSON array
    return JsonResponse(data, safe=False)


# Views for purchase number workflow
def list_numbers(request):
    """Uses the Twilio API to generate a list of available phone numbers"""
    form = AreaCodeForm(request.POST)

    if form.is_valid():
        # We received a valid area code - query the Twilio API
        area_code = form.cleaned_data['area_code']

        available_numbers = search_phone_numbers(area_code=area_code)

        # Check if there are no numbers available in this area code
        if not available_numbers:
            messages.error(
                request,
                'There are no Twilio numbers available for area code {0}. Search for numbers in a different area code.'.format(area_code))
            return redirect('home')

        context = {}
        context['available_numbers'] = available_numbers

        return render(request, 'call_tracking/list_numbers.html', context)
    else:
        # Our area code was invalid - flash a message and redirect back home
        bad_area_code = form.data['area_code']
        messages.error(request, '{0} is not a valid area code. Please search again.'
                       .format(bad_area_code))

        return redirect('home')


def purchase_number(request):
    """Purchases a new phone number using the Twilio API"""
    form = PurchaseNumberForm(request.POST)

    if form.is_valid():
        # Purchase the phone number
        phone_number = form.cleaned_data['phone_number']
        twilio_number = purchase_phone_number(phone_number.as_e164)

        # Save it in a new LeadSource object
        lead_source = LeadSource(incoming_number=twilio_number.phone_number)
        lead_source.save()

        messages.success(
            request,
            'Phone number {0} has been purchased. Please add a name for this lead source.'.format(
                twilio_number.friendly_name))

        # Redirect to edit lead page
        return redirect('edit_lead_source', pk=lead_source.pk)
    else:
        # In the unlikely event of an error, redirect to the home page
        bad_phone_number = form.data['phone_number']
        messages.error(request, '{0} is not a valid phone number. Please search again.'
                       .format(bad_phone_number))

        return redirect('home')


class LeadSourceUpdateView(SuccessMessageMixin, UpdateView):
    """Powers a form to edit Lead Sources"""

    model = LeadSource
    fields = ['name', 'forwarding_number']
    success_url = reverse_lazy('home')
    success_message = 'Lead source successfully updated.'


# View used by Twilio API to connect callers to the right forwarding
# number for that lead source
@csrf_exempt
def forward_call(request):
    """Connects an incoming call to the correct forwarding number"""
    # First look up the lead source
    source = LeadSource.objects.get(incoming_number=request.POST['Called'])

    # Create a lead entry for this call
    lead = Lead(
        source=source,
        phone_number=request.POST['Caller'],
        city=request.POST['CallerCity'],
        state=request.POST['CallerState'])
    lead.save()

    # Respond with some TwiML that connects the caller to the forwarding_number
    r = VoiceResponse()
    r.dial(source.forwarding_number.as_e164)

    return HttpResponse(r)
package com.twilio.calltracking.servlets.leadsources;

import com.twilio.calltracking.lib.Config;
import com.twilio.calltracking.lib.services.TwilioServices;
import com.twilio.calltracking.models.LeadSource;
import com.twilio.calltracking.repositories.LeadSourceRepository;
import com.twilio.calltracking.servlets.WebAppServlet;
import com.twilio.rest.api.v2010.account.incomingphonenumber.Local;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

public class CreateServlet extends WebAppServlet {

    private LeadSourceRepository leadSourceRepository;
    private TwilioServices twilioServices;

    @SuppressWarnings("unused")
    public CreateServlet() {
        this(new LeadSourceRepository(), new TwilioServices());
    }

    public CreateServlet(LeadSourceRepository leadSourceRepository, TwilioServices twilioServices) {
        this.leadSourceRepository = leadSourceRepository;
        this.twilioServices = twilioServices;
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String phoneNumber = request.getParameter("phoneNumber");

        String twimlApplicationSid = Config.getTwimlApplicationSid();
        if (Objects.equals(twimlApplicationSid, "") || (twimlApplicationSid == null)) {
            twimlApplicationSid = twilioServices.getApplicationSid();
        }

        Local twilioNumber = twilioServices.purchasePhoneNumber(phoneNumber, twimlApplicationSid);

        LeadSource leadSource = leadSourceRepository.create(new LeadSource(
                twilioNumber.getFriendlyName(),
                twilioNumber.getPhoneNumber().toString()));

        response.sendRedirect(String.format("/leadsources/edit?id=%s", leadSource.getId()));
    }
}
<?php

namespace App\Http\Controllers;

use App\Http\Requests;
use App\LeadSource;
use Illuminate\Http\Request;
use Twilio\Rest\Client;

class LeadSourceController extends Controller
{

    /**
     * Twilio Client
     */
    protected $_twilioClient;

    public function __construct(Client $twilioClient)
    {
        $this->_twilioClient = $twilioClient;
    }

    /**
     * Store a new lead source (i.e phone number) and redirect to edit
     * page
     *
     * @param  Request $request
     * @return Response
     */
    public function store(Request $request)
    {
        $appSid = $this->_appSid();

        $phoneNumber = $request->input('phoneNumber');

        $this->_twilioClient->incomingPhoneNumbers
            ->create(
                [
                    "phoneNumber" => $phoneNumber,
                    "voiceApplicationSid" => $appSid,
                    "voiceCallerIdLookup" => true
                ]
            );

        $leadSource = new LeadSource(
            [
                'number' => $phoneNumber
            ]
        );
        $leadSource->save();

        return redirect()->route('lead_source.edit', [$leadSource]);
    }

    /**
     * Show the form for editing a lead source
     *
     * @param  int $id
     * @return Response
     */
    public function edit($id)
    {
        $leadSourceToEdit = LeadSource::find($id);

        return response()->view(
            'lead_sources.edit',
            ['leadSource' => $leadSourceToEdit]
        );
    }

    /**
     * Update the lead source in storage.
     *
     * @param  Request $request
     * @param  int $id
     * @return Response
     */
    public function update(Request $request, $id)
    {
        $this->validate(
            $request,
            [
                'forwarding_number' => 'required',
                'description' => 'required'
            ]
        );

        $leadSourceToUpdate = LeadSource::find($id);
        $leadSourceToUpdate->fill($request->all());
        $leadSourceToUpdate->save();

        return redirect()->route('dashboard');
    }

    /**
     * Remove the lead source from storage and release the number
     *
     * @param  int $id
     * @return Response
     */
    public function destroy($id)
    {
        $leadSourceToDelete = LeadSource::find($id);
        $phoneToDelete = $this->_twilioClient->incomingPhoneNumbers
            ->read(
                [
                    "phoneNumber" => $leadSourceToDelete->number
                ]
            );

        if ($phoneToDelete) {
            $phoneToDelete[0]->delete();
        }
        $leadSourceToDelete->delete();

        return redirect()->route('dashboard');
    }

    /**
     * The Twilio TwiML App SID to use
     * @return string
     */
    private function _appSid()
    {
        $appSid = config('app.twilio')['TWILIO_APP_SID'];
        if (isset($appSid)) {
            return $appSid;
        }

        return $this->_findOrCreateCallTrackingApp();
    }

    private function _findOrCreateCallTrackingApp()
    {
        $existingApp = $this->_twilioClient->applications->read(
            array(
                "friendlyName" => 'Call tracking app'
            )
        );
        if ($existingApp) {
            return $existingApp[0]->sid;
        }

        $newApp = $this->_twilioClient->applications
            ->create('Call tracking app');

        return $newApp->sid;
    }
}

Node.jsとExpressによるコールトラッキング

Twilioを使用して電話番号を購入し、営業担当者に着信を転送し、各電話番号への通話データを表示する方法をご紹介します。

広告メトリックスを理解する

Twilioを使用してコールトラッキングを設定し、広告のパフォーマンスを追跡して把握するための手順をステップごとにご紹介します。

コールアノテーションにより新たなインサイトを発見する

コールアノテーションを使用し、キャンペーンから受信した音声通話について主観的なコンテキスト情報を取得する方法をご紹介します。

コードなしで進めたい?大丈夫です。

信頼できるTwilioパートナーの協力のもと、コーディングのサポートを受けたり、事前構築済みのソリューションを検討したりできます。

Work with Twilio Professional Services to set up global call tracking for your company

ビジネスコールトラッキングの構築にTwilioを使う理由

オフラインでもオンラインでも、マーケティングキャンペーンからのコールのトラッキングを開始するために必要なすべてが揃っています。

People reviewing call tracking metrics that are part of the Twilio advantages such as deep inventory of phone numbers, intelligent lead routing, custom reporting and analytics, and easy integration.

関連するユースケース


Twilioにより構築できるその他のユースケースをご覧ください。

マーケティングとプロモーション

メール、SMS、MMS、WhatsApp、またはVoiceを既存のマーケティング技術スタックに統合し、コンバージョンと顧客生涯価値を高めます。

インタラクティブ音声応答

オペレータ(有人)の介入を減らしながら、顧客が使いやすい最新のIVRを構築できます。

アラートと通知

重要なアカウント通知やアラートを、顧客が好むチャネルで、信頼性の高い方法を使用して大規模に配信します。