示例#1
0
 /**
  * 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;
 }
示例#2
0
 /**
  * @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;
 }
示例#3
0
 /**
  * @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;
 }
示例#4
0
 /**
  * @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;
 }
示例#5
0
 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]);
     }
 }
示例#6
0
 /**
  * @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;
 }
示例#7
0
 /**
  * @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;
 }
示例#8
0
 /**
  * @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')));
     }
 }
示例#9
0
 /**
  * @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;
 }
示例#10
0
 /**
  * @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));
 }
示例#11
0
 /**
  * @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;
 }
示例#12
0
 public function uploadMediaFile(MediaFile $mediaFile, Identity $identity, $uploadUrl, $to)
 {
     return $this->sendMediaFile($mediaFile, $uploadUrl, Identity::createJID($to), $identity->getPhone()->getPhoneNumber());
 }
示例#13
0
 /**
  * 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;
     });
 }
示例#15
0
 /**
  * @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;
 }
示例#16
0
 public function testParseJID()
 {
     $number = '393921234567';
     $ret = Identity::parseJID($number);
     $this->assertEquals($number, $ret);
 }