<commit_before># Let's make a plugin!

> Another example on how to use Got like a boss :electric_plug:

Okay, so you already have learned some basics. That's great!

When it comes to advanced usage, custom instances are really helpful.
For example, take a look at [`gh-got`](https://github.com/sindresorhus/gh-got).
It looks pretty complicated, but... it's really not.

Before we start, we need to find the [GitHub API docs](https://developer.github.com/v3/).

Let's write down the most important information:
1. The root endpoint is `https://api.github.com/`.
2. We will use version 3 of the API.<br>
   The `Accept` header needs to be set to `application/vnd.github.v3+json`.
3. The body is in a JSON format.
4. We will use OAuth2 for authorization.
5. We may receive `400 Bad Request` or `422 Unprocessable Entity`.<br>
   The body contains detailed information about the error.
6. *Pagination?* Not yet. This is going to be a native feature of Got. We'll update this page accordingly when the feature is available.
7. Rate limiting. These headers are interesting:

- `X-RateLimit-Limit`
- `X-RateLimit-Remaining`
- `X-RateLimit-Reset`
- `X-GitHub-Request-Id`

Also `X-GitHub-Request-Id` may be useful.

8. User-Agent is required.

When we have all the necessary info, we can start mixing :cake:

### The root endpoint

Not much to do here, just extend an instance and provide the `baseUrl` option:

```js
const got = require('got');

const instance = got.extend({
	baseUrl: 'https://api.github.com'
});

module.exports = instance;
```

### v3 API

GitHub needs to know which version we are using. We'll use the `Accept` header for that:

```js
const got = require('got');

const instance = got.extend({
	baseUrl: 'https://api.github.com',
	headers: {
		accept: 'application/vnd.github.v3+json'
	}
});
```

### JSON body

We'll use [`options.responseType`](../readme.md#responsetype):

```js
const got = require('got');

const instance = got.extend({
	baseUrl: 'https://api.github.com',
	headers: {
		accept: 'application/vnd.github.v3+json'
	},
	responseType: 'json'
});

module.exports = instance;
```

### Authorization

It's common to set some environment variables, for example, `GITHUB_TOKEN`. You can modify the tokens in all your apps easily, right? Cool. What about... we want to provide a unique token for each app. Then we will need to create a new option - it will default to the environment variable, but you can easily override it.

Let's use handlers instead of hooks. This will make our code more readable: having `beforeRequest`, `beforeError` and `afterResponse` hooks for just a few lines of code would complicate things unnecessarily.

**Tip:** it's a good practice to use hooks when your plugin gets complicated. Try not to overload the handler function, but don't abuse hooks either.

```js
const got = require('got');

const instance = got.extend({
	baseUrl: 'https://api.github.com',
	headers: {
		accept: 'application/vnd.github.v3+json'
	},
	responseType: 'json',
	token: process.env.GITHUB_TOKEN,
	handlers: [
		(options, next) => {
			// Authorization
			if (options.token && !options.headers.authorization) {
				options.headers.authorization = `token ${options.token}`;
			}

			return next(options);
		}
	]
});

module.exports = instance;
```

### Errors<commit_msg>Update `Let's make a plugin!` guide<commit_after># Let's make a plugin!

> Another example on how to use Got like a boss :electric_plug:

Okay, so you already have learned some basics. That's great!

When it comes to advanced usage, custom instances are really helpful.
For example, take a look at [`gh-got`](https://github.com/sindresorhus/gh-got).
It looks pretty complicated, but... it's really not.

Before we start, we need to find the [GitHub API docs](https://developer.github.com/v3/).

Let's write down the most important information:
1. The root endpoint is `https://api.github.com/`.
2. We will use version 3 of the API.<br>
   The `Accept` header needs to be set to `application/vnd.github.v3+json`.
3. The body is in a JSON format.
4. We will use OAuth2 for authorization.
5. We may receive `400 Bad Request` or `422 Unprocessable Entity`.<br>
   The body contains detailed information about the error.
6. *Pagination?* Not yet. This is going to be a native feature of Got. We'll update this page accordingly when the feature is available.
7. Rate limiting. These headers are interesting:

- `X-RateLimit-Limit`
- `X-RateLimit-Remaining`
- `X-RateLimit-Reset`
- `X-GitHub-Request-Id`

Also `X-GitHub-Request-Id` may be useful.

8. User-Agent is required.

When we have all the necessary info, we can start mixing :cake:

### The root endpoint

Not much to do here, just extend an instance and provide the `prefixUrl` option:

```js
const got = require('got');

const instance = got.extend({
	prefixUrl: 'https://api.github.com'
});

module.exports = instance;
```

### v3 API

GitHub needs to know which version we are using. We'll use the `Accept` header for that:

```js
const got = require('got');

const instance = got.extend({
	prefixUrl: 'https://api.github.com',
	headers: {
		accept: 'application/vnd.github.v3+json'
	}
});

module.exports = instance;
```

### JSON body

We'll use [`options.responseType`](../readme.md#responsetype):

```js
const got = require('got');

const instance = got.extend({
	prefixUrl: 'https://api.github.com',
	headers: {
		accept: 'application/vnd.github.v3+json'
	},
	responseType: 'json'
});

module.exports = instance;
```

### Authorization

It's common to set some environment variables, for example, `GITHUB_TOKEN`. You can modify the tokens in all your apps easily, right? Cool. What about... we want to provide a unique token for each app. Then we will need to create a new option - it will default to the environment variable, but you can easily override it.

Let's use handlers instead of hooks. This will make our code more readable: having `beforeRequest`, `beforeError` and `afterResponse` hooks for just a few lines of code would complicate things unnecessarily.

**Tip:** it's a good practice to use hooks when your plugin gets complicated. Try not to overload the handler function, but don't abuse hooks either.

```js
const got = require('got');

const instance = got.extend({
	prefixUrl: 'https://api.github.com',
	headers: {
		accept: 'application/vnd.github.v3+json'
	},
	responseType: 'json',
	token: process.env.GITHUB_TOKEN,
	handlers: [
		(options, next) => {
			// Authorization
			if (options.token && !options.headers.authorization) {
				options.headers.authorization = `token ${options.token}`;
			}

			return next(options);
		}
	]
});

module.exports = instance;
```

### Errors
{'fraction_non_alphanumeric': 0.12267267267267268, 'fraction_numerical': 0.006606606606606606, 'mean_word_length': 4.027169811320754, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 14, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5610646', 'n_tokens_mistral': 2125, 'n_tokens_neox': 2007, 'n_words': 818}