项目作者: wenewzhang

项目描述 :
PHP7 bot for Mixin Network
高级语言: PHP
项目地址: git://github.com/wenewzhang/mixin_labs-php-bot.git
创建时间: 2019-01-10T03:27:55Z
项目社区:https://github.com/wenewzhang/mixin_labs-php-bot

开源协议:

下载


PHP Bitcoin tutorial based on Mixin Network


A Mixin messenger bot will be created in this tutorial. The bot is powered by PHP and echo message and Bitcoin from user.

Mixin network resource

What you will learn from this tutorial

  1. How to create bot in Mixin messenger and reply message to user| Chinese |Indonesian|Portuguese
  2. How to receive Bitcoin and send Bitcoin in Mixin Messenger| Chinese
  3. Create Bitcoin wallet, read balance and send Bitcoin by PHP based on Mixin Network| Chinese
  4. How to trade bitcoin through PHP language: Pay to ExinCore | Chinese
  5. How to trade bitcoin through PHP: List your order on Ocean.One | Chinese
  6. How to trade ERC-20 compliant coins on OceanOne through PHP | Chinese

Create bot in Mixin messenger and reply message to user

PHP environment setup:

This tutorial is written in PHP 7. So you need to install PHP and Composer.

On macOS

  1. brew update
  2. brew install php@7.3
  3. php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
  4. php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
  5. //install composer to /usr/local/opt/php@7.3/bin and give a brief name 'composer'
  6. php composer-setup.php --install-dir=/usr/local/opt/php@7.3/bin --filename=composer
  7. php -r "unlink('composer-setup.php');"

If you install a old php 7.1 before, execute brew unlink php@7.1 to remove the symbol links, and then execute brew link php@7.3 to link php 7.3 to php default

  1. wenewzha:mixin_labs-php-bot wenewzhang$ brew unlink php@7.1
  2. Unlinking /usr/local/Cellar/php/7.1.23... 24 symlinks removed
  3. wenewzha:mixin_labs-php-bot wenewzhang$ brew link php@7.3
  4. Warning: php@7.3 is keg-only and must be linked with --force
  5. If you need to have this software first in your PATH instead consider running:
  6. echo 'export PATH="/usr/local/opt/php@7.3/bin:$PATH"' >> ~/.bash_profile
  7. echo 'export PATH="/usr/local/opt/php@7.3/sbin:$PATH"' >> ~/.bash_profile

After the php 7.3 installed and symlinks created, according your OS environment settings, if php -v prompt “command not found”, issue echo ‘export PATH=”/usr/local/opt/php@7.3/bin:$PATH”‘ to bash_profile.

  1. echo 'export PATH="/usr/local/opt/php@7.3/bin:$PATH"' >> ~/.bash_profile
  2. echo 'export PATH="/usr/local/opt/php@7.3/sbin:$PATH"' >> ~/.bash_profile
  3. source ~/.bash_profile

On Ubuntu

  1. apt update
  2. apt upgrade
  3. //install php 7.2
  4. apt-get install software-properties-common python-software-properties
  5. add-apt-repository -y ppa:ondrej/php
  6. apt-get update
  7. apt-get install php7.2 php7.2-cli php7.2-common
  8. //install composer
  9. php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
  10. php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
  11. //install composer to /usr/local/bin and give a brief name 'composer'
  12. php composer-setup.php --install-dir=/usr/local/bin --filename=composer
  13. php -r "unlink('composer-setup.php');"

The latest composer can be download from here
Make sure the the $PATH variable contains install directory, following command can be used to check the installation

  1. wenewzha:minecraft wenewzhang$ php -v
  2. PHP 7.2.13 (cli) (built: Dec 7 2018 10:41:23) ( NTS )
  3. Copyright (c) 1997-2018 The PHP Group
  4. Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
  5. with Zend OPcache v7.2.13, Copyright (c) 1999-2018, by Zend Technologies
  6. wenewzha:minecraft wenewzhang$ composer -V
  7. Composer version 1.8.0 2018-12-03 10:31:16

Create the project

Go to your documents folder then create a directory, for example: mixin_labs-php-bot

  1. mkdir mixin_labs-php-bot
  2. mixin_labs-php-bot

