Since 10th May 2023, whatsapp has updated the code for sending button by verifying the sender. This update lead button to be unusable once again. All button including :
is no longer able to be sent using fonnte.
This issue will inevitable to be happen again in the future even if fonnte managed to make it work once again.
In this moment, we have decided to completely stop maintaining the button feature.
It is unfortunate that we have to discontinue this feature, but this feature is one that should not be accessible without using the official WhatsApp API service. We also stop trying to circumvent WhatsApp for something that should not be done. If WhatsApp opens this button feature to the public and makes it available in the WhatsApp application, we may start working on it again so that it can be used again. But as long as WhatsApp does not open this button feature to the public, we will not work on it.
We apologize for having to discontinue this feature.
Webhook update message status will be replacement of API message status to make the updating status real time and do not need an API hit to update it.
The message status would have id and stateid to update the message status and message state.
The example below show how to save message status to mysql, you can modify as you need.
You need to send from API to be able to save it. this is the example of API send with saving the report to mysql.
You can download example database table here.
API send and save report :
<?php
$conn = mysqli_connect("localhost","root","","db");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
exit();
}
$message = "test ya";
$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' => '083120942579','message' => $message),
CURLOPT_HTTPHEADER => array(
'Authorization: TOKEN'
),
));
$response = curl_exec($curl);
curl_close($curl);
$res = json_decode($response,true);
var_dump($res);
foreach($res["id"] as $k=>$v){
$target = $res["target"][$k];
$status = $res["process"];
mysqli_query($conn,"INSERT INTO report (id,target,message,status) VALUES ('$v','$target','$message','$status')");
}
Then use the example code below to update the message status and state to mysql.
Webhook script :
<?php
header('Content-Type: application/json; charset=utf-8');
$conn = mysqli_connect("localhost","root","","db");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
exit();
}
$json = file_get_contents('php://input');
$data = json_decode($json, true);
$device = $data['device'];
$id = $data['id'];
$stateid = $data['stateid'];
$status= $data['status'];
$state = $data['state'];
//update status and state
if(isset($id) && isset($stateid)){
mysqli_query($conn,"UPDATE report SET status = '$status',state = '$state',stateid = '$stateid' WHERE id = '$id'");
}else if(isset($id) && !isset($stateid)){
mysqli_query($conn,"UPDATE report SET status = '$status' WHERE id = '$id'");
}else{
mysqli_query($conn,"UPDATE report SET state = '$state' WHERE stateid = '$stateid'");
}
Available parameter
We are adding the last planned features for this year.
Fonnte focus on making a follow up feature whenever a number is added to a group.
Every time a number is added to a group which connected to follow up, the number will be scheduled to get follow up messages.
This feature is very useful for newsletter purpose.
You can also use it together with submission feature.
You can now insert the target using csv.
It's easier for you to send bulk message using your own data from csv without having to add to a group.
Fonnte support device to send location using latitude and longitude.
you can find the example at the docs.
If you ever need to send a template message, fonnte has release this feature.
You can write anything on your whatsapp as you've created on autoreply and your device will be sending message.
fix not joined whatsapp group still exist after update
fix unable to delete filtered history
You can send fonnte using API with javascript native fetch.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
(async () => {
const data = new FormData()
data.append("target", "082227097005")
data.append("message", "kirim dari js")
data.append("url", "https://md.fonnte.com/images/wa-logo.png")
data.append("filename", "filename.pdf")
data.append("schedule", "0")
data.append("delay", "2")
data.append("countryCode", "62")
data.append("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"}]}')
data.append("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"}]}')
data.append("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"}]}]}')
const response = await fetch("https://api.fonnte.com/send", {
method: "POST",
mode: "cors",
headers: new Headers({
Authorization: "TOKEN",
}),
body: data,
});
const res = await response.json();
document.write(JSON.stringify(res))
})()
</script>
</body>
</html>
You can use any php version API data with javascript.
Fonnte mainly focus on developing submission for better support to developer and non-developer so it can be used more easily.
If your target is not only on a country, the default fonnte's country code will be a problem.
We have adjusted to enable an option to disable this by adding support to 0 on the field "countryCode" => "0".
The downside for using it is, fonnte no longer will take care of your country code number.
Use it only when needed.
You can now download the submission list
On successful submission, admin will get notified.
you can also use rotator on the target.
You can receive the submission data for your system by using webhook submission.
The submission sender can now be saved on a group for future usage.
We add support for button text on webhook for easier usage, if needed.
You can use $text to get the button text.
fix submission button answer on review list
fix incorrect file limit on dashboard
You can get the submission data using webhook with javascript.
const express = require("express");
const app = express();
app.use(express.json());
async function sendFonnte(data) {
const url = "https://api.fonnte.com/send";
const customHeaders = {
"Content-Type": "application/json",
Authorization: TOKEN ,
};
const response = await fetch(url, {
method: "POST",
headers: customHeaders,
body: JSON.stringify(data),
});
console.log(await response.json());
}
app.post("/submission", function (req, res) {
console.log(req.body);
const data = {
target: "082227097005",
message: "webhook submission working great!",
sendFonnte(data);
}
res.end();
});
app.listen(3000, function (err) {
if (err) console.log(err);
console.log("Server listening on PORT", 3000);
});
Available parameter
When a client submit their submission, you can get the data and save it to your own system or do anything with it.
Copy and use it however you like on your system.
<?php
header('Content-Type: application/json; charset=utf-8');
$json = file_get_contents('php://input');
$data = json_decode($json, true);
$sender = $data["sender"];
$submission = $data["submission"];
$name = $data["name"];
$list = $data["data"];
function sendFonnte($target, $data)
{
$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' => $target,
'message' => $data["message"],
),
CURLOPT_HTTPHEADER => array(
"Authorization: TOKEN"
),
));
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
$reply = [
"message" => $json
];
sendFonnte("082227097005", $reply); //change number to your own number
Available parameter
You can download the attachment sent to your device using webhook.
This function will only working on device with all feature package.
Special note : any autoreply feature won't work if you are using webhook.
const fs = require("fs");
const express = require("express");
const app = express();
app.use(express.json());
app.use(express.static("public"));
app.post("/webhook", async function (req, res) {
console.log(req.body);
const response = await fetch(req.body.url);
const result = await response.arrayBuffer();
fs.writeFile(`./public/file.${req.body.extension}`, Buffer.from(result), (err) => {
if (err) console.log(err);
});
res.end();
});
app.listen(3000, function (err) {
if (err) console.log(err);
console.log("Server listening on PORT", 3000);
});
If your attachment have message with it, you can find it in req.body.url.
The attachment will be downloaded and saved in the public folder.
To save somewhere else, determine the path where the attachment should be saved.
Note: The attachment will follow file limitation rules. if you are receiving an attachment outside file limitation rules, you will not receive it on your webhook.
Using webhook will enable your device to respond on incoming message with dynamic response.
We will use express for easier usage.
Special note : any autoreply feature won't work if you are using webhook.
const express = require("express");
const app = express();
app.use(express.json());
async function sendFonnte(data) {
const url = "https://api.fonnte.com/send";
const customHeaders = {
"Content-Type": "application/json",
Authorization: TOKEN ,
};
const response = await fetch(url, {
method: "POST",
headers: customHeaders,
body: JSON.stringify(data),
});
console.log(await response.json());
}
app.post("/webhook", function (req, res) {
console.log(req.body);
if (req.body.message == "test") {
const data = {
target: req.body.sender,
message: "working great!",
};
sendFonnte(data);
} else {
const data = {
target: req.body.sender,
message: "this is default reply from fonnte",
};
sendFonnte(data);
}
res.end();
});
app.listen(3000, function (err) {
if (err) console.log(err);
console.log("Server listening on PORT", 3000);
});
Available parameter
Replying using attachment is only available on devices with a package of super, advanced or ultra.
We are adding rotator option for the the recipient.
You can forward incoming message or split the leads when a client fill a form using API.
You can now use full power of autoreply fonnte.
Similar to forward rotator, you can now forward incoming text to a specific number.
You can only forward on default message.
It's pointless to forward text which is the same as keyword.
Fonnte adding a menu to make a partnership with you.
This is an opportunity for you to make more clients and more money.
Your product / service will be shown at partner's page.
But this is limited to a product/service which require their clients to use their own token.
add autoresend to group when failed.
fix missing validation on button url.
fix autorepy button type.