send whatsapp message with php (API)

Sending whatsapp programatically is hard back then.

Send invoice, notification, confirmation, etc mostly send through email.

As for today, send whatsapp message is possible through API.

Fonnte provide super easy API to send whatsapp message via API.

In this tutorial you will learn how.

This tutorial require you to understand basic programing language mainly PHP. If you don't have any experience or don't know what to do, please consider hire a developer.

Prerequisite

Before you can use this API, you need to make an account, login and create a device.

Copy the token as API key to be used on API.

Then, connect your device first before you can proceed to send a message.

Please use most recent curl with php version of 7.1++ as requirement.

Full API reference can be found in the docs and postman.

About Target

Target is the number or whatsapp group id who'll receive the message you sent.

If the target is personal, you can just set their whatsapp number as target

If the target is whatsapp group, you have to know the whatsapp group's id.

See tutorial for getting whatsapp group id.

Single Message

For using fonnte's API, just copy the code below.

Make a file, for example, send.php in your environment (localhost using xampp for example).

Then paste this code.

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.fonnte.com/send',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
'target' => '08123456789',
'message' => 'test message', 
'countryCode' => '62', //optional
),
  CURLOPT_HTTPHEADER => array(
    'Authorization: TOKEN' //change TOKEN to your actual token
  ),
));

$response = curl_exec($curl);
if (curl_errno($curl)) {
  $error_msg = curl_error($curl);
}
curl_close($curl);

if (isset($error_msg)) {
 echo $error_msg;
}
echo $response;

Don't forget to change the target and token and then just run the file in browser.

Then, you're good to go, the message is sent to your target number.

Bulk Message

If you really want to send bulk messages, DO NOT USE LOOP!

Unless you want to send multiple url, you are welcome to use loop.

Then how to send bulk messages without loop?

Don't worry, we got your back.

Just use comma separated for each target.

Example : 081xxxxx,082xxxxx.

