ryanthomashuff

SABB (Self Aware Battle Bot) for Cisco Spark

Feb 29th, 2016
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 15.30 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4.  *
  5.  * SAAB V3 WRAPPER FOR CISCO SPARK API V1
  6.  * @author Ryan Huff <[email protected]>
  7.  * @version 3.0.1
  8.  *
  9.  */
  10.  
  11. class sabbV3
  12. {
  13.     //DB VARS
  14.     var $db = array(
  15.         'host'=>'DBHOST',
  16.         'name'=>'DBNAME',
  17.         'user'=>'DBUSER',
  18.         'pass'=>'DBPASS',
  19.         'resource'=>null,
  20.         );
  21.     var $clientId = null; //POPULATED FROM DB SCHEMA
  22.     var $clientSecret = null; //POPULATED FROM DB SCHEMA
  23.     var $appName = 'sabb'; //POPULATED FROM DB SCHEMA
  24.     //URLs
  25.     var $oauthStep1 = 'https://api.ciscospark.com/v1/authorize';
  26.     var $oauthStep2 = 'https://api.ciscospark.com/v1/access_token';
  27.     var $redirectUrl = "http://sabb.ryanthomashuff.com";
  28.     var $messagesUrl = "https://api.ciscospark.com/v1/messages";
  29.     var $peopleUrl = 'https://api.ciscospark.com/v1/people';
  30.     var $roomsUrl = 'https://api.ciscospark.com/v1/rooms';
  31.  
  32.     //SECURITY VARS
  33.     var $oauthEnabled = true;
  34.     var $useDatabase = true;
  35.     var $SparkAccessToken = null; //ADD THE DEVELOPER TOKEN IF OAUTH IS DISABLED
  36.     var $refreshToken = null;
  37.    
  38.  
  39.     /**
  40.      * Class Constructor
  41.      * Used to establish a database connection,
  42.      * pre-populate the security and refresh token,
  43.      * determine if a token refresh should occur and
  44.      * to detect inbound JSON payloads
  45.      */
  46.     function __construct()
  47.     {
  48.         if ($this->useDatabase)
  49.         {
  50.             //SETUP DB CONNECTION
  51.             $this->db['resource'] = mysqli_connect($this->db['host'], $this->db['user'], $this->db['pass']);
  52.             mysqli_select_db($this->db['resource'], $this->db['name']);
  53.             //POPULATE CLIENT ID
  54.             $result = mysqli_fetch_array(
  55.                     mysqli_query(
  56.                             $this->db['resource'],
  57.                             "SELECT * FROM securityAssets WHERE clientName='" . $this->appName . "' LIMIT 1;"
  58.                             )
  59.                     );
  60.             $this->clientId = $result['clientId'];
  61.             $this->clientSecret = $result['clientSecret'];
  62.         }
  63.  
  64.         if ($this->oauthEnabled)
  65.         {
  66.             if (!empty($result['accessToken']))
  67.             {
  68.                 $this->SparkAccessToken = $result['accessToken'];
  69.                
  70.                 if (!empty($result['refreshToken']))
  71.                 {
  72.                     $this->refreshToken = $result['refreshToken'];
  73.                 }
  74.             }
  75.             else
  76.             {
  77.                 $this->newAuth();
  78.             }
  79.            
  80.             if (!empty($result['lastRefresh']))
  81.             {
  82.                
  83.                 if ($distal = time('now') - $result['lastRefresh'] > 432000)
  84.                 {
  85.                     $this->refreshToken();
  86.                 }
  87.                
  88.             }
  89.         }
  90.         if ( $callback = json_decode(
  91.                 file_get_contents(
  92.                         'php://input'
  93.                         ),
  94.                 true
  95.                 )
  96.             )
  97.         {  
  98.             //CALLBACK TRUE (PROCESS NOTIFICATION FROM WEBHOOK)
  99.         }
  100.        
  101.         else
  102.         {
  103.             echo "
  104.            <html>
  105.            <title>Thank You!</title>
  106.            <body>
  107.            <div style='width: 100%; text-align: center;'><img src='sabb.png'/></div>
  108.            <div style='width: 100%; text-align: center;'><span style='font-family: Verdana, Helvetica, Tahoma;'>I didn't detect any notifications from Spark.</span></div>
  109.            <br />
  110.            </body>
  111.            </html>
  112.            ";
  113.            
  114.         }
  115.     }
  116.    
  117.     /**
  118.      * OAuth navigation for new token
  119.      * Used to kick off the OAuth flow for the user in the case
  120.      * where an access token or refresh token is not already
  121.      * present in the database
  122.      * @return NULL returned output is handled within method
  123.      * @USAGE
  124.      * $this->newAuth();
  125.      */
  126.     function newAuth()
  127.     {  
  128.         if (isset($_GET['code']) && !is_null($_GET['code']))
  129.         {
  130.             $context = stream_context_create(
  131.                 $this->postPayload(
  132.                     array (
  133.                         'grant_type' => 'authorization_code',
  134.                         'client_id' => $this->clientId,
  135.                         'client_secret' => $this->clientSecret,
  136.                         'code' => $_GET['code'],
  137.                         'redirect_uri' => $this->redirectUrl,
  138.                         ),
  139.                         'HTTP'
  140.                     )
  141.                 );
  142.            
  143.             $result = json_decode(file_get_contents($this->oauthStep2, false, $context));
  144.             if (@mysqli_query($this->db['resource'], "UPDATE securityAssets SET accessToken='$result->access_token', expiresIn='$result->expires_in', refreshToken='$result->refresh_token', refreshExpiresIn='$result->refresh_token_expires_in', lastRefresh='" . time('now') . "' WHERE clientName='$this->appName'"))
  145.             {
  146.                 $this->SparkAccessToken = $result->access_token;
  147.             }
  148.             echo "
  149.            <html>
  150.            <title>Thank You!</title>
  151.            <body>
  152.            <div style='width: 100%; text-align: center;'><img src='sabb.png'/></div>
  153.            <div style='width: 100%; text-align: center;'><span style='font-family: Verdana, Helvetica, Tahoma;'>Thanks for the permission!</span></div>
  154.            </body>
  155.            </html>
  156.            ";
  157.             return;
  158.            
  159.         }
  160.         $scopes = array (
  161.             'spark:rooms_read',
  162.             'spark:rooms_write',
  163.             'spark:messages_read',
  164.             'spark:messages_write',
  165.             'spark:people_read',
  166.             'spark:memberships_read',
  167.             'spark:memberships_write',
  168.             );
  169.         echo header("Location: $this->oauthStep1?response_type=code&client_id=" . urlencode($this->clientId) . "&redirect_uri=" . urlencode($this->redirectUrl) . "&scope=" . urlencode(implode(" ", $scopes)) . "&state=" . urlencode(rand(1, 63)));
  170.     }
  171.    
  172.     /**
  173.      * OAuth navigation for new token
  174.      * Used for acquiring a new access token by using
  175.      * the refresh token
  176.      * @return NULL returned output is handled within method
  177.      * @USAGE
  178.      * $this->refreshAuth();
  179.      */
  180.     function refreshAuth()
  181.     {
  182.         $context = stream_context_create(
  183.              $this->postPayload(
  184.                 array (
  185.                      'grant_type' => 'refresh_token',
  186.                      'client_id' => $this->clientId,
  187.                      'client_secret' => $this->clientSecret,
  188.                      'refresh_token' => $this->refreshToken,
  189.                      ),
  190.                      'HTTP'
  191.                 )
  192.              );
  193.  
  194.         if ($result = json_decode(file_get_contents($this->oauthStep2, false, $context)))
  195.         {
  196.             if (@mysqli_query($this->db['resource'], "UPDATE securityAssets SET accessToken='$result->access_token', expiresIn='$result->expires_in' WHERE clientName='$this->appName'"))
  197.             {
  198.                 $this->SparkAccessToken = $result->access_token;
  199.             }        
  200.         }
  201.  
  202.         return;
  203.     }
  204.    
  205.     /**
  206.      *
  207.      * @param ARRAY $data ( optional response headers )
  208.      * @return ARRAY
  209.      * @USAGE
  210.      * $this->getPayload(array('key'=>'value','key'=>'value'));
  211.      */
  212.     function getPayload( $data = null )
  213.     {
  214.         if ( is_null( $data ) )
  215.         {
  216.             return array(
  217.                 'http' => array(
  218.                     'header' => "Authorization: Bearer $this->SparkAccessToken\r\nContent-type: application/json\r\n",
  219.                     'method' => 'GET',
  220.                 ),
  221.             );
  222.         }
  223.         else
  224.         {
  225.             return array(
  226.                 'http' => array(
  227.                     'header' => "Authorization: Bearer $this->SparkAccessToken\r\nContent-type: application/json\r\n",
  228.                     'method' => 'GET',
  229.                     'content' => json_encode($data),
  230.                 ),
  231.             );                
  232.         }
  233.     }
  234.    
  235.      /**
  236.      *
  237.      * @param ARRAY $data ( optional response headers )
  238.      * @return ARRAY
  239.      * @USAGE
  240.      * $this->postPayload(array('key'=>'value','key'=>'value'), 'HTTP'); ( json or HTTP as second param to determine header type )
  241.      */
  242.     function postPayload( $data = null, $header = 'json' )
  243.     {
  244.         if ( $header == 'json' )
  245.         {
  246.             $header = "Authorization: Bearer $this->SparkAccessToken\r\nContent-type: application/json\r\n";
  247.             $content = json_encode($data);
  248.         }
  249.         else
  250.         {
  251.             $header = "Content-type: application/x-www-form-urlencoded\r\n";
  252.             $content = http_build_query($data);
  253.         }
  254.         if ( is_null( $data ) )
  255.         {
  256.             return array(
  257.                 'http' => array(
  258.                     'header' => $header,
  259.                     'method' => 'POST',
  260.                 ),
  261.             );
  262.         }
  263.         else
  264.         {
  265.             return array(
  266.                 'http' => array(
  267.                     'header' => $header,
  268.                     'method' => 'POST',
  269.                     'content' => $content,
  270.                 ),
  271.             );                
  272.         }
  273.     }
  274.    
  275.     /**
  276.      *
  277.      * @param STRING $personId ( person ID or me )
  278.      * @param STRING $email ( email address of person to look up )
  279.      * @param STRING $type ( Type of payload requested )
  280.      * @return STRING ( display name of person )
  281.      * @USAGE
  282.      * $this->people('me'); ( introspective )
  283.      * $this->people(null, '[email protected]', 'list'); ( user lookup )
  284.      */
  285.     function people( $personId = null, $email = null, $type = null )
  286.     {
  287.         if ($type == 'list')
  288.         {
  289.             $result = $this->jDecoder(
  290.                     $this->peopleUrl . '?email=' . urlencode($email),
  291.                     $this->getPayload()
  292.             );
  293.  
  294.             return array(
  295.                 'id'=>$result->items[0]->id,
  296.                 'emails'=>$result->items[0]->emails[0],
  297.                 'displayName'=>$result->items[0]->displayName,
  298.                 'avatar'=>$result->items[0]->avatar,
  299.                 'created'=>$result->items[0]->created
  300.             );
  301.                    
  302.         }
  303.         else
  304.         {
  305.             $result = $this->jDecoder(
  306.                     $this->peopleUrl . '/' . $personId,
  307.                     $this->getPayload()
  308.                     );  
  309.             return array(
  310.                 'id'=>$results->id,
  311.                 'emails'=>$result->emails[0],
  312.                 'displayName'=>$result->displayName,
  313.                 'avatar'=>$result->avatar,
  314.                 'created'=>$result->created
  315.             );
  316.        
  317.         }
  318.        
  319.     }
  320.    
  321.     /**
  322.      *
  323.      * @param STRING $roomId (ID of room to get messages from after being notified by the web hook)
  324.      * @return ARRAY
  325.      * @USAGE
  326.      * $this->getRoomMessages (' ROOM ID ');
  327.      */
  328.     function getRoomMessages ( $roomId )
  329.     {
  330.        
  331.         $data = array(
  332.             'roomId' => $roomId,
  333.             'max' => $this->sample
  334.             );
  335.        
  336.         $result = $this->jDecoder(
  337.                 $this->messagesUrl . '?' . http_build_query(
  338.                         $data
  339.                         ),
  340.                 $this->getPayload()
  341.                 );
  342.        
  343.         foreach ( $result as $item )
  344.         {
  345.             foreach ( $item as $subk => $subv )
  346.             {
  347.                 $sampleSet[] = $subv->text;
  348.             }
  349.         }
  350.  
  351.         return $sampleSet;
  352.     }
  353.    
  354.     /**
  355.      *
  356.      * @param STRING $messageId (ID of the message to get the contents of
  357.      * @return ARRAY
  358.      * @USAGE
  359.      * $this->getMessageDetail ( 'MESSAGE ID' );
  360.      */
  361.     function getMessageDetail ( $messageId )
  362.     {
  363.        
  364.         $result = $this->jDecoder(
  365.                 $this->messagesUrl . '/' . $messageid,
  366.                 $this->getPayload()
  367.                 );
  368.  
  369.         return array(
  370.             $result->text,
  371.             $result->roomId,
  372.             $this->people(
  373.                     $result->personId
  374.                     ),
  375.             $result->files,
  376.             $result->personId
  377.         );
  378.      
  379.     }
  380.    
  381.     /**
  382.      *
  383.      * @param STRING $roomId (ID of the room that the Webhook will trigger for)
  384.      * @return INT
  385.      * @USAGE
  386.      * $this->createWebhook( 'ROOM ID' );
  387.      */
  388.     function createWebhook ( $roomId )
  389.     {
  390.             $data = array(
  391.                 'name' => 'BotCallback' . substr( $roomId,-6 ),
  392.                 'targetUrl' => $this->redirectUrl,
  393.                 'resource' => 'messages',
  394.                 'event' => 'created',
  395.                 'filter' => 'roomId=' . $roomId
  396.                 );
  397.  
  398.             $result = $this->jDecoder(
  399.                     $this->webhookurl,
  400.                     $this->postPayload( $data )
  401.                     );
  402.  
  403.             return $result->id;
  404.     }
  405.    
  406.     /**
  407.      *
  408.      * @param STRING $message ( Message ID )
  409.      * @param STRING $roomId ( Room ID )
  410.      * @param STRING $url ( URL )
  411.      * @return NULL
  412.      * @USAGE
  413.      * $this->createMessage ( 'MESSAGE ID', 'ROOM ID', 'URL' ); ( URL NOT REQUIRED )
  414.      */
  415.     function createMessage ( $message, $roomId, $url = null )
  416.     {
  417.         if (is_null( $url ) )
  418.         {
  419.             $data = array(
  420.                 'roomId' => $roomId,
  421.                 'text' => $message,            
  422.             );
  423.         }
  424.         else
  425.         {
  426.             $data = array(
  427.                 'roomId' => $roomId,
  428.                 'text' => $message,
  429.                 'files' => array($url),
  430.             );
  431.         }
  432.  
  433.         $result = $this->jDecoder(
  434.                 $this->messagesurl,
  435.                 $this->postPayload($data)
  436.         );
  437.        
  438.         return null;
  439.     }
  440.    
  441.     /**
  442.      * @return ARRAY ( List of current rooms )
  443.      */
  444.     function showCurrentRooms ()
  445.     {
  446.         $result = $this->jDecoder(
  447.                 $this->roomsUrl,
  448.                 $this->getPayload(
  449.                     array(
  450.                     'showSipAddress' => true
  451.                     )
  452.                 )
  453.         );
  454.  
  455.         foreach ($result as $k=>$v)
  456.         {
  457.             foreach ($v as $subk=>$subv)
  458.             {
  459.                 $currentRooms[] = $subv->id;
  460.             }
  461.         }
  462.        
  463.         return $currentRooms;
  464.     }
  465.    
  466.     /**
  467.      *
  468.      * @param STRING $url ( URL to retrieve JSON payload from )
  469.      * @param ARRAY $payload ( array of header options )
  470.      * @return OBJECT
  471.      * @USEAGE
  472.      * $this->jDecoder( 'http://...', array() ); ( First param is the url to get the json payload from and second is the response headers )
  473.      */
  474.     function jDecoder( $url, $payload )
  475.     {
  476.         return json_decode(
  477.                 file_get_contents(
  478.                         $url,
  479.                         false,
  480.                         stream_context_create(
  481.                                 $payload
  482.                         )
  483.                 )
  484.         );
  485.     }
  486.    
  487. }
  488.  
  489. $sabb = new sabbV3();
  490.  
  491. //USAGE EXAMPLES
  492.  
  493. /** PRINT THE ROOM IDs OF ALL ROOMS CURRENTLY JOINED TO **/
  494. //print_r($sabb->showCurrentRooms());
  495.  
  496. /** CREATE A WEBHOOK IN SPARK FOR YOUR USER ACCOUNT THAT WILL NOTIFY THIS SCRIPT **/
  497. //$roomId = 'One of the room IDs shown from showCurrentRooms()';
  498. //$sabb->createWebhook ($roomId );
  499. ?>
Advertisement
Add Comment
Please, Sign In to add comment