WriterAI: A Revolutionary AI Based Content Writing Tool

WriterAI: A Revolutionary AI Based Content Writing Tool

Easily write high quality emails, blogs and ebooks using this free and open source content writing tool :)

Jul 31, 2022Β·

10 min read

Play this article

About our Team 🀝

I am Ishant. I am a full stack web developer and an android app developer with over 6+ years of programming experience. I also enjoy designing logos, mockups and other UI related stuff using tools like Figma and Photoshop. Currently I am pursuing my Bachelors in Computer Science.

Vaibhav is an android app developer, a backend developer, and a UI designer. He has contributed to multiple open source projects. He is an expert in writing clean and scalable code. Currently, he is also pursuing his Bachelors in Computer Science.

Together, we have formed a team named Team 404 for this hackathon!

About WriterAI πŸ’₯

WhatsApp Image 2022-07-31 at 6.36.23 PM (1).jpeg

WriterAI is an AI-based content writing tool that can turn your unstructured text into engaging content and generate up to 5 different paragraphs with an input of just 5 words! Using the power of artificial intelligence, this tool helps you write an engaging piece of content and end up with something professional. You can use it for writing emails, blogs, articles, letters, thesis and even e-books! It is completely free to use and open-source :)

Story behind the idea, how and why πŸ˜ƒ

When I worked as a content writer, I often had to write over 5000 to 10000 words of blogs and articles for different clients within a span of few days. The stress of sitting for 7-8 hours on computer and trying to come up with new content ideas significantly affected my productivity and overall performance. Not only this, but after finishing any project, when me and vaibhav were to write the github project documentation, both of us always struggled with coming up with content that is professional, engaging and unique.

If you are from Hashnode community, you can also easily understand how hard it is to write content which engaging, user friendly and unique. A good quality content not only helps in increasing the user's engaging time but also helps in improving the overall website's SEO score.

Overwhelmed by this, we both together decided to create something that can automatically generate content for users and save their time and mental energy!

WriterAI πŸ”₯

WhatsApp Image 2022-07-31 at 6.36.23 PM.jpeg

WriterAI is an AI based content-writing tool that helps users easily write high quality content. One can also share their projects with others, work in teams, and have complete control over the final version. The platform has been built to assist people in meeting their writing needs by providing them with an "auto text-generation support" along with offering an inbuilt "markdown-supported text editor" to meet most of the authors' requirements.

Demo πŸ’»

Try out WriterAI by clicking on the link below:

writerai.netlify.app

Video Demonstration πŸ“Έ

Features βœ…

  • Auto Text Completion - Generates up to 120 words with an input of just 5 words
  • Inbuilt Text Editor - For writing your blogs, emails, letters, e-books and other stuff
  • Project Sharing - You can share your project with unlimited number of users and work in teams
  • Markdown Support - You can add images, tables, hyperlinks and code snippets in your projects by using markdown syntax
  • Project Download - You can download your projects in JSON, XML and Markdown formats
  • Platform Compatiblity - WriterAI is highly responsive and has been tested on the latest versions of Chrome, Safari and Opera Mini
  • User Authentication - Supports Email-Password authentication and Google Mail authentication
  • User Authorization - WriterAI keeps on validating the user's auth tokens every 5 minutes automatically in order to prevent any unauthorized access

Insights into the project πŸ““

2.png

WriterAI generates over 5 different paragraphs with an input of just 5 words! However, for best results, it is better to provide an input of 12 to 15 words :)

3.png

On WriterAI, you can share your projects with others by using their email address. As a result, multiple people can work together on one same project

4.png

Many times, you will need to add images, tables, hyperlinks and code snippets in your project. On WriterAI, you can do this easily by using the markdown syntax :)

5.png

If you ever wish to take a backup of your projects or publish them to other platforms like wordpress, you can easily export your projects in JSON, XML and Markdown formats!

Technical details πŸ’»

Slide 16_9 - 2 (1).jpg

WriterAI consists of a frontend and a backend. The frontend part is written using ReactJS where as the backend part is written using Ktor (A Kotlin framework for writing server side code). For storing data, we have used PlanetScale which is a highly scalable MySQL database platform. The frontend part is deployed on Netlify where as the backend is deployed on Linode.