Execute composer init in your project directory, follow the instruction to create the composer.json,

  1. root@iZj6cbmqen2lqp7l48nfgkZ:~/mixin_labs-php-bot# composer init
  2. Welcome to the Composer config generator
  3. This command will guide you through creating your composer.json config.
  4. Package name (<vendor>/<name>) [user/mixin_labs-php-bot]:
  5. Description []: PHP 7 bot for Mixin Messenger
  6. Author [, n to skip]: JimmyZhang <this-a-email-address@nodomain.com>
  7. Minimum Stability []:
  8. Package Type (e.g. library, project, metapackage, composer-plugin) []:
  9. License []:
  10. Define your dependencies.
  11. Would you like to define your dependencies (require) interactively [yes]? no
  12. Would you like to define your dev dependencies (require-dev) interactively [yes]? no
  13. {
  14. "name": "user/mixin_labs-php-bot",
  15. "description": "PHP 7 bot for Mixin Messenger",
  16. "authors": [
  17. {
  18. "name": "JimmyZhang",
  19. "email": "this-a-email-address@nodomain.com"
  20. }
  21. ],
  22. "require": {}
  23. }
  24. Do you confirm generation [yes]? yes

This tutorial requires two libraries.

In composer.json file, add the two libraries in the “require” code block.

  1. "require": {
  2. "exinone/mixin-sdk-php": "^1.1",
  3. "ratchet/pawl": "^0.3.3",
  4. },

Save composer.json file and then execute composer install to download required libraries.

  1. composer install

A vendor directory is created in the project directory after all libraries are downloaded.

  1. root@iZj6cbmqen2lqp7l48nfgkZ:~/mixin_labs-php-bot# ls
  2. composer.json composer.lock vendor

If you clone this repository from Github repo, you only need to execute composer install to download all libraries.

Create your first app in Mixin Network developer dashboard

You need to create an app in dashboard. This tutorial can help you.

Generate parameter of your app in dashboard

After app is created in dashboard, you still need to generate parameter
and write down required content, these content will be written into config.php file.

mixin_network-keys
In project folder, create a file: config.php. Copy the following content into it.

config.php

  1. <?php
  2. return [
  3. 'mixin_id' => '7000101716',
  4. 'client_id' => 'a1ce2967-a534-417d-bf12-c86571e4eefa',
  5. 'client_secret' => '7339866727d24eeec1c4ebb6c634fd25a7b9057ee6d5939cca9b6b9fc15f4d1f',
  6. 'pin' => '512772',
  7. 'pin_token' => 'abRdNq6soRALRG434IgR7WS/qP7LOcpfviqSfWfABdIKyZGLnWXFMrVCHpChIkBRGRAcsUguni0OoNsShddPVL3qoD5fxbF5dRUiRv14urH1Pmdl6zIZdCH159QMr5wLmmSHSGu2AihNkUHUo3bAJsrvOW0nke5y6R5YE/pNNfo=',
  8. 'session_id' => '51faabbf-48ff-4df2-898d-e9b318afae35',
  9. 'private_key' => <<<EOF
  10. -----BEGIN RSA PRIVATE KEY-----
  11. MIICXQIBAAKBgQCuKI65sJR9lQ1+kyKouWu3CpmkPdJKaFqKVMEWk9RRH1Wgju9n
  12. z/y5MiBVZKUeeIYtwrCNKbbdkSPqMoj1kLh5XUk4HaV9DUt+s9USBHOgU8m5Pxov
  13. Km+HQ+Pam62lHWn6ClYaNrDihpcdDg9i7Y8hY1cgKiUcdkFQmDQ9lz2VHwIDAQAB
  14. AoGANHJSSOk8TnVMkwmMLnNoVL8EdcmIQpAac/4CB+KM1cEx8CAbSJAB82N9CTo9
  15. 32c8QRuYP2qIf0DuJ+EADbN/Wc3o9zRY3dkbnLo144g3YaKwDccSgUMux03ANHlP
  16. MEPDxOUbxJTRPXmKgUZmGJrkAClGbr3pPyQDDHDWRQc9JUECQQDT7pUYcXtu+hSc
  17. nAlZllzqkBG2gZrDYpPJ0JirpfNhaApBo+CGZYKQ1961o6+HcI9gZmZA8hPEhT6p
  18. PlubjqxbAkEA0l89du8TIUGrY9/sxyfZif6aeEztXPwBHZ9r8dm0L8Mlu5zTrOX2
  19. SUgu3znM6djmuRMS45iPHJbPkvw9ilaljQJBAJRN323Ec/D79ZKGKpDThN/rw0lo
  20. tolFoU/Xtg5fycl/CbZXXFYQEOcU+Nc43Ss1HFAEOEf4Xtbluyyp42ce1wMCQElv
  21. P4htyhK41rglaYTXr0NRYeCOkej8evM5PDgPU6u8hkZoZyeamo9YKCx6A8K5mUiP
  22. lO9nyMUlC852SJEqz90CQQDBguGg5GGcfehpIZwERlMJgKGg1+13/9GfnEPdAW2v
  23. px7DZoMG/pQ/SEa53tJHmGGD9+qyp93z/fEPXsD5RSwx
  24. -----END RSA PRIVATE KEY-----
  25. EOF
  26. , //import your private_key
  27. ];

Replace the value with content generated in dashboard.

Hello world in PHP

Copy the following code into app.php, create app.php file if it is missing in your folder

  1. <?php
  2. require __DIR__ . '/vendor/autoload.php';
  3. use ExinOne\MixinSDK\Traits\MixinSDKTrait;
  4. use ExinOne\MixinSDK\MixinSDK;
  5. use Ramsey\Uuid\Uuid;
  6. use Ratchet\RFC6455\Messaging\Frame;
  7. $loop = \React\EventLoop\Factory::create();
  8. $reactConnector = new \React\Socket\Connector($loop, [
  9. 'timeout' => 15
  10. ]);
  11. $connector = new \Ratchet\Client\Connector($loop,$reactConnector);
  12. class callTraitClass {
  13. use MixinSDKTrait;
  14. public $config;
  15. public function __construct()
  16. {
  17. $config = require(__DIR__.'/config.php');
  18. $this->config = $config;
  19. }
  20. }
  21. $callTrait = new callTraitClass();
  22. $Token = $callTrait->getToken('GET', '/', '');
  23. // $connector('ws://127.0.0.1:9000', ['protocol' => 'Mixin-Blaze-1'], ['Origin' => 'http://localhost',
  24. $connector('wss://blaze.mixin.one', ['protocol' => 'Mixin-Blaze-1'],[
  25. 'Authorization' => 'Bearer '.$Token
  26. ])
  27. ->then(function(Ratchet\Client\WebSocket $conn) {
  28. $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
  29. $jsMsg = json_decode(gzdecode($msg));
  30. print_r($jsMsg);
  31. if ($jsMsg->action === 'CREATE_MESSAGE' and property_exists($jsMsg,'data')) {
  32. echo "\nNeed reply server a receipt!\n";
  33. $RspMsg = generateReceipt($jsMsg->data->message_id);
  34. $msg = new Frame(gzencode(json_encode($RspMsg)),true,Frame::OP_BINARY);
  35. $conn->send($msg);
  36. if ($jsMsg->data->category === 'PLAIN_TEXT') {
  37. $msgData = sendPlainText($jsMsg->data->conversation_id,
  38. base64_decode($jsMsg->data->data));
  39. $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY);
  40. $conn->send($msg);
  41. } //end of PLAIN_TEXT
  42. } //end of CREATE_MESSAGE
  43. });
  44. $conn->on('close', function($code = null, $reason = null) {
  45. echo "Connection closed ({$code} - {$reason})\n";
  46. });
  47. /* start listen for the incoming message */
  48. $message = [
  49. 'id' => Uuid::uuid4()->toString(),
  50. 'action' => 'LIST_PENDING_MESSAGES',
  51. ];
  52. print_r(json_encode($message));
  53. $msg = new Frame(gzencode(json_encode($message)),true,Frame::OP_BINARY);
  54. $conn->send($msg);
  55. // $conn->send(gzencode($msg,1,FORCE_DEFLATE));
  56. }, function(\Exception $e) use ($loop) {
  57. echo "Could not connect: {$e->getMessage()}\n";
  58. $loop->stop();
  59. });
  60. $loop->run();
  61. function sendPlainText($conversation_id,$msgContent):Array {
  62. $msgParams = [
  63. 'conversation_id' => $conversation_id,
  64. 'category' => 'PLAIN_TEXT',
  65. 'status' => 'SENT',
  66. 'message_id' => Uuid::uuid4()->toString(),
  67. 'data' => base64_encode($msgContent),//base64_encode("hello!"),
  68. ];
  69. $msgPayButton = [
  70. 'id' => Uuid::uuid4()->toString(),
  71. 'action' => 'CREATE_MESSAGE',
  72. 'params' => $msgParams,
  73. ];
  74. return $msgPayButton;
  75. }
  76. function generateReceipt($msgID):Array {
  77. $IncomingMsg = ["message_id" => $msgID, "status" => "READ"];
  78. $RspMsg = ["id" => Uuid::uuid4()->toString(), "action" => "ACKNOWLEDGE_MESSAGE_RECEIPT",
  79. "params" => $IncomingMsg];
  80. return $RspMsg;
  81. }

