Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build-and-test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x, 20.x, 22.x, 24.x]
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run validation
run: npm run validate
- name: Build project
run: npm run build
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ $RECYCLE.BIN/
/dist
.clasp.json
.clasp.json.bk
appsscript.json
node_modules
private.[gj]s
IMPROVEMENTS.md
12 changes: 11 additions & 1 deletion GEMINI.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,14 @@ This is a Google Apps Script project for cleaning old emails in Gmail based on r
2. **Testing**: This project uses [Jest](https://jestjs.io/) for automated testing. Run `npm test` to execute the test suite.
3. **Code Style**: The project is configured with ESLint and Prettier for code quality and consistent formatting. Run `npm run lint` to check for any linting issues. Please adhere to the existing code style.
4. **TypeScript Migration**: The project is a good candidate for migration to TypeScript for improved type safety. If significant changes are made, consider proposing this migration.
5. **Commit Messages**: Use the GitMoji convention for commit messages (e.g., `✨ feat: ...`, `🐛 fix: ...`).
5. **Commit Messages**: Follow the GitMoji convention for commit messages. The format is `emoji type(scope): subject`. For a complete list of emojis and their meanings, refer to the [GitMoji website](https://gitmoji.dev).
- Use lowercase for the subject line (after the colon).
- **CI/Build System (`ci`, `chore`):**
- Use `👷` for adding or updating the CI build system (e.g., GitHub Actions).
- Use `🔧` for configuration file changes.
- Use `🔨` for development script updates.
- Example: `👷 ci: add new workflow`
- Example: `🔧 chore(eslint): update eslint config`
- **Documentation (`docs`):**
- Use `📝` for adding or updating documentation.
- Example: `📝 docs(readme): update installation instructions`
117 changes: 3 additions & 114 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,127 +12,16 @@ This is a Google Apps Script project that helps you delete old emails in Gmail t

## How to use

1. Create a new Google Apps Script project in Google Drive.
2. Copy and paste the code from `src/code.js` and `src/examples.js` into the script editor.
3. From the `examples.js` file, choose a function that matches your needs, or create a new one. You can then run this function from the Apps Script editor.

For example, to run one of the pre-made functions, you would select it in the editor's function list and click **Run**.

The `main` function, which does the core work, has been updated to be more flexible. Here is how you would call it inside a custom function:

```js
function removeOldGoogleAlerts() {
const query = 'from:(Google Alerts <[email protected]>)';
const regex = /[0-9]{1,2} (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/m;

// Call main with an options object for configuration
main(query, regex, {
tresholdInDays: 90, // Optional: default is 60
isDryRun: true, // Optional: default is true
mode: 'html', // Optional: default is 'plain'
dateFormatter: (textWithDate, lastMessageDate) => {
/*
Your code to extract and format the date part to a date string
that can be parsed by the Date constructor.
*/
// This is just an example, a real implementation is needed here.
return new Date().toISOString();
}
});
}
```

> [!NOTE]
> **`query`**: A string that specifies the search criteria for the emails you want to delete. It should follow the same syntax as the Gmail search box. For example, `from:(Google Alerts <[email protected]>)` will match all emails from Google Alerts. You can find more examples and tips on how to use the Gmail search operators [here](https://developers.google.com/codelabs/apps-script-fundamentals-1).
>
> **`regex`**: A regular expression that matches the date part of the email subject or body. It should be enclosed in slashes and follow the JavaScript regex syntax. For example, `/[0-9]{1,2} (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/m` will match a date like “8 Feb” or “23 Nov” in the email.
>
> The third parameter to `main` is now an **options object** with the following optional properties:
>
> - **`tresholdInDays`**: The number of days to keep emails. Defaults to `60`.
> - **`isDryRun`**: A boolean value that indicates whether to run the script in test mode or not. If `true` (the default), the script will only log the emails that match the query and the regex, but will not delete them. If `false`, the script will delete the emails permanently. It is recommended to run the script with `isDryRun` set to `true` first to make sure it works as expected.
> - **`mode`**: A string that specifies whether to process the email body as plain text or HTML. Can be either `'plain'` (default) or `'html'`. If set to `'html'`, the script will strip all HTML tags from the email body before searching for the regex pattern.
> - **`dateFormatter`**: A function that takes two parameters: `textWithDate` and `lastMessageDate`. The `textWithDate` is a string that contains the date part extracted from the email body. The `lastMessageDate` is a date object that represents the latest date of the email thread. The function should return a date string like `yyyy-MM-dd` that can be parsed by `new Date()`.

4. Save and run the desired function from the script editor. You can use the **Run** menu or the **Run** button in the toolbar.

> [!IMPORTANT]
> When running the script for the first time, you may need to authorize it to access your Gmail account.

5. Optionally, set up a trigger to run a function periodically. You can do this by clicking the **Triggers** icon in the left sidebar, then clicking the **Add a trigger** button, and choosing the options you want. For example, you can set the script to run every day, week, or month.

> [!WARNING]
> This script will delete your emails permanently, without moving them to the trash. Please use it with caution and make sure you have a backup of your important emails. You can run the script with the `isDryRun` option set to `true` first to see what emails will be deleted.
For detailed instructions on how to set up and use this script, please see the [**Usage Guide**](./docs/usage.md).

## Development

This project uses [ESLint](https://eslint.org/) for code linting and [Prettier](https://prettier.io/) for code formatting. It is recommended to run the linter before committing any changes.

To run the linter, use the following command:

```bash
npm run lint
```

This project uses [Jest](https://jestjs.io/) for automated testing.

To run the tests, use the following command:

```bash
npm test
```

### Build Process

This project uses [Rollup](https://rollupjs.org/) to bundle the source files from `src/` into the `dist/` directory, which is ready for deployment with `@google/clasp`.

To build the project, run:

```bash
npm run build
```

This command bundles `src/code.js` and processes `src/examples.js` into the `dist/` directory. It also removes a Node.js-specific code block from `code.js` that is used for testing with Jest.

#### Excluding Example Functions

You can prevent specific functions from `src/examples.js` from being included in the final `dist/examples.js` file. This is useful if you only need a subset of the example functions for your deployment.

To exclude functions, add their names to the `config.examples.exclude` array in your `package.json` file:

```json
{
"name": "gmail-regex-cleaner-apps-script",
"version": "1.0.0",
// ...
"config": {
"examples": {
"exclude": [
"removeAffiliatesOne",
"removeCorelAffiliateInfo"
]
}
},
// ...
}
```

When you run `npm run build`, the functions listed in the `exclude` array will be omitted from the output.

#### Timezone Update

Optionally, you can update the timezone in the `dist/appsscript.json` manifest to match your local machine's timezone. This is useful to ensure that scheduled triggers run at the correct time.

To update the timezone, run the following command **after** the build command:

```bash
npm run update-timezone
```
This project uses ESLint for linting, Prettier for formatting, Jest for testing, and Rollup for building. For more details on the development setup and build process, please see the [**Development Guide**](./docs/development.md).

## Disclaimer

This script is provided as is, without any warranty or liability. Use it at your own risk. Make sure to test the script before using it on your Gmail account. The script may delete emails that you want to keep, or fail to delete emails that you want to remove. The script may also exceed the quota limits of Google Apps Script or Gmail API, resulting in errors or partial execution. The author is not responsible for any loss or damage caused by the use of this script.

## License

This project is distributed under the AGPL-3.0 license. You can use, modify, and distribute this project, as long as you comply with the terms and conditions in the [LICENSE](/LICENSE) file.
This project is distributed under the AGPL-3.0 license. You can use, modify, and distribute this project, as long as you comply with the terms and conditions in the [LICENSE](/LICENSE) file.
64 changes: 64 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Development

This project uses [ESLint](https://eslint.org/) for code linting and [Prettier](https://prettier.io/) for code formatting. It is recommended to run the linter before committing any changes.

To run the linter, use the following command:

```bash
npm run lint
```

This project uses [Jest](https://jestjs.io/) for automated testing.

To run the tests, use the following command:

```bash
npm test
```

## Build Process

This project uses [Rollup](https://rollupjs.org/) to bundle the source files from `src/` into the `dist/` directory, which is ready for deployment with `@google/clasp`.

To build the project, run:

```bash
npm run build
```

This command bundles `src/code.js` and processes `src/examples.js` into the `dist/` directory. It also removes a Node.js-specific code block from `code.js` that is used for testing with Jest.

### Excluding Example Functions

You can prevent specific functions from `src/examples.js` from being included in the final `dist/examples.js` file. This is useful if you only need a subset of the example functions for your deployment.

To exclude functions, add their names to the `config.examples.exclude` array in your `package.json` file:

```json
{
"name": "gmail-regex-cleaner-apps-script",
"version": "1.0.0",
// ...
"config": {
"examples": {
"exclude": [
"removeAffiliatesOne",
"removeCorelAffiliateInfo"
]
}
},
// ...
}
```

When you run `npm run build`, the functions listed in the `exclude` array will be omitted from the output.

### Timezone Update

Optionally, you can update the timezone in the `dist/appsscript.json` manifest to match your local machine's timezone. This is useful to ensure that scheduled triggers run at the correct time.

To update the timezone, run the following command **after** the build command:

```bash
npm run update-timezone
```
53 changes: 53 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# How to Use

1. Create a new Google Apps Script project in Google Drive.
2. Copy and paste the code from `dist/code.js` and `dist/examples.js` into the script editor.
3. From the `examples.js` file, choose a function that matches your needs, or create a new one. You can then run this function from the Apps Script editor.

For example, to run one of the pre-made functions, you would select it in the editor's function list and click **Run**.

The `main` function, which does the core work, has been updated to be more flexible. Here is how you would call it inside a custom function:

```js
function removeOldGoogleAlerts() {
const query = 'from:(Google Alerts <[email protected]>)';
const regex = /[0-9]{1,2} (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/m;

// Call main with an options object for configuration
main(query, regex, {
tresholdInDays: 90, // Optional: default is 60
isDryRun: true, // Optional: default is true
mode: 'html', // Optional: default is 'plain'
dateFormatter: (textWithDate, lastMessageDate) => {
/*
Your code to extract and format the date part to a date string
that can be parsed by the Date constructor.
*/
// This is just an example, a real implementation is needed here.
return new Date().toISOString();
}
});
}
```

> [!NOTE]
> **`query`**: A string that specifies the search criteria for the emails you want to delete. It should follow the same syntax as the Gmail search box. For example, `from:(Google Alerts <[email protected]>)` will match all emails from Google Alerts. You can find more examples and tips on how to use the Gmail search operators [here](https://developers.google.com/codelabs/apps-script-fundamentals-1).
>
> **`regex`**: A regular expression that matches the date part of the email subject or body. It should be enclosed in slashes and follow the JavaScript regex syntax. For example, `/[0-9]{1,2} (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/m` will match a date like “8 Feb” or “23 Nov” in the email.
>
> The third parameter to `main` is now an **options object** with the following optional properties:
>
> - **`tresholdInDays`**: The number of days to keep emails. Defaults to `60`.
> - **`isDryRun`**: A boolean value that indicates whether to run the script in test mode or not. If `true` (the default), the script will only log the emails that match the query and the regex, but will not delete them. If `false`, the script will delete the emails permanently. It is recommended to run the script with `isDryRun` set to `true` first to make sure it works as expected.
> - **`mode`**: A string that specifies whether to process the email body as plain text or HTML. Can be either `'plain'` (default) or `'html'`. If set to `'html'`, the script will strip all HTML tags from the email body before searching for the regex pattern.
> - **`dateFormatter`**: A function that takes two parameters: `textWithDate` and `lastMessageDate`. The `textWithDate` is a string that contains the date part extracted from the email body. The `lastMessageDate` is a date object that represents the latest date of the email thread. The function should return a date string like `yyyy-MM-dd` that can be parsed by `new Date()`.

4. Save and run the desired function from the script editor. You can use the **Run** menu or the **Run** button in the toolbar.

> [!IMPORTANT]
> When running the script for the first time, you may need to authorize it to access your Gmail account.

5. Optionally, set up a trigger to run a function periodically. You can do this by clicking the **Triggers** icon in the left sidebar, then clicking the **Add a trigger** button, and choosing the options you want. For example, you can set the script to run every day, week, or month.

> [!WARNING]
> This script will delete your emails permanently, without moving them to the trash. Please use it with caution and make sure you have a backup of your important emails. You can run the script with the `isDryRun` option set to `true` first to see what emails will be deleted.
Loading