/** * Authenticate with the Whatsapp Server. * * @param Connection $connection * @param Identity $identity * @param string $challengeData * @return string Returns binary string */ protected function getAuthData(Connection $connection, Identity $identity, $challengeData) { $keys = KeyStream::generateKeys(base64_decode($identity->getPassword()), $challengeData); $connection->setInputKey($this->createKeyStream($keys[2], $keys[3])); $connection->setOutputKey($this->createKeyStream($keys[0], $keys[1])); $array = "" . $identity->getPhone()->getPhoneNumber() . $challengeData; $response = $connection->getOutputKey()->encodeMessage($array, 0, 4, strlen($array) - 4); return $response; }
/** * @return Node */ public function createNode() { $state = new Node(); $state->setName($this->getState()); $node = new Node(); $node->setName('chatstate')->setAttribute('to', Identity::createJID($this->getTo()))->addChild($state); return $node; }
/** * @return Node */ public function createNode() { $child = new Node(); $child->setName('query'); $node = new Node(); $node->setName('iq'); $node->setAttributes(["id" => 'getgroupinfo-', "type" => "get", "xmlns" => "w:g", "to" => Identity::createJID($this->getGroupId())]); $node->addChild($child); return $node; }
/** * @param array $data * @return Group */ public static function factory(array $data) { $group = new self(); $group->setId($data['id']); $group->setOwner(Identity::parseJID($data['owner'])); $creation = new DateTime(); $creation->setTimestamp((int) $data['creation']); $group->setCreation($creation); $group->setSubject($data['subject']); return $group; }
protected function parseGroupPresence(Client $client, NodeInterface $node) { $groupId = Identity::parseJID($node->getAttribute('from')); if (null != $node->getAttribute('add')) { $added = Identity::parseJID($node->getAttribute('add')); $client->getEventManager()->trigger('onGroupParticipantAdded', $client, ['group' => $groupId, 'participant' => $added]); } elseif (null != $node->getAttribute('remove')) { $removed = Identity::parseJID($node->getAttribute('remove')); $author = Identity::parseJID($node->getAttribute('author')); $client->getEventManager()->trigger('onGroupParticipantRemoved', $client, ['group' => $groupId, 'participant' => $removed, 'author' => $author]); } }
/** * @param NodeInterface $node * @return Presence */ public function createPresence(NodeInterface $node) { $presence = new Presence(); $presence->setFrom(Identity::parseJID($node->getAttribute('from'))); $presence->setLast($node->getAttribute('last')); switch ($node->getAttribute('type')) { case 'unavailable': $presence->setType(Presence::TYPE_UNAVAILABLE); break; default: $presence->setType(Presence::TYPE_AVAILABLE); } return $presence; }
/** * @return Node */ public function createNode() { $server = new Node(); $server->setName('server'); $x = new Node(); $x->setName('x')->setAttribute('xmlns', 'jabber:x:event')->addChild($server); $notify = new Node(); $notify->setName('notify')->setAttribute('xmlns', 'urn:xmpp:whatsapp')->setAttribute('name', $this->getFromName()); $request = new Node(); $request->setName('request')->setAttribute('xmlns', 'urn:xmpp:receipts'); $body = new Node(); $body->setName('body')->setData($this->getBody()); $node = new Node(); $node->setName('message')->setAttribute('id', null)->setAttribute('t', null)->setAttribute('to', Identity::createJID($this->getTo()))->setAttribute('type', 'text')->addChild($x)->addChild($notify)->addChild($request)->addChild($body); return $node; }
/** * @param EventInterface $e */ public function onReceivedNode(EventInterface $e) { /** @var NodeInterface $node */ $node = $e->getParam('node'); /** @var Client $client */ $client = $e->getTarget(); $identity = $client->getIdentity(); if ($this->isNodeFromMyNumber($identity, $node) || $this->isNodeFromGroup($node)) { return; } if ($node->hasChild('composing')) { $client->getEventManager()->trigger('onMessageComposing', $client, array('node' => $node, 'from' => Identity::parseJID($node->getAttribute('from')), 'id' => $node->getAttribute('id'), 'timestamp' => (int) $node->getAttribute('t'))); } elseif ($node->hasChild('paused')) { $client->getEventManager()->trigger('onMessagePaused', $client, array('node' => $node, 'from' => Identity::parseJID($node->getAttribute('from')), 'id' => $node->getAttribute('id'), 'timestamp' => (int) $node->getAttribute('t'))); } }
/** * @param NodeInterface $node * @return MessageText */ public function createMessage(NodeInterface $node) { $message = new MessageText(); $message->setBody($node->getChild('body')->getData()); $participant = $node->getAttribute('participant'); $from = $node->getAttribute('from'); if ($participant) { $message->setFrom(Identity::parseJID($participant)); $message->setGroupId(Identity::parseJID($from)); } else { $message->setFrom(Identity::parseJID($from)); } $message->setId($node->getAttribute('id')); $dateTime = new DateTime(); $dateTime->setTimestamp((int) $node->getAttribute('t')); $message->setDateTime($dateTime); $message->setNotify($node->getAttribute('notify')); $message->setType($node->getAttribute('type')); return $message; }
/** * @param NodeInterface $node * @return bool */ protected function isNodeFromMyNumber(Identity $identity, NodeInterface $node) { $currentPhoneNumber = $identity->getPhone()->getPhoneNumber(); return 0 === strncmp($node->getAttribute('from'), $currentPhoneNumber, strlen($currentPhoneNumber)); }
/** * @return Node */ public function createNode() { $syncNode = new Node(); $syncNode->setName('sync'); $syncNode->setAttributes(["mode" => $this->getMode(), "context" => $this->getContext(), "sid" => "" . (time() + 11644477200) * 10000000, "index" => "" . $this->getIndex(), "last" => $this->isLast() ? "true" : "false"]); foreach ($this->getNumbers() as $number) { $userNode = new Node(); $userNode->setName('user')->setData($number); $syncNode->addChild($userNode); } $node = new Node(); $node->setName('iq'); $node->setAttributes(["id" => 'sendsync-', "type" => "get", "xmlns" => "urn:xmpp:whatsapp:sync", "to" => Identity::createJID($this->getTo())]); $node->addChild($syncNode); return $node; }
public function uploadMediaFile(MediaFile $mediaFile, Identity $identity, $uploadUrl, $to) { return $this->sendMediaFile($mediaFile, $uploadUrl, Identity::createJID($to), $identity->getPhone()->getPhoneNumber()); }
/** * Check if account credentials are valid. * * WARNING: WhatsApp now changes your password everytime you use this. * Make sure you update your config file if the output informs about * a password change. * * @param Identity $identity * @return array * An object with server response. * - status: Account status. * - login: Phone number with country code. * - pw: Account password. * - type: Type of account. * - expiration: Expiration date in UNIX TimeStamp. * - kind: Kind of account. * - price: Formatted price of account. * - cost: Decimal amount of account. * - currency: Currency price of account. * - price_expiration: Price expiration in UNIX TimeStamp. * * @throws \RuntimeException */ public function checkCredentials(Identity $identity) { $host = 'https://' . Client::WHATSAPP_CHECK_HOST; $query = ['cc' => $identity->getPhone()->getCc(), 'in' => $identity->getPhone()->getPhoneNumber(), 'id' => $identity->getIdentityString(), 'lg' => $identity->getPhone()->getIso639() ?: 'en', 'lc' => $identity->getPhone()->getIso3166() ?: 'US', 'network_radio_type' => "1"]; $response = $this->getResponse($host, $query); if ($response['status'] != 'ok') { $message = 'There was a problem trying to request the code. ' . $response['reason']; throw new \RuntimeException($message); } return $response; }
/** * Register the service provider. * * @return void */ public function register() { //Set up how the create the Identity when one is asked to be created $this->app->bindShared('Tmv\\WhatsApi\\Entity\\Identity', function () { //Setup Account details. $account = Config::get("larawhatsapi::useAccount"); $nickName = Config::get("larawhatsapi::accounts.{$account}.nickName"); $number = Config::get("larawhatsapi::accounts.{$account}.number"); $password = Config::get("larawhatsapi::accounts.{$account}.password"); $userIdent = Config::get("larawhatsapi::accounts.{$account}.identity"); // Initializing client // Creating a service to retrieve phone info $localizationService = new LocalizationService(); // Creating a phone object... $phone = new Phone($number); // Injecting phone properties $localizationService->injectPhoneProperties($phone); // Creating identity $identity = new Identity(); $identity->setPhone($phone)->setNickname($nickName)->setPassword($password)->setIdentityToken($userIdent); return $identity; }); //Set up how the create TMV's Client Object when one is asked to be created (which needs the Identity) $this->app->bindShared('Tmv\\WhatsApi\\Client', function () { $debug = Config::get("larawhatsapi::debug"); $account = Config::get("larawhatsapi::useAccount"); $number = Config::get("larawhatsapi::accounts.{$account}.number"); $nextChallengeFile = Config::get("larawhatsapi::nextChallengeDir") . "/" . $number . "-NextChallenge.dat"; $identity = App::make('Tmv\\WhatsApi\\Entity\\Identity'); // Initializing client $client = new Client($identity); $client->setChallengeDataFilepath($nextChallengeFile); // Attaching events... if (class_exists('MGP25WhatapiEvents')) { $events = new MGP25WhatapiEvents($client); foreach ($events->activeEvents as $eventName) { $client->getEventManager()->attach($eventName, function () use($events, $eventName) { $events->{$eventName}(); }); } } // TODO I don't want to attach events here, but this is just for demo. // $client->getEventManager()->attach( // 'onMessageReceived', // function (MessageReceivedEvent $e) // { // $message = $e->getMessage(); // echo str_repeat('-', 80) . PHP_EOL; // echo '** MESSAGE RECEIVED **' . PHP_EOL; // echo sprintf('From: %s', $message->getFrom()) . PHP_EOL; // if ($message->isFromGroup()) // { // echo sprintf('Group: %s', $message->getGroupId()) . PHP_EOL; // } // echo sprintf('Date: %s', $message->getDateTime()->format('Y-m-d H:i:s')) . PHP_EOL; // // if ($message instanceof Received\MessageText) // { // echo PHP_EOL; // echo sprintf('%s', $message->getBody()) . PHP_EOL; // } elseif ($message instanceof Received\MessageMedia) // { // echo sprintf('Type: %s', $message->getMedia()->getType()) . PHP_EOL; // } // echo str_repeat('-', 80) . PHP_EOL; // } // ); // Debug events if ($debug) { $client->getEventManager()->attach('node.received', function (Event $e) { $node = $e->getParam('node'); echo sprintf("\n--- Node received:\n%s\n", $node); }); $client->getEventManager()->attach('node.send.pre', function (Event $e) { $node = $e->getParam('node'); echo sprintf("\n--- Sending Node:\n%s\n", $node); }); } dd('done'); return $client; }); //Which concret implementation will we use when an SMSInterface is asked for? User can pick in the config file. $this->app->bindShared('Williamson\\Larawhatsapi\\Repository\\SMSMessageInterface', function () { $fork = strtoupper(Config::get('larawhatsapi::fork')); switch ($fork) { case $fork == 'MGP25': return App::make('Williamson\\Larawhatsapi\\Clients\\LaraWhatsapiMGP25Client'); break; default: return App::make('Williamson\\Larawhatsapi\\Clients\\LaraWhatsapiTMVClient'); break; } }); //Set up how the create the WhatsProt object when using MGP25 fork $this->app->bindShared('WhatsProt', function () { //Setup Account details. $debug = Config::get("larawhatsapi::debug"); $account = Config::get("larawhatsapi::useAccount"); $nickName = Config::get("larawhatsapi::accounts.{$account}.nickName"); $number = Config::get("larawhatsapi::accounts.{$account}.number"); $userIdent = Config::get("larawhatsapi::accounts.{$account}.identity"); $nextChallengeFile = Config::get("larawhatsapi::nextChallengeDir") . "/" . $number . "-NextChallenge.dat"; $identityFileNoDat = Config::get("larawhatsapi::nextChallengeDir") . "/" . $number . "-Identity"; $identityFileDat = $identityFileNoDat . '.dat'; if (!File::exists($identityFileDat) || File::get($identityFileDat) !== $userIdent) { File::put($identityFileDat, $userIdent); } $whatsProt = new WhatsProt($number, $identityFileNoDat, $nickName, $debug); $whatsProt->setChallengeName($nextChallengeFile); if (class_exists('MGP25WhatapiEvents')) { $events = new MGP25WhatapiEvents($whatsProt); $events->setEventsToListenFor($events->activeEvents); } return $whatsProt; }); }
/** * @return Node */ public function createNode() { $server = new Node(); $server->setName('server'); $x = new Node(); $x->setName('x')->setAttribute('xmlns', 'jabber:x:event')->addChild($server); $notify = new Node(); $notify->setName('notify')->setAttribute('xmlns', 'urn:xmpp:whatsapp')->setAttribute('name', $this->getFromName()); $request = new Node(); $request->setName('request')->setAttribute('xmlns', 'urn:xmpp:receipts'); $media = new Node(); $media->setName('media')->setAttribute('xmlns', "urn:xmpp:whatsapp:mms")->setAttribute('type', $this->getType())->setAttribute('url', $this->getUrl())->setAttribute('file', $this->getFile())->setAttribute('size', $this->getSize())->setAttribute('hash', $this->getHash())->setData($this->getIconData() ?: ''); $node = new Node(); $node->setName('message')->setAttribute('id', null)->setAttribute('t', null)->setAttribute('to', Identity::createJID($this->getTo()))->setAttribute('type', 'media')->addChild($x)->addChild($notify)->addChild($request)->addChild($media); return $node; }
public function testParseJID() { $number = '393921234567'; $ret = Identity::parseJID($number); $this->assertEquals($number, $ret); }