Skip to content
xPuddaPublic

About

Unofficial Home Assistant integration for Tryber: earnings, experience points, monthly ranking and new campaign alerts

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

16 Commits

Folders and files

Repository files navigation

Tryber for Home Assistant

hacs license

Unofficial custom integration for the tester APIs of Tryber (AppQuality). Exposes your earnings, experience points, monthly ranking and available campaigns as sensors, and notifies you when a new applicable campaign appears.

Installation

HACS (recommended)

  1. HACS > Integrations > top-right menu > Custom repositories
  2. URL https://github.com/xPudda/TryberHA, category Integration
  3. Search for Tryber, install and restart Home Assistant

Manual

  1. Copy the custom_components/tryber folder to /config/custom_components/
  2. Restart Home Assistant
  3. Settings > Devices & services > Add integration > Tryber
  4. Enter your username (e.g. first-last) and password

The username is the account one, it doesn't always match the email.

Authentication

  • Login via POST /authenticate with username and password
  • The bearer token is kept in memory and reused until expiry (the API issues it with a 24h validity)
  • Automatic renewal 10 minutes before expiry, plus an immediate retry on a 401 mid-refresh
  • If the password changes, HA starts the re-authentication flow

Credentials

Your password is needed at every token renewal, so Home Assistant keeps it in the config entry, unencrypted, in /config/.storage/core.config_entries — as it does for every integration. Anyone who can read that folder, or an unencrypted backup of it, can read the password.

Recommended:

  • Use a password unique to Tryber
  • Keep Home Assistant backups encrypted
  • Restrict access to the configuration folder

Polling

Every 2 minutes, with 6 parallel calls: users/me (selected fields), users/me/rank, three queries on users/me/campaigns (applicable, accepted, active) and one on users/me/bugs.

Entities created

Home Assistant builds the entity IDs from the device name and the entity name, following Settings > System > Entity ID format. With the default format and the default device name Tryber First Last you get sensor.tryber_first_last_net_earnings; rename the device to Tryber if you prefer the shorter sensor.tryber_net_earnings.

Entity Entity ID suffix Description
Net earnings net_earnings Already paid out earnings (net)
Gross earnings gross_earnings Already paid out earnings (gross)
Net pending earnings net_pending_earnings Accrued but not yet paid (net)
Gross pending earnings gross_pending_earnings Accrued but not yet paid (gross)
Payout threshold payout_threshold Minimum threshold to request payout
Experience points experience_points Total experience points
Approved bugs approved_bugs Approved bugs
Attended campaigns attended_campaigns Campaigns you took part in
Ranking position ranking_position Position in the monthly ranking
Monthly level monthly_level Current level (Bronze, Gold...)
Monthly points monthly_points Points for the current month
Points to next level points_to_next_level Points missing to the next level
Available campaigns available_campaigns Campaigns you can apply to
Accepted campaigns accepted_campaigns Campaigns you've been selected for
Active campaigns active_campaigns Campaigns you're selected for that are still running
Latest available campaign latest_available_campaign Name of the most recent applicable one
Payout threshold reached payout_threshold_reached binary_sensor, on when you can cash out
Bug info requested bug_info_requested binary_sensor, on when at least one of your bugs needs more info

Changing the entity ID format only affects newly created entities: the ones you already have keep their current ID. Entity names are in English and are not translated.

Automation example

The examples below use the short entity IDs: replace them with yours.

automation:
  - alias: "Tryber - can cash out"
    triggers:
      - trigger: state
        entity_id: binary_sensor.tryber_payout_threshold_reached
        to: "on"
    actions:
      - action: notify.mobile_app_iphone_16
        data:
          title: "Tryber"
          message: >-
            Threshold reached: {{ states('sensor.tryber_net_pending_earnings') }} EUR
            available to request.

  - alias: "Tryber - new campaigns available"
    triggers:
      - trigger: numeric_state
        entity_id: sensor.tryber_available_campaigns
        above: 0
    actions:
      - action: notify.mobile_app_iphone_16
        data:
          message: >-
            There are {{ states('sensor.tryber_available_campaigns') }} campaigns available.

  - alias: "Tryber - a bug needs more info"
    triggers:
      - trigger: state
        entity_id: binary_sensor.tryber_bug_info_requested
        to: "on"
    actions:
      - action: notify.mobile_app_iphone_16
        data:
          title: "Tryber"
          message: >-
            {{ state_attr('binary_sensor.tryber_bug_info_requested', 'count') }}
            bug(s) waiting for more info from you.

