💁

Adding an AI Assistant to all Podio

Have you ever wanted Chat GPT generally available in all of your Podio workspaces? This is possible.

We’ve previously shared how to use OpenAI via ProcFu, and now we’ll take it one step further. We want to be able to assign tasks to our assistant, and get responses based on the current item.

In short:

  1. On any Podio item, assign a task ✅
  1. Get an AI response 💬

🤖

This blog post describes a more complex process on how to implement AI in Podio. It requires some logic and code to work.

If you just want to have Chat GPT available in your Podio Workspaces, use the built-in service in ProcFu. Easy mode - No code required. See: https://procfu.com/site/gpt/

But Why?

There are numerous use-cases for this, and I’m sure you’ll keep coming up with new ones once you start using this process.

Here are some basic examples I’ve come up with so far:

Demo

The Setup

To set this up is actually rather easy. You will need:

All we need then is:

  1. A script to deal with hooks when a task is created and do the work
  1. Another script to install the required hooks on all your Podio spaces

Webhook Code

The code for the webhook is event handler is as follows:

// AI task event webhook
// fires when a task is assigned to a specific user
// gets a response from open ai 
// includes item payload as context if task is on an item

// configuration
$userId = 1460572;          // user_id of the user having tasks assigned to them - ignore all other tasks
// end configuration

// verify webhook in podio
if ( $payload["POST"]["type"] == "hook.verify" ) {
	// ayload: {"GET":[],"POST":{"type":"hook.verify","hook_id":"24167225","code":"91e900c0"},"FILES":[],"STDIN":"type=hook.verify&hook_id=24167225&code=91e900c0"}
	$hookId = $payload["POST"]["hook_id"];
	$url = "/hook/"+$hookId+"/verify/validate";
	$attributes = [
		"code" => $payload["POST"]["code"]
	];
	$options = [];
	podio_api_raw_curl($url, "POST", json_encode($options), json_encode($attributes));
	return;
}

// we're only interested in item created at this point
if ( $payload["POST"]["type"] != "task.create" ) {
	return;
}

// OK - item was created
$taskId = $payload["POST"]["task_id"];

// get the task from Podio
$task = podio_task_get($taskId);
if ( ! $task ) return;

// make sure task is assigned to required user
$responsible = $task["responsible"]["user_id"];
if ( $responsible != $userId ) return;

// task details
$title = $task["text"];
$description = $task["description"];

// get related item if applicable
$context = false;
if ( $task["ref"]["type"] == "item" ) {
	$context = "Provided Context JSON data of Podio Item:\n";
	$context += podio_item_get_raw($task["ref"]["id"]);
}

// build query prompt
$instructions = "Keep your response short and to-the-point";
$query = "Your Task: "+$title + "\n" + $description + "\n\n" + $context+"\n\n"+$instructions;

// increase max_execution_time to maximum allowed in case openai is slow
ini_set("max_execution_time", 120);

// get response from open ai
$response = open_ai_gpt($query);

// create comment on task with open ai response
$url = "/comment/task/"+$taskId+"/";
$attributes = [
	"value" => $response;
];
$options = [];
podio_api_raw_curl($url, "POST", json_encode($options), json_encode($attributes));

// complete task - uncomment below if you want this functionality
//$url = "/task/"+$taskId+"/complete";
//podio_api_raw_curl($url, "POST");

You will need to do 2 things with this code:

  1. Change the $userId value to the user_id of the PF account holder that will be handling these tasks
  1. Make sure that the “Mode” of the script is “HTTP - via URL”, and record the URL. You’ll need that later

Creating the Hooks

To make it easier to create the hooks in all your spaces, here’s a small script you can run directly in the ProcFu Code editor:

// add task create space hooks to all admin spaces for current user

// configuration
global $hookUrl;
$hookUrl = "https://procfu.com/widgets/code/ax235ac6g04azcf24e3afun";    // URL of PF webhook script 
// end configuration

// get all orgs & spaces
$orgs = podio_orgs_get_raw();
foreach ( $orgs as $org ) {
	print "## Checking hooks in org " + $org["name"];
	foreach ( $org["spaces"] as $space ) {
		if ( $space["role"] != "admin" ) continue;
		// if we're an admin, make sure hooks are present for task.create
		$spaceId = $space["space_id"];
		ensureHook($spaceId);
	}
}

print "DONE";


function ensureHook($spaceId) {
	// get existing hooks for space
	$hooks = podio_hooks_get_raw("space", $spaceId);
	// [{"hook_id":24167225,"status":"inactive","type":"task.create","url":"https:\/\/procfu.com\/widgets\/code\/a9225ac6904afcf2fe3abun3","created_on":"2025-10-31 12:57:25","created_by":{"type":"user","id":1460572},"created_via":{"id":27227,"auth_client_id":27227,"name":"ProcFu","url":null,"display":true}}]

	// find if there is an existing hook in space
	$found = false;
	foreach ( $hooks as $hook ) {
		if ( $hook["type"] != "task.create" ) continue;
		if ( $hook["url"] != $hookUrl ) continue;
		$found = $hook;
		break;
	}
	
	// no hook found - create one
	if ( ! $found ) {
		print "creating task.create hook for space " + $spaceId;
		$url = "/hook/space/"+$spaceId+"/";
		$attributes = [
			"url" => $hookUrl,
			"type" => "task.create"
		];
		$options = [];
		$hook = podio_api_raw_curl($url, "POST", json_encode($options), json_encode($attributes));
	}
	
	// hook found but not active - validate it
	if ( $hook["status"] != "active" ) {
		print "validating hook for space " + $spaceId;
		$hookId = $hook["hook_id"];
		$url = "/hook/"+$hookId+"/verify/request";
		$attributes = [];
		$options = [];
		podio_api_raw_curl($url, "POST", json_encode($options), json_encode($attributes));
		$hook["status"] = "active";
	}
	
	// hook is good
	if ( $hook["status"] == "active" ) {
		//print "hook for space " + $spaceId + ": OK";
	}
}

All you need to do with this script is to change the $hookUrl to the URL of your webhook event processing script obtained from the previous step.

Then run the script.

You can re-run it at any time to ensure that hooks are present and active in all spaces that this user has access to.

In Action

As an example, I’m going to use a ticket in our ProcFu helpdesk app in Podio:

To get some assistance, I’m going to assign a task to our AI helper asking for some insight and guidance:

And within a few seconds, I got this back:

The assistant correctly identified 1 error, 1 spelling mistake in the code, and provided some good debugging options. I could basically copy-paste this as a response.

It’s worth noting that the AI has the full Podio Item as it’s context, so you can ask it some pretty in-depth questions. It has all the fields (obviously) and all comments!.

Taking it further

There are numerous ways to extend this even further. I just wanted to give you a basic starting point and some quick code to get you up and running.

Here are some ideas for extending this system: