DEV Community

Cover image for Rick Roll Your Friends Using Appwrite, Twilio, and .NET
Aditya Oberai
Aditya Oberai

Posted on • Edited on

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! โค๏ธ

Top comments (5)

Collapse
 
lunada profile image
Lukasz Nadarzynski • Edited

cool idea, a friend of mine also did a project with Twilio but instead of rick rolling he made a quiz game.
So basically receiver of the call would hear the question and if he answered correctly price in some crypto would be sent.
Here is the link if you want to know more: tinyurl.com/crypto-quizz

Appwrite project looks really cool, I will definitely give it a try.
In the past firebase was my go to approach for quick prototypes, but I am seeing more and more issues using that in long term.

Collapse
 
tr11 profile image
Tiago Rangel
  1. Click tinyurl.com/crypto-quizz
  2. Silence...
Never gonna give you up
Never gonna let you down
Never gonna run around and desert you
Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you
Enter fullscreen mode Exit fullscreen mode
Collapse
 
adityaoberai profile image
Aditya Oberai

That sounds pretty cool! ๐Ÿคฉ
Will check it out ๐Ÿ™Œ

Collapse
 
tony199555 profile image
Tony Yu

Wow, crazy!

Am I getting rick rolled by reading this article, lol.

Collapse
 
adityaoberai profile image
Aditya Oberai

Oh, yes! ๐Ÿ˜†

Thank you for the read ๐Ÿ˜„