Here's the code

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.fonnte.com/send',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
'target' => '08123456789,08987654321',
'message' => 'test message',
'delay' => '2', 
'countryCode' => '62', //optional
),
  CURLOPT_HTTPHEADER => array(
    'Authorization: TOKEN' //change TOKEN to your actual token
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

You just need to separate each target with comma.

Set 'delay' is highly recommended, it's in second.

In the example above the message will be sent to 628123456789 immediately then wait 2 seconds before send to 628987654321.

Schedule Message

The message can also be sent in a scheduled time.

Pass the parameter 'schedule' with value of unix timestamp down to second, not to milisecond.

For example : 1667433600 for November 3rd, 2022 12:00:00 AM (GMT +0)

In indonesian time, the time above will run on :

  • WIB (GMT +7) : November 3rd, 2022 7:00:00 AM
  • WITA (GMT +8) : November 3rd, 2022 8:00:00 AM
  • WIT (GMT +9) : November 3rd, 2022 9:00:00 AM

So this is the code

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.fonnte.com/send',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
'target' => '08123456789',
'message' => 'test message', 
'schedule' => '1667433600', 
'countryCode' => '62', //optional
),
  CURLOPT_HTTPHEADER => array(
    'Authorization: TOKEN' //change TOKEN to your actual token
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

That's all.

The message will be sent on scheduled time.

Dynamic Message

So after successfully send message, There is another wish.

"i want to send this message personally".

Well, ofcourse it's possible!

First option is not using fonnte's API feature (not recommended).

  • Lookup data in the database
  • Save as variable
  • Make a loop
  • Send through API individually

You are making n request to fonnte.

Even fonnte does not have problem with it, we have a better solution!

Second option is using fonnte's API feature (highly recommended).

  • Lookup data in the database
  • Save as variable
  • Make a loop
  • Send through API once

To send dynamic messages, you can use variables.

To use it, you need to set the variables on 'target', and use the variable on 'message'

Here's the code

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.fonnte.com/send',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
'target' => '08123456789|Fonnte|Admin,08987654321|Lily|Client',
'message' => 'test message to {name} as {var1}', 
'delay' => '2', 
'countryCode' => '62', //optional
),
  CURLOPT_HTTPHEADER => array(
    'Authorization: TOKEN' //change TOKEN to your actual token
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

That code will send message to with 2 seconds delay for each message

  • 628123456789 : test message to Fonnte as Admin
  • 628987654321 : test message to Lily as Client

Separate each variable with pipe (|).

The first variable will using {name} and the rest is using {var1},{var2},...

This is great! you can send personalized messages with one go.

How much can i make the variable? as much as you need, ofcourse!

You can learn more about it on about variable page.

Media Message

Can i add message with attachment like image? or video? file like pdf, excel, docs? and audio?

Yes you can!

This code require all feature package, otherwise, will not work.

Public url

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.fonnte.com/send',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
'target' => '08123456789',
'message' => 'test message', 
'url' => 'https://md.fonnte.com/images/logo-dashboard.png', 
'filename' => 'my-file.pdf', //optional, only works on file and audio
'countryCode' => '62', //optional
),
  CURLOPT_HTTPHEADER => array(
    'Authorization: TOKEN' //change TOKEN to your actual token
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

That's it, you can now send the message with an image!

Local file

local file is supported using file parameter file

the path must correct otherwise you will get error : operation aborted by callback.

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.fonnte.com/send',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
'target' => '08123456789',
'message' => 'test message', 
'file' => new CURLFile("localfile.png"), 
'filename' => 'my-file.pdf', //optional, only works on file and audio
'countryCode' => '62', //optional
),
  CURLOPT_HTTPHEADER => array(
    'Authorization: TOKEN' //change TOKEN to your actual token
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

That's it, you can now send the file via your own local file.

Form uploads

You can also send directly from a form upload.

this is super beneficial that you don't have to save it to your local/server first.

<?php
//logic
$file = $_FILES["file"]["tmp_name"]; //change "file" with your actual file input name tag
$name = $_FILES["file"]["name"];
$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.fonnte.com/send',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
'target' => '08123456789',
'message' => 'test message', 
'file' => new CURLFile($file, '', $name), 
'filename' => 'my-file.pdf', //optional, only works on file and audio
'countryCode' => '62', //optional
),
  CURLOPT_HTTPHEADER => array(
    'Authorization: TOKEN' //change TOKEN to your actual token
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

you can utilize fonnte api to suits your need.

The next 3 message types is used for interactive purpose. (deprecated)

Button Message (Deprecated)

This feature has been deprecated and no longer maintained

What is button message?

That's button message.

It's more interactive than wishing user to respond in a text.

To send this message, you will need to make a multidimensional array, then just encode it to be a json.

Note : max 3 buttons

here's the code

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.fonnte.com/send',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
'target' => '08123456789',
'url' => 'https://md.fonnte.com/images/logo-dashboard.png', 
'buttonJSON' => '{"message":"fonnte button message","footer":"fonnte footer message","buttons":[{"id":"mybutton1","message":"hello fonnte"},{"id":"mybutton2","message":"fonnte pricing"},{"id":"mybutton3","message":"tutorial fonnte"}]}', 
'countryCode' => '62', //optional
),
  CURLOPT_HTTPHEADER => array(
    'Authorization: TOKEN' //change TOKEN to your actual token
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

You can add url ofcourse, but it's limited to image and video only.

Template Message (Deprecated)

This feature has been deprecated and no longer maintained

Template button is much more interactive than just button message.

Sadly, our API's can not send this type to IOS yet.

This message type support call and link.

The other one is just regular button.

Note : max 3 buttons

So how to send it?

Here's the code

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.fonnte.com/send',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
'target' => '08123456789',
'templateJSON' => '{"message":"fonnte template message","footer":"fonnte footer message","buttons":[{"message":"fonnte","url":"https://fonnte.com"},{"message":"call me","tel":"6282227097005"},{"id":"mybutton1","message":"hello fonnte"}]}', 
'countryCode' => '62', //optional
),
  CURLOPT_HTTPHEADER => array(
    'Authorization: TOKEN' //change TOKEN to your actual token
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

Template is not supporting any media yet.

So you can only send plain text with it.

List Message (Deprecated)

This feature has been deprecated and no longer maintained

List message is another message type which allow you to create many buttons, not just 3.

And when you click button, this popup appear.

This is great! you can give your user many choices.

And even better, it has group and description for easier understanding of choice.

Here's the code

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.fonnte.com/send',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
'target' => '08123456789',
'listJSON' => '{"message":"fonnte list message","footer":"fonnte footer message","buttonTitle":"fonnte's packages","title":"fonnte title","buttons":[{"title":"text only","list":[{"message":"regular","footer":"10k messsages/month","id":"list-1"},{"message":"regular pro","footer":"25k messsages/month","id":"list-2"},{"message":"master","footer":"unlimited messsages/month","id":"list-3"}]},{"title":"all feature","list":[{"message":"super","footer":"10k messsages/month","id":"list-4"},{"message":"advanced","footer":"25k messsages/month","id":"list-5"},{"message":"ultra","footer":"unlimited messsages/month","id":"list-6"}]}]}', 
'countryCode' => '62', //optional
),
  CURLOPT_HTTPHEADER => array(
    'Authorization: TOKEN' //change TOKEN to your actual token
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

With this, you can send list message and waiting for a reply.

Location

Location can be send using latitude and longitude.

the format should be latitude,longitude.

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.fonnte.com/send',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array(
'target' => '08123456789',
'location' => '-7.983908, 112.621391',

),
  CURLOPT_HTTPHEADER => array(
    'Authorization: TOKEN' //change TOKEN to your actual token
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

You can change the location value with your desired location.

Poll

You can send whatsapp poll message to your recipients.

The poll may be sent to group or individual.

Screenshot_150
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.fonnte.com/send',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS => array('target' => '082227097005','message' => 'test dari postman','choices' => 'satu,dua,tiga','select' => 'single','pollname' => 'pollku'),
  CURLOPT_HTTPHEADER => array(
    'Authorization: TOKEN'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

You can change the data to your personal needs.

Conclusion

Fonnte provide many configuration to make the API as flexible as possible.

If you are not a programmer or confuse how to do it, you can hire a programmer or just use fonnte's dashboard to send whatsapp message.

We have cover all this way to send message in our dashboard.

In the end, it's not only meant for sending, you can also reply the message.

We'll cover in autoreply tutorial on how to create a whatsapp chat bot.

Related knowledge

See more
Made with in Indonesia