Frontend

screen.jpg

  • WriterAI's frontend is created using CSS, ReactJS and MaterialUI
  • WriterAI is highly responsive on all popular devices like desktops, laptops, tablets and smartphones. This is achieved using CSS concepts like flexbox, grids, and media queries
  • To add interactive UI components like Dialog Boxes, Notifications and Side Menues, MaterialUI library has been used
  • To handle the states in ReactJS, ContextAPI is used
  • To communicate with OpenAI's GPT-3 model, its public API is used
  • To securely login and signup a user, Firebase's authentication service is used
  • All the React UI components are properly structured for easy understanding
  • Additionally, BEM naming convention is used while naming CSS clases so that other people can easily understand the code
  • WriterAI's frontend is deployed on Netlify which provides easy deployment process and fast website loading

Backend

Slide 16_9 - 1.jpg

  • WriterAI's backend is written in Ktor. Ktor is a kotlin based framework for writing server side code
  • WriterAI's backend implements Model View Controller (MVC) Architecture
  • It makes use of PlanetScale to store user's data in a SQL database. PlanetScale is a highly scalable MySQL database platform which supports horizontal sharding and unlimited connections
  • WriterAI's backend uses Jetbrain's Exposed library which is a SQL ORM which makes its easy to work with SQL databases
  • The backend makes use of firebase authentication tokens to securely authenticate user's requests
  • WriterAI's backend also makes use of Coroutines to perform asynchronous request and response handling
  • WriterAI's backend is deployed on Linode which is a popular cloud hosting service provider
  • A custom domain is also used for backend communication. SSL certificate is also enabled in order to safeguard any sensitive data that is sent during the communication between frontend and backend

How we made this tool πŸ”¨

WhatsApp Image 2022-07-31 at 6.36.42 PM.jpeg

The development of WriterAI can be divided into 5 phases:

Planning Phase

  • We made a list of all the features we want, the tech stacks and APIs we will be needing
  • We then prepared a UI prototype of WriterAI in Figma

Backend Development Phase

db_tables.jpeg

  • Here we first explored the PlanetScale documentation, and figured out how to connect it to our backend
  • After this, we wrote the APIs for saving a user, creating, updating, deleting and sharing of project and other necessary operations using ktor while connecting our backend with PlanetScale and then ran the server code on localhost using Intellij IDEA IDE
  • Once our backend server started running successfully, we tested all our APIs using Postman

Frontend Design Phase

  • Here we designed the front end of web pages. We used ReactJS as it lets programmers reuse the UI components
  • Then we made all the web pages responsive
  • Then we implemented Firebase authentication in our project and connected the React app with Ktor server

Frontend Development Phase

frontend_ai.jpg

  • Once we wrote the design code for all web pages, we now were supposed to implement the auto text generation feature in our app. For this, we made use of GPT-3 AI model which is the most powerful text generation model in world as of 2022 with an unprecedented size of 2048-token-long context and 175 billion parameters.
  • Then we eventually implemented all the backend server API calls in javascript using Axios.
  • Once CRUD operations and sharing of project was successfully done, we then wrote code for dowloading the project. For this, we took the data stored in PlanetScale's database and converted it into a javascript Blob object and triggered the download action for it.

Deployment Phase

linode.png

  • In this, we first deployed the frontend react app on netlify
  • For backend, we created an account on Linode, there we created an ubuntu server and installed all the important tools like java, nginx, ufw and certbot
  • We then bought a custom domain, connected it with linode and enabled HTTPS to secure the traffic
  • Finally, we configured NGINX to respond to HTTPS requests and forward them to our Ktor server's port. Then we uploaded the backend's executable jar file on linode using linux's scp tool and executed it
  • Then we finally tested WriterAI on different browsers like Chrome, Safari and Opera Mini and fixed all the bugs that were discovered

Challenges we faced and how we solved them πŸ‘¨β€πŸš€

  • In the backend part, the biggest challenge we faced was the CORS error. Although we initially had configured CORS in Ktor, still our API requests were getting rejected by server. After going through countless stackoverflow questions, luckily we were able to make relevant changes in our Ktor code, NGINX setup and Netlify .toml file and resolve the CORS issue

  • The biggest challenge we faced in the frontend part was to make the website responsive. Since WriterAI consists of many different tabs and split screens, and also since it is quite difficult to customise the MaterialUI components, we had to make use of extensive media queries and write most of the code from scratch to come up with a flexible and responsive website design

