Build a Magic: The Gathering SMS price checker with Twilio and .NET CORE

May 02, 2017
Written by

Build a Magic: The Gathering SMS price checker with Twilio and .NET CORE

I have been a Magic: The Gathering player for many years now and during my travels I always enjoy partaking in local drafts.

Most Magic stores require the player to be a member in order to let them use their wifi. Because I usually only ever go to stores I don’t have a membership, I always have to rely on my flakey phone’s data to buy or trade cards when I don’t know their price.

I wish there was a way I could get card prices without having to rely on my phone’s internet. Let’s build an app to do just that using Twilio and .NET CORE.

You can download the source code here if you don’t want to go through all the steps. Or just try it out by texting a card name to:

UK: +44 1543 MAGIC5 ( +44 1543 624425)
US: +1 646-84MAGIC ( +1 (646) 846-2442)

Our tools

Creating a .NET CORE project

Open up your console application and create a new project by typing:

dotnet new mvc —framework netcoreapp1.1 —name MagicPricr
cd MagicPricr
dotnet add package twilio
dotnet restore

With that, you should end up with a new .NET MVC project called MagicPricr that has the Twilio .NET library installed to it. I’ve created mine under ~/Projects/CSharp.

Still in terminal give it a quick spin by running dotnet run and loading up http://localhost:5000 on your browser.


Great, the base of our application is built and now it’s time for us to start querying prices.

The Magic API

There are a number of Magic APIs out there, but most of them will not return prices. For this application we will be using an API called Scryfall which lets you search for card names and return information about them including their prices in USD, Euros and Tix.

So when we send our application a text with a card name it queries the api and with the results we can create a new SMS using TwiML and respond.

The API does not require authentication but has rate limits. For an example of what kind of data the API returns for a card search have a look at this JSON response.

We’re only interested in the pricing information so let’s create a model for this response that includes that information. In the root of your application, alongside the Controllers folder create a new directory called Models and inside of it a new class called Card.cs.

In that class file we will define two classes, one as the root object of the JSON response and one for the information we want about the card response.

using System.Collections.Generic;
public class RootObject
{
    public List<Card> data { get; set; }
}
public class Card
{
    public string id { get; set; }
    public string image_uri { get; set; }
    public string usd { get; set; }
    public string tix { get; set; }
    public string eur { get; set; }
}

As you can see, our field names match the ones returned by the JSON response which will make it much easier for us to deserialise it later on.

Open HomeController.cs and delete all the other routes leaving Index as this is all we’re going to need.

At the top of the class create a member variable called cardResponse. We will update the value of this variable with the response we want to send back to Twilio when an SMS comes in.

public class HomeController : Controller
{
    private string cardResponse;
    public async Task<IActionResult> Index(string body)
    {
        return View();
    }
}

We’re also changing the signature of the method so it becomes asynchronous. This is important because our API request will only return when the response is completed.

Let’s change the contents of that method to read what was passed in the body of the SMS message and open a new HttpClient connection. Make sure you resolve this dependency using System.Net.Http.

public async Task<IActionResult> Index(string body)
{
    var card = body;
    using (var client = new HttpClient())
    {
        
    }
}

Now that we have an HTTPClient instance we will make an HTTP request to the Scryfall API and if the response is successful, map it to our model class and deserialise it.

using (var client = new HttpClient())
{
    using(var response = await client.GetAsync($"https://api.scryfall.com/cards/search?q={card}"))
    {
        var messagingResponse = new MessagingResponse();
        if(response.IsSuccessStatusCode){
            var result = await response.Content.ReadAsStringAsync();
            var prices = JsonConvert.DeserializeObject<RootObject>(result).data[0];
            cardResponse = messagingResponse.Message($"The card {card} costs: n ${prices.usd} n €{prices.eur} n Tix {prices.tix}").ToString();                        
        }else{
            cardResponse = messagingResponse.Message($"The card {card} doesn't exist").ToString();                        
        }
        return Content(cardResponse, "text/xml");
        
    }
}

Notice we also respond to the message in case the API returns any status code that isn’t equal to “success”.

Stop the running application by pressing CTRL+C on the console and run it again with dotnet run.

Open up this URL on your browser and you should see that indeed your application now generates TwiML with the prices.

Let’s configure our number to use it so it responds when we text it.

Magic Prices hotline

My colleague Dominik wrote a blog post that shows you how to Deploy .NET Core with Docker and now.sh. I am running the application locally with ngrok and if you want to do that too just download ngrok and in a new console window run ngrok http 5000.


Once you have that running copy the URL you get from ngrok and go to your phone number in the Twilio dashboard. Change the “Messaging” webhook to point to your ngrok URL.


Text your number the name of a card and wait for it to give you prices back in three different currencies when available.

MagicPricr-small.gif

No data? No problem!

With only a few lines of code we’ve been able to build an application that interacts with an external API and give us up-to-date Magic the Gathering prices for cards we’re about to buy or trade.

There are other things we could add here such as the card description and picture and how much mana that card costs to put it in battle. The Scryfall API has all this information waiting to be used.

Hit me up on twitter @marcos_placona or send me an email on marcos@twilio.com if you add any new functionality to this app.