Run the code

  1. php app.php

The following content will be displayed in console.

  1. wenewzha:mixin_labs-php-bot wenewzhang$ php helloworld.php
  2. a1ce2967-a534-417d-bf12-c86571e4eefa{"id":"4454b6c5-4a89-440c-bd22-7a79cf4954ca","action":"LIST_PENDING_MESSAGES"}stdClass Object
  3. (
  4. [id] => 4454b6c5-4a89-440c-bd22-7a79cf4954ca
  5. [action] => LIST_PENDING_MESSAGES
  6. )

Add the bot(for example, this bot id is 7000101639) as your friend in Mixin Messenger and send your messages.
mixin_messenger

Source code summary

The PHP code creates a websocket client.

  1. $loop = \React\EventLoop\Factory::create();
  2. $reactConnector = new \React\Socket\Connector($loop, [
  3. 'timeout' => 15
  4. ]);
  5. $connector = new \Ratchet\Client\Connector($loop,$reactConnector);

The code generates a valid token and creates connection between the websocket and Mixin Messenger server. Messages will be pushed to websocket client.

API of the operation, Guide of the operation

The mixin-sdk-php implements the getToken function, call it and generate a token.

  1. class callTraitClass {
  2. use MixinSDKTrait;
  3. public $config;
  4. public function __construct()
  5. {
  6. $config = require(__DIR__.'/config.php');
  7. $this->config = $config;
  8. }
  9. }
  10. $callTrait = new callTraitClass();
  11. $Token = $callTrait->getToken('GET', '/', '');

Connect to Mixin messenger server with the correct token.

  1. $connector('wss://blaze.mixin.one', ['protocol' => 'Mixin-Blaze-1'],[
  2. 'Authorization' => 'Bearer '.$Token
  3. ])

Send “LIST_PENDING_MESSAGES” to server to receive pending messages.

  1. /* start listen for the incoming message */
  2. $message = [
  3. 'id' => Uuid::uuid4()->toString(),
  4. 'action' => 'LIST_PENDING_MESSAGES',
  5. ];
  6. print_r(json_encode($message));
  7. $msg = new Frame(gzencode(json_encode($message)),true,Frame::OP_BINARY);
  8. $conn->send($msg);

onMessage function will be called when message is pushed to websocket client.

  1. ->then(function(Ratchet\Client\WebSocket $conn) {
  2. $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
  3. $jsMsg = json_decode(gzdecode($msg));
  4. print_r($jsMsg);
  5. if ($jsMsg->action === 'CREATE_MESSAGE' and property_exists($jsMsg,'data')) {
  6. echo "\nNeed reply server a receipt!\n";
  7. $RspMsg = generateReceipt($jsMsg->data->message_id);
  8. $msg = new Frame(gzencode(json_encode($RspMsg)),true,Frame::OP_BINARY);
  9. $conn->send($msg);
  10. if ($jsMsg->data->category === 'PLAIN_TEXT') {
  11. $msgData = sendPlainText($jsMsg->data->conversation_id,
  12. base64_decode($jsMsg->data->data));
  13. $msg = new Frame(gzencode(json_encode($msgData)),true,Frame::OP_BINARY);
  14. $conn->send($msg);
  15. } //end of PLAIN_TEXT
  16. } //end of CREATE_MESSAGE
  17. });
  18. $conn->on('close', function($code = null, $reason = null) {
  19. echo "Connection closed ({$code} - {$reason})\n";
  20. });

Not only text, images and other type message will be pushed to your bot. You can find more details about Messenger message.

Send a READ operation message to the server let it knows this message has been read. The bot will receive the duplicated message when the bot connected to server again if bot don’t send response.

  1. echo "\nNeed reply server a receipt!\n";
  2. $RspMsg = generateReceipt($jsMsg->data->message_id);
  3. $msg = new Frame(gzencode(json_encode($RspMsg)),true,Frame::OP_BINARY);
  4. $conn->send($msg);
  5. function generateReceipt($msgID):Array {
  6. $IncomingMsg = ["message_id" => $msgID, "status" => "READ"];
  7. $RspMsg = ["id" => Uuid::uuid4()->toString(), "action" => "ACKNOWLEDGE_MESSAGE_RECEIPT",
  8. "params" => $IncomingMsg];
  9. return $RspMsg;
  10. }

End

Now your bot worked, you can hack it.

Full code is here