Automatically Send Invoices With WhatsApp
Tags: javascript, node, webhooks
Published: 2022-04-25 16:35:25


In this tutorial we look at how you can create a shareable link when an Invoice is created in FreshBooks. Then send this link to your client over Whatsapp. So that the client can view the invoice immediately on his/her mobile. The same concept can be applied for checkout links, expenses and more.

#### Prerequisites
- A FreshBooks Developer account.
- A [Twilio Sandbox account](https://www.twilio.com/docs/whatsapp/sandbox).
- Basic knowledge of Async, Await and Node.js.
- A code editor (e.g. VS Code, Sublime, Atom etc.)
- How to generate a bearer token in Postman

#### Setup your express app locally 

First we setup our express app, which listens on port 3000 and has a uri available at '/webhooks/ready'

```javascript
const app = express();
app.use(express.json()); 
app.use(express.urlencoded({
    extended: true
}));

app.get('/', function (req, res) {
  res.end('Hello World 1',()=>{
  console.log(`Get Body ${JSON.stringify(req.body)}`)
  });

})

app.post('/webhooks/ready',function (req,res){
    res.end('Thanks for your business POST',()=>{
      console.log(`POST Body ${JSON.stringify(req.body)}`)
      });
    var name = req.body.name;
    if(name == "invoice.create" || name == "invoice.update"){
      var { account_id, object_id } = req.body;  
      sendShareLink(account_id,object_id);
    };
  })

  app.listen(3000,()=>{
    console.log("listening on port 3000")
  })
```
#### Create a public web server
 
I am making use of ‘ngrok’ to create a publicly accessible web server. You can download ngrok using this [link](https://ngrok.com/download). Once you have installed ngrok, you can start ngrok and expose your local web server. Don’t forget to make note of your https url provided by ngrok, we will use this to register a webhook. ngrok will relay our calls to our localhost server at port 3000


#### Register for webhooks

FreshBooks need to notify our application on invoice creation. To get notified, we need to register and listen to the [FreshBooks webhook](https://www.freshbooks.com/api/webhooks) for the event 'invoice.created'. Register for webhooks using the URI generated earlier using ngrok e.g. `https://d7b0-213-127-111-74.ngrok.io` . This part has not yet been built into the application at time of writing. For now we do this using [postman](https://documenter.getpostman.com/view/3322108/S1ERwwza#fb78c21c-8c52-4acf-baa5-b10c7799415e). You can use ngrok inspect to get the verifier code for the webhook. 

> You can inspect calls coming in via a web UI provided by ngrok. After you start the ngrok agent, open [http://localhost:4040](http://localhost:4040/) in a browser on the same machine

#### Getting a shareable link and client contact

We first generate a FreshBooks client to interact using the [FreshBooks nodeJs sdk](https://dev.to/freshbooks/getting-started-with-freshbooks-nodejs-sdk-expenses-invoices-a6). We initialise the client with the clientID of our app and the bearer token which we provided using env variables.

When you generate an invoice using the FreshBooks UI, it triggers a webhook call to our previously registered link. When our app receives this api call we retrieve the invoice id. The invoice id is then used to generate an invoice link using the FreshBooks Client.

To create a shareable invoice link we use the nodejs sdk, we use the get shareable link api to get an invoice link against the invoice id. Additionally we also retrieve the mobile number of the client.

```javascript
const postWhatsapp = require('./postWhatsapp');
const clientId = process.env.CLIENTID;
const token = process.env.TOKEN;

let accountId;
let invoiceId;



module.exports = async (accountId,invoiceId)=>{
    try {
        const { Client } = await import("@freshbooks/api");
        const app = new Client(clientId,token);
        const shareLink = await app.invoices.shareLink(accountId,invoiceId);
        const invoiceInfo = await app.invoices.single(accountId,invoiceId);
        const client  = await app.clients.single(accountId,invoiceInfo.data.customerId);   


        postWhatsapp(shareLink.data.shareLink, client.data.mobPhone);
      
      } catch (error) {
      console.log(error);  
    }
    
};
```

#### Sending your invoice over whatsapp

Once we have a shareable link, we use the Twilio SDK to initialise a client using our ‘Twilio SID’ and ‘Auth Token’.  Using this twilio client we send a whatsapp message which includes the shareable link to the invoice.

```javascript
const twilio = require('twilio');

const accountSid  =  process.env.ACCSID; 
const authToken   =  process.env.AUTHTOK; 
const client      =  require('twilio')(accountSid, authToken); 
let shareLink;
let mobNo

module.exports= (shareLink,mobNo)=>{
  client.messages 
  .create({ 
     body: `Here is your share link ${shareLink}`, 
     from: 'whatsapp:+14155238886',       
     to: `whatsapp:${mobNo}` 
   }) 
  .then(message => console.log(message.sid)) 
  .catch(error=>{
    console.log(error);
  })
  .done();
  
}
```
If your looking for more information on the Twilio whatsapp api, you can check this [link](https://www.twilio.com/docs/whatsapp/quickstart/node).

Now whenever you create an invoice for a client, your server receives a notice, gets the share link, and sends it to them via WhatsApp.

You can checkout the entire code at my personal repo 
{% github lygel07/freshbooks-whatsapp-link %}