DEV Community

MarsCode for MarsCode

Posted on • Updated on

User Story EP1 : How Alex Built His First GPT Action from Scratch๐ŸŽ‰

This article comes from User @ Alex Liu,big shoutout to ALEX for an incredible share! ๐ŸŒŸ
Calling all users to join in and share your stories too! ๐Ÿ“š
We have awesome gifts worth up to $200 waiting for those with amazing tales to tell! ๐ŸŽ

Recently, with some free time on my hands, I developed a cool GPT Action using MarsCode. It allows querying of information on popular GitHub projects. It's been quite enjoyable, so I thought I'd share my development process and insights.

(how it worksโ†‘)

About GPT Actions: You can think of them as handy little helpers powered by AI, capable of fetching all sorts of information for you. For more details, check out "Actions in GPTs."
Developing GPT actions may require an IDE, deployment platform, and API testing tools, among others. That's why I opted for MarsCode โ€“ it offers a one-stop solution, allowing me to quickly create a development project and streamline the development of GPT Actions.

Alright, let's take a look at my entire development process

Step1: Designing GPT Actions

This is where you get to brainstorm what you want your GPT to do. For mine, I wanted it to scour GitHub Trending for hot projects based on programming language and time frame. Here's what I came up with for inputs and outputs:

  • Inputs: the programming language to search for the time frame for the search (e.g., daily, weekly, monthly)
  • Outputs: Project list, including project name, author, link, star count, and recent star increments.

Step2: Setting Up the Project

MarsCode makes this part a breeze. With its variety of ready-to-use development frameworks and templates, I was spoilt for choice. Since I'm more comfortable with Node.js, I opted for the Node.js for AI Plugin template.

Image description

(Clicking on "Create," I swiftly entered the project spaceโ†‘)

Image description
(The overall layout of MarsCode is quite similar to VS Code, so there wasn't much of a learning curve for me, as someone accustomed to using VS Code. BTW, I have to mention its theme โ€“ I really like it! It's a pity it's not open-source.๐Ÿ˜„โ†‘)

Step3 Development

For anyone diving into this template for the first time, it's a smart move to give the README a thorough read. Since it's a template project, sticking to the presets is the way to go.

In this template, each function file needs to export a function called handler that conforms to the following TypeScript definition:

export async function handler({ input, logger }: Args<Input>): Promise<Output> {
  const name = input.name || 'world';

  logger.info(`user name is ${name}`);

  return {
    message: `hello ${name}`
  };
}
Enter fullscreen mode Exit fullscreen mode

When an HTTP request comes in, MarsCode executes this function and passes in input and logger. The logic for the action is written within the handler function, which provides several predefined TypeScript types:

  • Args: The arguments passed to MarsCode when executing the handler, including input and logger.
  • Input: The input of the HTTP request.
  • logger: This logs information, including methods like logger.info, logger.error, and logger.debug. These logs appear in the Runtime logs panel of the deployment dashboard and in the API Test's log panel.
  • Output: The output of the function.

After grasping all that, I jumped right into coding. I created github/searchTrending.ts under the api directory to fetch GitHub Trending data. Here's how I broke it down into 2 steps:

  1. Fetching GitHub Trending Page: I started by making a fetch request to https://github.com/trending to grab the page's HTML. Since MarsCode's Node.js version is v20.12.2, I could directly use fetch for network requests.
  2. Parsing HTML with cheerio: I had the HTML, I used cheerio to parse it and extract repo data like names, descriptions, and star counts.

Image description
(During the coding process, MarsCode AI Assistants were super helpful. They provided features like code auto-completion and generating code based on comments. The fields for the GitHubRepo interface were automatically inferred, making the whole process incredibly convenient. ๐Ÿ˜Žโ†‘)

Once the dependencies are installed, we can dive into writing the core logic of the plugin:

async function searchTrending(input: Input): Promise<GitHubRepo[]> {
  let url = 'https://github.com/trending';
  // You can filter by language and time period
  if (input.language) {
    url += `/${input.language}`;
  }
  if (input.since) {
    url += `?since=${input.since}`;
  }

  try {
    // Fetch the HTML from GitHub Trending.
    const response = await fetch(url);
    const body = await response.text();
    // Parse the HTML with cheerio to extract project information.
    const $ = cheerio.load(body);
    // Initialize the list for repository info.
    let repositoriesInfo = [];

    // Iterate over all <article class="Box-row"> elements on the page.
    $('article.Box-row').each(function () {
      const article = $(this);
      // Extract data.
      const name = article.find('h2.h3 a').text().trim();
      const url = 'https://github.com' + article.find('h2.h3 a').attr('href');
      const author = article.find('span.text-normal').text().trim().replace(' /', '');
      const stars = article.find('a[href*="/stargazers"]').last().text().trim().replace(/,/g, ''); // Remove commas from numbers.
      const todayStarsText = article.find('.d-inline-block.float-sm-right').text().trim();
      const todayStarsMatch = todayStarsText.match(/(\d+)/);
      const todayStars = todayStarsMatch ? parseInt(todayStarsMatch[0], 10) : 0;
      const language = article.find('[itemprop="programmingLanguage"]').text().trim();
      const description = article.find('p.color-fg-muted').text().trim();  Extract repo description

      repositoriesInfo.push({
        description,
        language,
        name,
        url,
        author,
        stars,
        todayStars
      });
    });

    return repositoriesInfo;
  } catch (error) {
    console.error('Error fetching data:', error);
  }
  return [];
}

Call the searchTrending function in the handler:
typescript
/**
 * Search the GitHub trending repos
 */
export async function handler({ input, logger }: Args<Input>): Promise<Output> {
  const projects = await searchTrending(input);

  return {
    projects,
  };
}
Enter fullscreen mode Exit fullscreen mode

Now that we've wrapped up the main coding part, we can move on to testing this action. ๐Ÿš€

Step4: API test

(MarsCode offers a testing tool: API Test. In the API Test panel, you can input the parameters for the interface. Click "Send," and you can check the logs through the Output panel. ๐Ÿ”โ†‘)

Step5: Deployment

(Click the "Deploy" button at the top, enter the Changelog, and then click "Start." Your project will begin deploying, and you can monitor the deployment process through the logs. ๐Ÿš€โ†‘)

(After a successful deployment, you can view the service details through Service Detail. This includes the OpenAPI Schema, Bearer token, domain name, and more.โ†‘)

Final Step

For details on how to add the action to your ChatGPT, there's a document from MarsCode team Add an action to your ChatGPT. I won't go into it here, but you can refer to that for a step-by-step guide. ๐Ÿ“„๐Ÿค–

Some of my ideas

Even though this was my first time developing a GPT Action, I found MarsCode's custom solution pretty impressive overall. The process was smooth with hardly any hiccups. Moving forward, I'm considering developing more AI Bots to cover various other scenarios. If anyone has ideas, feel free to join in and let's create something awesome together! ๐Ÿš€

FYI : https://github.com/L-mofeng/marscode-github-trending-action

Top comments (1)

Collapse
 
zhaoxudong90 profile image
zhaoxudong90

I am already a user of MarsCode, I think it is a great free alternative to Github Copilot and Replit.