Rick Roll Your Friends Using Appwrite, Twilio, and .NET

adityaoberai

Aditya Oberai

Posted on June 10, 2022

Rick Roll Your Friends Using Appwrite, Twilio, and .NET

Being the fun-loving guy and absolute geek that I am, I've always looked for ways to use tech to prank my friends 😏. I remember that first prank I did 11 years back, a little shortcut hidden behind an Internet Explorer icon that shut down my friend's Windows XP based PC and gave him a mini heart-attack πŸ˜†. My pranks have gotten "a little more sophisticated" since then, having graduated to rick rolling them via phone calls now! 🀣

Rick Roll GIF

The best part is that little prank is really easy to create, and I will show you how to create this prank using 3 of my favourite technologies, Appwrite, Twilio, and .NET today! πŸ˜„

πŸ“ƒ Table of Contents

πŸ“ Prerequisites

Before we get started, there are a couple of prerequisites. If you have the prerequisites set up already, you can skip to the following section.

In order to follow along, you’ll need a few things beforehand.

  • πŸ–₯ An Appwrite instance

If you haven’t set up an Appwrite instance yet, you can follow the getting started guides to get it up and running quickly. Feel free to choose between the One-Click installations on DigitalOcean or manual installations with Docker.

TL;DR: It just takes a single command to install Appwrite.

docker run -it --rm \
    --volume /var/run/docker.sock:/var/run/docker.sock \
    --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
    --entrypoint="install" \
    appwrite/appwrite:1.3.2
Enter fullscreen mode Exit fullscreen mode

Once your server is up and running, head over to the Appwrite Dashboard on your server’s public IP address ( or localhost if you installed locally ) and create a new admin user account.

Sign Up

In order to enable the .NET 6.0 runtime for Appwrite Cloud Functions, you need to update the .env file in the Appwrite installation folder. Enter the file and add dotnet-6.0 to the comma-separated list in the environment variable _APP_FUNCTIONS_RUNTIMES. This will make the .NET runtime available in Appwrite Functions. You can then load the updated configuration using the docker-compose up -d command.

  • πŸ§‘β€πŸ’» The Appwrite CLI

We’ll use the Appwrite CLI during this exercise as it makes the process super simple. If you have Node.js installed, the installation command is a simple

npm install -g appwrite-cli
Enter fullscreen mode Exit fullscreen mode

If npm is not your thing, we have numerous installation options you can find in the getting started guide for the CLI.

  • πŸ“± A Twilio Account and Phone Number

Sign up for a Twilio account if you don't have one already. Add a phone number to your account that has calling capabilities at the very minimum.

Twilio Console

ℹ️ The Twilio Account SID and Auth Token can be obtained from your Twilio console. You can purchase a Twilio phone number using this guide.

πŸ—οΈ Setting up Appwrite and Initializing Our Function

If you already know how to create a Cloud Function from the Appwrite CLI, please skip over to the next section.

In order to create an Appwrite Cloud Function, first we must login to the Appwrite CLI using the appwrite login command using the credentials we created when setting up the Appwrite instance.

appwrite login
? Enter your email test@test.com
? Enter your password ********
? Enter the endpoint of your Appwrite server http://localhost/v1
βœ“ Success
Enter fullscreen mode Exit fullscreen mode

Next up, we need to create a new Appwrite project (or link an existing one) to work with. This can be achieved via the appwrite init project command.

appwrite init project
? How would you like to start? Create a new Appwrite project
? What would you like to name your project? Project X
βœ“ Success
Enter fullscreen mode Exit fullscreen mode

You can give your project any name you'd like. As soon as you create or link a project, you should notice a new appwrite.json file in the current directory which stores all the information about your project.

Now that our CLI is all set up with our Appwrite project, let's initialize our function using the appwrite init function command.

appwrite init function
? What would you like to name your function? RickRoll
? What runtime would you like to use? .NET (dotnet-6.0)
βœ“ Success 
Enter fullscreen mode Exit fullscreen mode