Notification when a new campaign appears

The integration queries /users/me/campaigns and keeps only the campaigns with visibility.type == "available", i.e. the ones you can actually apply to (the others are candidate or unavailable).

When an id that was never seen before appears, the tryber_new_campaign event is fired on the bus with this data:

Field Content
id Campaign id
name Campaign name
start_date / end_date Campaign dates
close_date Application deadline
free_spots / total_spots Free and total spots
applied Whether you've already applied

Already-seen ids are persisted to disk: after an HA restart you won't get notified again for already-known campaigns. On the very first startup nothing is notified, only the starting state is recorded.

Notification automation

automation:
  - alias: "Tryber - new campaign available"
    triggers:
      - trigger: event
        event_type: tryber_new_campaign
    actions:
      - action: notify.mobile_app_iphone_16
        data:
          title: "New Tryber campaign"
          message: >-
            {{ trigger.event.data.name }}
            {% if trigger.event.data.free_spots is not none %}
            - {{ trigger.event.data.free_spots }} free spots
            {% endif %}
            {% if trigger.event.data.close_date %}
            (apply by {{ trigger.event.data.close_date }})
            {% endif %}
          data:
            url: "https://app.tryber.me/campaigns/{{ trigger.event.data.id }}"
            push:
              interruption-level: time-sensitive

A variant that only notifies if there are free spots:

    conditions:
      - condition: template
        value_template: >-
          {{ trigger.event.data.free_spots is none
             or trigger.event.data.free_spots > 0 }}

Related entities

  • sensor.tryber_available_campaigns - how many there are, with the full list in the campaigns attribute (useful in templates)
  • sensor.tryber_latest_available_campaign - name of the first one in the list, with id, spots and deadline in the attributes

To list them all in a Markdown card:

{% for c in state_attr('sensor.tryber_available_campaigns', 'campaigns') %}
- **{{ c.name }}** ({{ c.free_spots }}/{{ c.total_spots }} spots)
{% endfor %}

Notification when you get selected for a campaign

The integration also queries /users/me/campaigns with filterBy[accepted]=1, which returns only the campaigns your application was accepted for, and keeps those that haven't ended yet.

When a campaign id shows up there for the first time, the tryber_campaign_selected event is fired on the bus with this data:

Field Content
id Campaign id
name Campaign name
start_date / end_date Campaign dates
close_date Application deadline
campaign_type Campaign type (e.g. Functional, Experience)

Like new campaigns, selections are persisted to disk and the very first startup only records the starting state without notifying anything.

automation:
  - alias: "Tryber - selected for a campaign"
    triggers:
      - trigger: event
        event_type: tryber_campaign_selected
    actions:
      - action: notify.mobile_app_iphone_16
        data:
          title: "You're in!"
          message: >-
            Selected for {{ trigger.event.data.name }}
            {% if trigger.event.data.end_date %}
            (until {{ trigger.event.data.end_date }})
            {% endif %}
          data:
            url: "https://app.tryber.me/campaigns/{{ trigger.event.data.id }}"

The full list of campaigns you're currently working on is in the campaigns attribute of sensor.tryber_active_campaigns.

Bugs waiting for more info

binary_sensor.tryber_bug_info_requested turns on when at least one bug you reported is in the Need Review status, i.e. still open (neither approved nor refused) and waiting for extra information from you.

Attributes:

  • count - how many bugs are in that state
  • bugs - the list, each with id, title, campaign, campaign_id and severity
{% for b in state_attr('binary_sensor.tryber_bug_info_requested', 'bugs') %}
- **{{ b.title }}** ({{ b.campaign }})
{% endfor %}

Requirements

  • Home Assistant 2024.11 or later
  • No additional Python dependencies

Contributing

Pull requests and issues are welcome. The project is released under the MIT license: you can fork, modify and redistribute it, keeping the copyright notice.

Disclaimer

Unofficial project, not affiliated with nor supported by AppQuality / Tryber. It only uses user-area endpoints with your own personal credentials. Mentioned trademarks belong to their respective owners. The Tryber logo in custom_components/tryber/brand is © AppQuality, used only to identify the integration in the Home Assistant UI; it is not covered by this repository's MIT license.

License

MIT (c) 2026 Nicola Rodella

About

Unofficial Home Assistant integration for Tryber: earnings, experience points, monthly ranking and new campaign alerts

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages