OpenAI Assistants API PHP Integration


Noah Wilson

Published: Jul. 16th, 2024


OpenAI Assistants API PHP Integration

In this blog article, we will dive into the functionality of a PHP class designed to interact with OpenAI's assistants API. We will break down the code step-by-step to understand its purpose and functionality.

Class Definition


class openai_php {
	
	private $endpoint;
	private $apikey;
	private $assistant_id;
	
	function __construct() {
		$this->endpoint = "https://api.openai.com";
		$this->apikey = "--YOUR--API-KEY--HERE--";
		$this->assistant_id = "--YOUR--ASSISTANT--ID-HERE--";
	}

The `openai_php` class begins with the definition of three private properties: `$endpoint`, `$apikey`, and `$assistant_id`. These properties store the base URL of the OpenAI API, the API key for authentication, and the assistant ID, respectively.

The constructor function (`__construct()`) initializes these properties with predefined values. Users of this class must replace the placeholder values with their actual API key and assistant ID.

Creating a Thread


	function create_thread() {
		$response = [];
		$url = $this->endpoint . "/v1/threads";
		
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , "Authorization: Bearer ".$this->apikey, 'OpenAI-Beta: assistants=v2' ));
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
		
		if(($result = curl_exec($ch)) === false){
			$response['code'] = 0;
			$response['msg'] = curl_error($ch);
		} else {
			$response['code'] = 1;
			$response['msg'] = json_decode($result)->id;
		}
		
		$response['source'] = 'create_thread()';
		curl_close($ch);
		return $response;
	}

The `create_thread` function initiates a new thread with the OpenAI API. It constructs the URL for the API request and sets up a cURL session. The function specifies HTTP headers, including the API key and content type. It sends a POST request to the `/v1/threads` endpoint.

If the cURL request fails, the function returns an error message. If successful, it decodes the response to retrieve the thread ID and returns it along with a success code.

Creating a Message


	function create_message($thread_id, $post) {
		$response = [];
		$url = $this->endpoint . "/v1/threads/" . $thread_id . "/messages";
		
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , "Authorization: Bearer ".$this->apikey, 'OpenAI-Beta: assistants=v2' ));
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	
		if(($result = curl_exec($ch)) === false){
			$response['code'] = 0;
			$response['msg'] = curl_error($ch);
		} else {
			$response['code'] = 1;
			$response['msg'] = json_decode($result)->id;
		}
		
		$response['source'] = 'create_message()';
		curl_close($ch);
		return $response;
	}

The `create_message` function adds a message to a specified thread. It takes two parameters: the thread ID and the message content (`$post`). The function constructs the URL for the API request, sets up a cURL session, and specifies the necessary HTTP headers.

It sends a POST request to the `/v1/threads/{thread_id}/messages` endpoint with the message content. The function handles the cURL response similarly to `create_thread`, returning either an error or the message ID.

Running a Thread


	function run_thread($thread_id){
		$response = [];
		$url = $this->endpoint . "/v1/threads/" . $thread_id . "/runs";
	
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , "Authorization: Bearer ".$this->apikey, 'OpenAI-Beta: assistants=v2' ));
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_POSTFIELDS, '{"assistant_id": "'.$this->assistant_id.'"}');
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	
		if(($result = curl_exec($ch)) === false){
			$response['code'] = 0;
			$response['msg'] = curl_error($ch);
		} else {
			$response['code'] = 1;
			$response['msg'] = json_decode($result)->id;
		}
		
		$response['source'] = 'run_thread()';
		curl_close($ch);
		return $response;
	}

The `run_thread` function initiates the execution of a thread. It takes the thread ID as a parameter and constructs the URL for the API request. The function sets up a cURL session and specifies the HTTP headers, including the assistant ID in the request body.

It sends a POST request to the `/v1/threads/{thread_id}/runs` endpoint. The function handles the cURL response, returning either an error or the run ID.

Listing Thread Messages


	function list_thread_messages($thread_id) {
		$response = [];
		$url = $this->endpoint . "/v1/threads/" . $thread_id . "/messages";
		
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , "Authorization: Bearer ".$this->openai_apikey, 'OpenAI-Beta: assistants=v2' ));
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
		
		if(($result = curl_exec($ch)) === false){
			$response['code'] = 0;
			$response['msg'] = curl_error($ch);
		} else {
			$response['code'] = 1;
			$response['msg'] = json_decode($result);
		}
		
		$response['source'] = 'list_thread_messages()';
		curl_close($ch);
		return $response;
	}

The `list_thread_messages` function retrieves all messages from a specified thread. It takes the thread ID as a parameter, constructs the URL for the API request, and sets up a cURL session. The function sends a GET request to the `/v1/threads/{thread_id}/messages` endpoint.

It handles the cURL response, returning either an error or the list of messages.

Retrieving the Next Message


	function _retrieve_next_message($thread_id, $parent_message_id) {
		$messageList = $this->list_thread_messages($thread_id);
		if(intval($messageList['code']) === 0){
			return $messageList;
		}
		
		if($parent_message_id === $messageList['msg']->first_id){
			sleep(2);
			return $this->_retrieve_next_message($thread_id, $parent_message_id);
		}
		return $messageList['msg']->first_id;
	}

The `_retrieve_next_message` function is a private helper function that recursively retrieves the next message in a thread. It takes the thread ID and the parent message ID as parameters.

The function calls `list_thread_messages` to get the list of messages. If the parent message ID matches the first message ID in the list, it waits for 2 seconds and retries. Otherwise, it returns the first message ID.

Retrieving a Specific Message


	function retrieve_message($thread_id, $message_id) {
		$response = [];
		$url = $this->endpoint . "/v1/threads/" . $thread_id . "/messages/" . $message_id;
	
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , "Authorization: Bearer ".$this->openai_apikey, 'OpenAI-Beta: assistants=v2' ));
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	
		if(($result = curl_exec($ch)) === false){
			$response['code'] = 0;
			$response['msg'] = curl_error($ch);
		} else {
			$response['code'] = 1;
			$response['msg'] = json_decode($result)->content[0]->text->value;
		}
		
		$response['source'] = 'retrieve_message()';
		curl_close($ch);
		return $response;
	}
}

The `retrieve_message` function retrieves a specific message from a thread. It takes the thread ID and message ID as parameters, constructs the URL for the API request, and sets up a cURL session. The function sends a GET request to the `/v1/threads/{thread_id}/messages/{message_id}` endpoint.

It handles the cURL response, returning either an error or the message content.

Example Execution Flow


$i = new openai_php();

$post = '{"role": "user", "content": "What is the square root of 64?"}';

$thread_r = $i->create_thread();
if(intval($thread_r['code']) === 0){
	echo '<pre>';
	print_r($thread_r);
	echo '</pre>';
	exit(0);
}
$thread_id = $thread_r['msg'];

$message_r = $i->create_message($thread_id, $post);
if(intval($message_r['code']) === 0){
	echo '<pre>';
	print_r($message_r);
	echo '</pre>';
	exit(0);
}
$parent_message_id = $message_r['msg'];

$run_r = $i->run_thread($thread_id);
if(intval($run_r['code']) === 0){
	echo '<pre>';
	print_r($run_r);
	echo '</pre>';
	exit(0);
}
$message_id = $i->_retrieve_next_message($thread_id, $parent_message_id);

$retrieve_r = $i->retrieve_message($thread_id, $message_id);
if(intval($retrieve_r['code']) === 0){
	echo '<pre>';
	print_r($retrieve_r);
	echo '</pre>';
	exit(0);
}

$response = $retrieve_r['msg'];
echo $response;

The main execution flow demonstrates the use of the openai_php class to interact with the OpenAI API:

  1. An instance of the `openai_php` class is created.
  2. A thread is created using the `create_thread` function.
  3. A message is added to the thread using the `create_message` function.
  4. The thread is run using the `run_thread` function.
  5. The next message ID is retrieved using the `_retrieve_next_message` function.
  6. The specific message is retrieved using the `retrieve_message` function.
  7. The response message is printed.

This code showcases how to manage threads and messages with the OpenAI API, making it a useful tool for developers looking to integrate OpenAI's capabilities into their PHP applications.