Give your function a name (I've chosen RickRoll here for convenience) and choose the .NET 6.0 runtime. This will create a new Appwrite Function in your project and set up all the boilerplate code necessary. The function's files are available in the functions/RickRoll directory, which is where we'll be working.

If you don't feel comfortable creating Appwrite Cloud Functions with .NET, please make sure to check out our blog before moving onto the next step.

πŸ§‘β€πŸ’» Creating the Rick Roll Function

After initializing the RickRoll Function, please visit the functions/RickRoll directory. Our file structure here looks as follows.

RickRoll
β”œβ”€β”€ Function.csproj 
|
└── src
    └── Index.cs
Enter fullscreen mode Exit fullscreen mode

Enter src/Index.cs and replace the boilerplate with the following code.

using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Twilio;
using Twilio.Types;
using Twilio.Rest.Api.V2010.Account;

public async Task<RuntimeResponse> Main(RuntimeRequest req, RuntimeResponse res)
{
  // Convert payload from JSON string to Dictionary and get the phone number to call 
  var payload = JsonConvert.DeserializeObject<Dictionary<string, string>>(req.Payload);
  var toPhoneNumber = payload["phoneNumber"];

  // Get Twilio Account SID, Auth Token, and Phone Number from the Environment Variables
  var accountSID = req.Env["TWILIO_ACCOUNTSID"];
  var authToken = req.Env["TWILIO_AUTHTOKEN"];
  var twilioPhoneNumber = req.Env["TWILIO_PHONENUMBER"];

  //Initialize the Twilio SDK
  TwilioClient.Init(accountSID, authToken);

  // Create the phone call with the Twilio Voice API
  var call = CallResource.Create(
                to: new PhoneNumber(toPhoneNumber),
                from: new PhoneNumber(twilioPhoneNumber),
                twiml: new Twiml("<Response><Play>https://demo.twilio.com/docs/classic.mp3</Play></Response>") 
             );

  // Return the response from the Twilio SDK
  return res.Json(new()
  {
    { "twilioResponse", call }
  });
}
Enter fullscreen mode Exit fullscreen mode

Let’s go over the code we have here. From the Cloud Functions documentation, we see that the payload and environment variables are available through the request object. Here, we take the payload, which we receive as a JSON string, and convert it into a Dictionary. This is achieved using the Newtonsoft.Json library. We grab the phone number we want to call from the deserialized payload as well.

We then retrieve the Twilio Account SID, Twilio Auth Token, and our Twilio Phone Number from our environment variables and use the Twilio C# / .NET SDK to make a phone call with a very special audio πŸ˜‰.

Dancing to the music

In order to make sure that Appwrite installs the Newtonsoft.Json library and the Twilio SDK to our function, we must include them in the Function.csproj file.

<ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
    <PackageReference Include="Twilio" Version="5.75.2" />
</ItemGroup>
Enter fullscreen mode Exit fullscreen mode

Now that our function is ready, we can deploy it to our Appwrite instance using the appwrite deploy function command.

appwrite deploy function
? Which functions would you like to deploy? RickRoll (62a1a474b154de566308)
β„Ή Info Deploying function RickRoll ( 62a1a474b154de566308 )
β„Ή Info Ignoring files using configuration from appwrite.json
βœ“ Success Deployed RickRoll ( 62a1a474b154de566308 )
Enter fullscreen mode Exit fullscreen mode

The function should be visible within your Appwrite Instance here.

RickRoll Function

One last thing we must do before we can test the function is add the necessary environment variables to the Function's Settings page.

  • TWILIO_ACCOUNTSID: Twilio Account SID
  • TWILIO_AUTHTOKEN: Twilio Auth Token
  • TWILIO_PHONENUMBER: Twilio Phone Number to make the call from

RickRoll Environment Variables

Now our function is fully ready to test! πŸ₯³

😜 Testing the Rick Roll Cloud Function

Once the function is deployed, we can head over to the Appwrite console and execute the function with the payload in the following format.

{
    "phoneNumber": "+919876543210"
}
Enter fullscreen mode Exit fullscreen mode

Executing the function should lead to the phone number you entered receiving a call as shown.

We can also find the response from the Twilio SDK in the Function's Logs page.

{
    "twilioResponse": {
        "Sid": "CA83758d533c786be5bcf82e34b94cc8b5",
        "DateCreated": null,
        "DateUpdated": null,
        "ParentCallSid": null,
        "AccountSid": "ACe29c144db149972dbf5427bbdd0c16dd",
        "To": "\u002B919876543210",
        "ToFormatted": "\u002B919876543210",
        "From": "\u002B12184232045",
        "FromFormatted": "(218) 423-2045",
        "PhoneNumberSid": "PN671d012061f32085fcd63b046f23826f",
        "Status": {},
        "StartTime": null,
        "EndTime": null,
        "Duration": null,
        "Price": null,
        "PriceUnit": "USD",
        "Direction": "outbound-api",
        "AnsweredBy": null,
        "ApiVersion": "2010-04-01",
        "ForwardedFrom": null,
        "GroupSid": null,
        "CallerName": null,
        "QueueTime": "0",
        "TrunkSid": null,
        "Uri": "/2010-04-01/Accounts/ACe29c144db149972dbf5427bbdd0c16dd/Calls/CA83758d533c786be5bcf82e34b94cc8b5.json",
        "SubresourceUris": {
            "feedback": "/2010-04-01/Accounts/ACe29c144db149972dbf5427bbdd0c16dd/Calls/CA83758d533c786be5bcf82e34b94cc8b5/Feedback.json",
            "notifications": "/2010-04-01/Accounts/ACe29c144db149972dbf5427bbdd0c16dd/Calls/CA83758d533c786be5bcf82e34b94cc8b5/Notifications.json",
            "recordings": "/2010-04-01/Accounts/ACe29c144db149972dbf5427bbdd0c16dd/Calls/CA83758d533c786be5bcf82e34b94cc8b5/Recordings.json",
            "streams": "/2010-04-01/Accounts/ACe29c144db149972dbf5427bbdd0c16dd/Calls/CA83758d533c786be5bcf82e34b94cc8b5/Streams.json",
            "payments": "/2010-04-01/Accounts/ACe29c144db149972dbf5427bbdd0c16dd/Calls/CA83758d533c786be5bcf82e34b94cc8b5/Payments.json",
            "siprec": "/2010-04-01/Accounts/ACe29c144db149972dbf5427bbdd0c16dd/Calls/CA83758d533c786be5bcf82e34b94cc8b5/Siprec.json",
            "events": "/2010-04-01/Accounts/ACe29c144db149972dbf5427bbdd0c16dd/Calls/CA83758d533c786be5bcf82e34b94cc8b5/Events.json",
            "feedback_summaries": "/2010-04-01/Accounts/ACe29c144db149972dbf5427bbdd0c16dd/Calls/FeedbackSummary.json"
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

πŸ† Conclusion

And that brings us to the end folks! I sincerely hope you enjoyed yourself learning how you can leverage Appwrite Cloud Functions to build a fun little prank project. Feel free to visit the GitHub repo for this project (and give it a star 🌟 if you like it).

GitHub logo adityaoberai / RickRoll-AppwriteFunction

Appwrite Cloud Function that rick rolls a person on phone call via Twilio

πŸ“² Rick Roll Someone with Appwrite, Twilio, and .NET 6.0

πŸ€– Documentation

Appwrite Cloud Function that rick rolls a person on phone call via Twilio.

Example input:

This function expects a phone number in the payload in the following format: +[Country Code][Phone Number]

Here's an example JSON input:

{
    "phoneNumber": "+919876543210"
}
Enter fullscreen mode Exit fullscreen mode

Example output:

{
    "twilioResponse": {
        "Sid": "CA83758d533c786be5bcf82e34b94cc8b5"
        "DateCreated": null,
        "DateUpdated": null,
        "ParentCallSid": null,
        "AccountSid": "ACe29c144db149972dbf5427bbdd0c16dd",
        "To": "\u002B919876543210",
        "ToFormatted": "\u002B919876543210",
        "From": "\u002B12184232045",
        "FromFormatted": "(218) 423-2045",
        "PhoneNumberSid": "PN671d012061f32085fcd63b046f23826f",
        "Status": {},
        "StartTime": null,
        "EndTime": null,
        "Duration": null,
        "Price": null,
        "PriceUnit": "USD",
        "Direction": "outbound-api"
…
Enter fullscreen mode Exit fullscreen mode

In case you want to learn more about Appwrite Cloud Functions, feel free to visit the Functions Guide and feel free to visit the Appwrite Discord Server if you need any help.

Thanks a lot and hope you have a great day! ❀️

πŸ’– πŸ’ͺ πŸ™… 🚩
adityaoberai
Aditya Oberai

Posted on June 10, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related