Habitica Wiki
Habitica Wiki

Habitica-side[]

Third party tools[]

There are third-party tools to set up webhooks for your Habitica account.

Webhook categories[]

With the help of those tools you can set up Habitica to listen to certain, predefined actions:

Webhook Category Action
quest activity
  • quest started
  • quest finished
  • quest invited
task activity
  • task created
  • task updated
  • task deleted
  • task checked
  • checklist item checked
user activity
  • pet hatched
  • mount raised
  • leveled up
group chat received
  • group chat received from a specific group (party/guild)

Official Habitica API-Documentation[]

Detailed information is provided by the official Habitica API-Documentation.

Example data being transferred by the webhook[]

Example-data transmitted to the Web-App (retrieved by var dataContents = e.postData.contents given function doPost(e)):

Quest invitation (including questOwner as the person starting the quest):

{"type":"questInvited","group":{"id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","name":"My Habitica Party"},quest":{"key":"owl","questOwner":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}","webhookType":"questActivity","user":{"_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}}

Quest finished:  

{"type":"questFinished","group":{"id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","name":"My Habitica Party"},"quest":{"key":"butterfly"},"webhookType":"questActivity","user":{"_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}}

Task created:

{"type":"created","task":{"challenge":{},"group":{"approval":{"required":false,"approved":false,"requested":false},"assignedUsers":[],"sharedCompletion":"singleCompletion"},"completed":false,"collapseChecklist":false,"type":"todo","notes":"","tags":[],"value":0,"priority":1,"attribute":"str","byHabitica":false,"text":"Add To Do","_id":"0ec3a680-3c8b-4e61-88f1-2848782226e9","reminders":[],"checklist":[],"createdAt":"2020-03-30T10:23:10.956Z","updatedAt":"2020-03-30T10:23:10.956Z","userId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","id":"0ec3a680-3c8b-4e61-88f1-2848782226e9"},"webhookType":"taskActivity","user":{"_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}}

Task scored:

{"type":"scored","direction":"up","delta":1,"task":{"challenge":{},"group":{"approval":{"required":false,"approved":false,"requested":false},"assignedUsers":[],"sharedCompletion":"singleCompletion"},"completed":true,"collapseChecklist":false,"type":"todo","notes":"","tags":[],"value":1,"priority":1,"attribute":"str","byHabitica":false,"checklist":[],"reminders":[],"createdAt":"2020-03-30T10:23:10.956Z","updatedAt":"2020-03-30T10:27:28.236Z","_id":"0ec3a680-3c8b-4e61-88f1-2848782226e9","text":"Add To Do","userId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","dateCompleted":"2020-03-30T10:27:28.204Z","id":"0ec3a680-3c8b-4e61-88f1-2848782226e9"},"user":{"_tmp":{"quest":{"progressDelta":1.475,"collection":1},"drop":{"target":"Desert","canDrop":true,"value":1,"key":"Potatoe","type":"Food","dialog":"You've found a Potato!"}},"stats":{"buffs":{"str":0,"int":0,"per":0,"con":0,"stealth":0,"streaks":false,"snowball":false,"spookySparkles":false,"shinySeed":false,"seafoam":false},"training":{"int":0,"per":0,"str":0,"con":0},"hp":46.35717357116706,"mp":136.94362288135568,"exp":199218.27891340942,"gp":3319.1888075206516,"lvl":931,"class":"wizard","points":0,"str":0,"con":0,"int":100,"per":0,"toNextLevel":226140,"maxHealth":50,"maxMP":527},"_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"},"webhookType":"taskActivity"}

Task deleted:

{"parameter":{},"contextPath":"","contentLength":672,"queryString":"","parameters":{},"postData":{"type":"application/json","length":672,"contents":"{\"type\":\"deleted\",\"task\":{\"challenge\":{},\"group\":{\"approval\":{\"required\":false,\"approved\":false,\"requested\":false},\"assignedUsers\":[],\"sharedCompletion\":\"singleCompletion\"},\"completed\":false,\"collapseChecklist\":false,\"type\":\"todo\",\"notes\":\"\",\"tags\":[],\"value\":-33.71057310093657,\"priority\":1,\"attribute\":\"str\",\"byHabitica\":false,\"checklist\":[],\"reminders\":[],\"createdAt\":\"2020-02-09T10:46:46.723Z\",\"updatedAt\":\"2020-03-30T10:22:43.497Z\",\"_id\":\"dc5d0acd-e889-4c42-850f-9110aef8be33\",\"text\":\"test\",\"userId\":\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\",\"id\":\"dc5d0acd-e889-4c42-850f-9110aef8be33\"},\"webhookType\":\"taskActivity\",\"user\":{\"_id\":\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"}}","name":"postData"}}

You can see that e.postData.contents may include backslashes. Please use var dataContents = JSON.parse(e.postData.contents) to parse the string.

Requirement for the Webhook to be processed is a Server that listens to the webhook. So before setting up the Habitica-webhook, please set up the server side:

Server-side (backend)[]

Google Apps Server Script (Web-App)[]

On execution of one of the certain, predefined webhook-actions, Habitica posts a request to a server, which processes the request. This server can be reached via a URL. The server will listen to POST requests from Habitica. E.g. in Google Apps Script, please use a doPost(e) function like in the example below.

Google Apps can be used to set up such a server by deploying the server-script as a Web App:

https://developers.google.com/apps-script/guides/web

Example Auto-Accept Script[]

Here is an example of a server-script that will instantly auto-accept a quest invitation:

// [Users] Required script data to fill in
const USER_ID = "PasteYourUserIdHere";
const API_TOKEN = "PasteYourApiTokenHere"; // Do not share this to anyone

// [Users] Do not edit code below this line

// [Developers] If you're authoring your own script, place your user ID and
//   script name here. If just using this as a sample, you can leave as is.
const AUTHOR_ID = "01daa187-ff5e-46aa-ac3f-d4c529a8c012";
const SCRIPT_NAME = "Faster Auto Accept Quests";
const HEADERS = {
  "x-client" : AUTHOR_ID + "-" + SCRIPT_NAME,
  "x-api-user" : USER_ID,
  "x-api-key" : API_TOKEN,
}

// [Developers] This is the function that will be executed whenever Habitica
//   encounters the event designated by the webhook
function doPost(e) {
  var dataContents = JSON.parse(e.postData.contents);
  var type = dataContents.type;

  if (type == "questInvited") {
    api_acceptQuest();
  }

  return HtmlService.createHtmlOutput();
}

function api_acceptQuest() {
  var params = {
    "method" : "post", 
    "headers" : HEADERS,
    "muteHttpExceptions" : true,
  }

  var url = "https://habitica.com/api/v3/groups/party/quests/accept";
  UrlFetchApp.fetch(url, params);
}

More examples here: (including possibility to display data on google sheets)

https://github.com/PitiTheGrey/google-script-Webhook-Server-for-Habitica

Handling the Server-Script[]

Saving, managing versions and deploying the Server-Script as Web-App:

Server Script Explanation
Save the script Save the script using "Manage Versions". Every change to the code shall be saved as a new version.
Deploy as "Web App" Every new version has to be deployed as "Web App". Deploying the script as a web-app will deliver the Server-Url (which is needed to set up the Habitica-side webhook). Changes to code and versions will not alter any given Url. For changes to take effect, it is required to deploy every new version as a web app everytime the code/version changes.
Settings for the "Web App" Deploying the script as a web-app will work for Habitica webhooks only if following settings are made:

- "Execute the script as 'Yourself'." ("Me" on google scrips)

- "Grant access to everyone, even anonymous"

URL of the Web-App On deploying the Web-App, Google shows the Web-App-URL. This is the Url you will need to set up the Habitica-side Webhook. (The Habitica-side Webhook does not require to be changed upon any new version of the server-side script!).

Questions, troubleshooting[]

General questions can be asked in Habitica's Aspiring Comrades Guild.

For specific questions, regarding the Api-Helper-Tool or the "PitiTheGrey" example server script, please ask in the Habitican Wardrobes Guild.

Piti! March 30th, 2020