Code Snippets πŸ’»

This is how we create a route in Ktor

fun Route.getProject(controller: ProjectController) = get("/getProject") {
    val userId = call.principal<FirebaseUserPrincipal>()?.uid
    val projectId = call.request.queryParameters["projectId"]?.toIntOrNull()
    controller.getProject(userId, projectId).also {
        call.respond(it.httpStatusCode, it.serialize())
    }
}

This is how we handle the business logic of this route

suspend fun getProject(userId: String?, projectId: Int?) = when {
    userId.isNullOrEmpty() -> Response.Error(USER_ID_EMPTY)
    projectId == null -> repo.getAllProjects(userId)
    else -> repo.getProject(userId, projectId)
}

This is how we get the data according to the request

suspend fun getAllProjects(userId: String): Response<List<ProjectResponse>> = safeCall {
    val projectResponse = mergeProjectWithSharedTo(
        dataSource.getAllProjectsOfUser(userId),
        sharedToDataSource.getSharedByMe(userId)
    )
    Response.Success(projectResponse, "All projects fetched successfully")
}

This is how we make the Database Call to PlanetScale to get the data

override suspend fun getAllProjectsOfUser(userId: String): List<Project> = newSuspendedTransaction {
    Project.find {
        ProjectTable.userId eq userId
    }.toList().sortedByDescending { it.timeStamp }
}

This is how we implement the AI text generation in frontend


 const generateAiContent = async () => {
    // If AI is fetching data, prevent from making repeated API calls
    if (loadingAiContent) {
      return;
    }
    // Store the input field text in a variable
    const inputText = aiInput;
    // Validate the input data for null value and minimum words
    if (!inputText) {
      notify("Input text cannot be empty");
      return;
    }
    if (inputText.split(" ").length < 5) {
      notify("Input text should contain atleast five words");
      return;
    }
    // Show loading progress bar
    setLoadingAiContent(true);
    // Initialize the AI configuration variable
    const configuration = new Configuration({
      apiKey: process.env.REACT_APP_AI_API_KEY,
    });
    // Create the AI Instance
    const openai = new OpenAIApi(configuration);

    try {
      // Get data from AI and store it in respective state variables
      const response = await openai.createCompletion({
        model: "text-davinci-002",
        prompt: inputText,
        max_tokens: 40,
        temperature: 0.9,
        n: 5,
        echo: true,
      });

      const content = response.data.choices;
      setGeneratedAiContent(content);
      //console.log("Content: ", response.data.choices);
      setLoadingAiContent(false);
      updateUserAPICount();
    } catch (e) {
      //console.log(e);
      notify(
        "Unable to generate AI content, it seems your credits have crossed the daily usage limit",
        "error"
      );
      setLoadingAiContent(false);
    }
  };

This is how we implemented the security interval check functionality

 // Refresh Auth Token Every 10 Minutes
  useEffect(() => {
    const interval = setInterval(async () => {
      if (token) {
        const newToken = await getUserToken();
        localStorage.setItem("userInfo", JSON.stringify(newToken));
        setToken(newToken);
      }
    }, 10 * 60 * 1000);

    return () => clearInterval(interval);
  }, [token]);

  const [shouldLogout, setShouldLogout] = useState(false);

  // Check for token validity every 5 minutes
  useEffect(() => {
    const interval = setInterval(async () => {
      if (token) {
        const result = await checkUserValidity(token);
        if (result === false) {
          notify("You have been logged out due to token expiration", "error");
          setShouldLogout(true);
        }
      }
    }, 5 * 60 * 1000);

    return () => clearInterval(interval);
  }, [token]);

Source Code

If you want to have a look at the complete source code of WriterAI, here are the links to the Github Repositories:

Team Members

Vote of thanks πŸ‘

We would like to thank PlanetScale for providing such an awesome platform for horizontally scaling SQL databases. Special thanks to the members of Hashnode discord server for providing such a good support.

Β