1. Go to this page and download the library: Download tritech/threadwire-laravel library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
tritech / threadwire-laravel example snippets
use Threadwire\Facades\Threadwire;
$message = Threadwire::sendText($numberId, '201012345678', 'Hi Sara, your order 1042 is on its way.', [
'idempotency_key' => "order-1042-shipped", // a retry returns this message instead of sending twice
]);
$message['status']; // "queued": what happens next arrives by webhook (message.status)
Threadwire::sendMedia($numberId, '201012345678', ['url' => 'https://shop.example/invoice-1042.pdf', 'mimetype' => 'application/pdf', 'filename' => 'invoice-1042.pdf'], 'Your invoice');
Threadwire::sendLocation($numberId, '201012345678', 30.0444, 31.2357, 'Our shop');
Threadwire::sendContact($numberId, '201012345678', 'Support', '201000000009');
Threadwire::sendPoll($numberId, '201012345678', 'Which time suits you?', ['10:00', '14:00']);
Threadwire::sendText($numberId, '[email protected]', 'Meeting at 5'); // a group
// Any other field of POST /v1/messages goes in the options too:
Threadwire::sendText($numberId, '201012345678', 'See you tomorrow', ['reply_to' => $messageId, 'send_at' => '2026-10-05T09:00:00+03:00']);
Threadwire::message($id); // its status, and the reason in "error" if it failed
Threadwire::messages(['phone' => '201012345678']); // newest first; "links.next" for older ones
Threadwire::cancelMessage($id); // only while it waits: null when it was scheduled; a ConflictException once it went
Threadwire::deleteMessage($id); // a sent message, deleted for everyone in the chat (within about two days)
Threadwire::instances(); // your numbers
Threadwire::instance($numberId)['protection']; // where the number stands today: new people left, warm-up, safety score
Threadwire::chats(['waiting' => 1]); // chats waiting for your reply
Threadwire::chatHistory($numberId, '201012345678'); // the chat's history from the phone, newest first
$after = Cache::get('threadwire-after'); // null the first time: from the oldest kept (30 days)
do {
$page = Threadwire::events(['after' => $after, 'types' => ['message.received']]);
foreach ($page['data'] as $event) {
// $event['id'], $event['type'], $event['created_at'], $event['data']
}
Cache::forever('threadwire-after', $after = $page['next_after']);
} while ($page['has_more']);
// 1. The link (recommended)
$otp = Threadwire::verifyByLink($numberId, ['brand' => 'Acme', 'reference' => 'signup-7', 'phone' => $phone]);
// show $otp['link'] as a button (or $otp['qr'] on a computer), $otp['code'] as a fallback
// then, in a listener:
Event::listen(\Threadwire\Events\OtpCompleted::class, function ($event) {
$phone = $event->payload['data']['phone']; // sign in by this; never by a null phone
});
// 2. A code your number sends
$otp = Threadwire::sendOtpCode($numberId, '201012345678', ['brand' => 'Acme']);
try {
Threadwire::checkOtp($otp['id'], $request->input('code')); // status: verified
} catch (\Threadwire\Exceptions\ValidationException $e) {
$e->attemptsLeft(); // wrong code; after the fifth it fails
}
Threadwire::otp($otp['id']); // status, phone, attempts left; never the code
Threadwire::resendOtp($otp['id']);
Threadwire::cancelOtp($otp['id']);
// Everyone who wrote in the last 14 days
$broadcast = Threadwire::createBroadcast($numberId, 'Hi {name}, our autumn menu starts today.', 'recent', ['days' => 14, 'idempotency_key' => 'autumn-menu']);
// Your own list, with fields for placeholders
Threadwire::createBroadcast($numberId, 'Hi {name}, {city} has a new branch.', [
['phone' => '201012345678', 'name' => 'Mona', 'fields' => ['city' => 'Giza']],
'201098765432',
], ['interval_seconds' => 90, 'per_day' => 150]);
Threadwire::broadcast($broadcast['id']); // status, reason when paused, progress
Threadwire::pauseBroadcast($broadcast['id']);
Threadwire::resumeBroadcast($broadcast['id']); // a ConflictException says what still stops it
Threadwire::cancelBroadcast($broadcast['id']);
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Cache;
use Threadwire\Events\MessageReceived;
class AnswerCustomer implements ShouldQueue
{
public function handle(MessageReceived $event): void
{
// The same event can come twice (a retry, or "Send again" in the panel): same id.
if (! Cache::add("threadwire-event:{$event->id}", true, now()->addDay())) {
return;
}
$phone = $event->data['phone'];
$text = $event->data['body'];
// ...
}
}