Forgot where I saved my AWS S3 files so I wrote this File Watcher Program
Tags: aws, s3, cloudfront, javascript
Published: 2023-09-15 12:48:14

It is a File Watcher that watches my local S3 repository for changes. When any file is changed my AWS S3 Bucket file is updated magically with the below code. A simple NodeJS script, just save as myfile.js, open CMD prompt and enter node myfile.js to run. Read my story below.

Note: I have not yet found a tutorial that includes it all correctly. Hint, its all about pre setting content-type.

Most may use Github as their website repository but for aws S3 any old local folder will do. An inconvenience of hosting on s3 is u can't edit your html files right in the bucket. So after a few months of no edits, suddenly, where did I save my files and most importantly is this folder my most current version? more below...

```js
const AWS = require('aws-sdk'); //add these 2 dependencies
const fs = require('fs');
   
var file_name;
  //next line polls the origin folder while program is open
 const WATCH_TARGET = 'C:/Users/rickd/Downloads/backup 6-4-23/howtolearnjava.com/other/';
    fs.watch(WATCH_TARGET, (eventType, filename) => {
console.log('File "' + filename + '" was changed: ' + eventType);
  file_name = filename;

if (eventType == 'change') {
    // a file change occurred
    //get aws user credentials
const s3 = new AWS.S3({
  accessKeyId: 'xxxxxxxxxxxxxxxxxxxxxxxxx',
  secretAccessKey: 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'
});

const bucketName = 'howtolearnjava.com';//need to define this here
const fileName2 = file_name;  //must be defined here
   // this is the origin file that we are changing
const origin_file = 'C:/Users/rickd/Downloads/backup 6-4-23/howtolearnjava.com/other/'+fileName2;
//needs full path otherwise no such file or dir shows as error                                                                                                                                                                                                         //no fancy concat anymore...dont put syntax in the path
//******very important..this program will not overwrite s3 file
 //if content type is absent (in cf and perhaps always)
    //here is where we read our file
const fileData = fs.readFileSync(origin_file);

s3.upload({
  Bucket: bucketName,
  Key: file_name, //this is only the name of the file
 //ContentType: 'valid content type', //this is very major,
 //most tutorials leave this part out
//when hosting on cloudfront default content type is
 //octetstream which causes file to download
//to overcome we MUST specify content type on creation of file
  ContentType: 'text/html',
 //set content type here in top level params not in above const
  Body: fileData 
}, (err, data) => {
  if (err) {
    console.error(err);
  } else {
    console.log(`File uploaded successfully. ${data.Location}`);
  }
});

  } //end if changed condition

});

```
**Caveats**
**1** cannot do this in aws lambda because lambda will not access the local windows file system
**2** beware that content type MUST be stated upon creation of an html file or the default octetstream format will cause a file download and will not overwrite existing content (a cloudfront issue)
**3** must use user credentials for s3 access, instructions are <a href="https://support.infinitewp.com/support/solutions/articles/212258-where-are-my-amazon-s3-credentials-"> here.</a>
**4** when program is started a message appears saying in 2023 we must use aws-sdk (v3) vs v2. I am using v2 at the moment so this code may not function in a few months
**5** best not to have s3 open when running this program as it causes it to crash. No damage so far but concerned. Check your files by httping to them instead.

**Continuing Saga**

Getting scared I figured I could go to my bucket and download the files. All well and good if u want to waste time downloading one by one since when trying to checkmark each file my download option goes away. We'll anyway, I did find the files but never want this to happen again.

Fs.watch to the rescue. A folder watcher that auto saves to s3 each time a file change is detected. Oh BTW u also need to copy updated file and paste to s3 bucket each time u make a change, forgot to tell u about this. I can live with all this but once I made my program s3 became a sinch to manage.

The program is a simple node file with only a few lines of code. When executed a listener opens waiting for updates. Keep the program running while making changes to html files. When the file change is detected the program passes the file name to an aws upload function which then uploads to s3 and overwrites the existing file. All we need to remember is the name of the node.js file. In cmd enter node my_program.js, go make some html updates and the rest is magic. 

More about the Author, Rick Delpo at https://howtolearnjava.com and https://javasqlweb.org