Skip to content

Instantly share code, notes, and snippets.

@acamino
Created August 25, 2016 17:13
Show Gist options
  • Save acamino/44acf4413c770763de144d692f7b78b7 to your computer and use it in GitHub Desktop.
Save acamino/44acf4413c770763de144d692f7b78b7 to your computer and use it in GitHub Desktop.
Blog: Build a Simple Phone Verification System with Twilio Voice, C#, SQL Server, and jQuery
$(document).ready(function () {
$("#enter_number").submit(function (e) {
e.preventDefault();
initiateCall();
});
});
function initiateCall() {
$.post("call/create", { phoneNumber: $("#phone_number").val() },
function (data) { showCodeForm(data.verificationCode); }, "json");
checkStatus();
}
function showCodeForm(code) {
$("#verification_code").text(code);
$("#verify_code").fadeIn();
$("#enter_number").fadeOut();
}
function checkStatus() {
$.post("call/status", { phoneNumber: $("#phone_number").val() },
function (data) { updateStatus(data.status); }, "json");
}
function updateStatus(current) {
if (current === "unverified") {
$("#status").append(".");
setTimeout(checkStatus, 3000);
}
else {
success();
}
}
function success() {
$("#status").text("Verified!");
}
// POST: Call/Create
[HttpPost]
public async Task<JsonResult> Create(string phoneNumber)
{
// Delete a phone number.
await _service.DeleteByPhoneNumberAsync(phoneNumber);
// Create a phone number.
var verificationCode = GenerateVerificationCode();
await _service.CreateAsync(
new Number
{
PhoneNumber = phoneNumber,
VerificationCode = verificationCode,
Verified = false
});
// Make the phone call.
var client = new TwilioRestClient(TwilioAccountSID, TwilioAuthToken);
var call = client.InitiateOutboundCall(new CallOptions
{
From = TwilioNumber, // The phone number you wish to dial.
To = phoneNumber,
Url = $"{BaseUrl}/call/twiml" // The URL of call/twiml on your server.
});
if (call.RestException != null)
{
// If there is an exception, fail loudly.
throw new TwilioRestException(call.RestException);
}
return Json(new {verificationCode});
}
// POST: Call/Status
[HttpPost]
public async Task<JsonResult> Status(string phoneNumber)
{
var number = await _service.FindByPhoneNumberAsync(phoneNumber);
var status = number.Verified ? "verified" : "unverified";
return Json(new {status});
}
[HttpPost]
public async Task<ActionResult> Twiml(string digits, string called)
{
var response = new TwilioResponse();
if (string.IsNullOrEmpty(digits))
{
response
.BeginGather(new {numDigits = 6, timeOut = 10})
.Say("Please enter your verification.")
.EndGather();
}
else
{
var number = await _service.FindByPhoneNumberAsync(called);
if (digits.Equals(number.VerificationCode))
{
number.Verified = true;
await _service.UpdateAsync(number);
response.Say("Thank you! Your phone number has been verified.");
}
else
{
response
.BeginGather(new {numDigits = 6, timeOut = 10})
.Say("Verification code incorrect, please try again.")
.EndGather();
}
}
return TwiML(response);
}
<form id="enter_number">
<div class="form-group">
<label for="phone_number">Enter your phone number</label>
<input type="text" class="form-control" name="phone_number" id="phone_number" />
</div>
<button type="submit" name="submit" class="btn btn-default">Verify</button>
</form>
<div id="verify_code" style="display: none;">
<p>
Calling you now. <br />
When prompted, enter the verification code:
</p>
<h1 id="verification_code"></h1>
<p><strong id="status">Waiting...</strong></p>
</div>
namespace PhoneVerification.Web.Models
{
public class Number
{
public int Id { get; set; }
public string PhoneNumber { get; set; }
public string VerificationCode { get; set; }
public bool Verified { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment