Как интегрировать систему геймификации Discourse с внешней системой (обмен и начисление очков)

Поскольку год назад мы запустили Discourse Gamification, одной из самых востребованных функций в нашем плане развития стала возможность интеграции системы геймификации Discourse с внешними системами геймификации. Примеров множество:

  • Интеграция с существующими программами геймификации в компаниях

  • Возможность начисления баллов за события, происходящие вне Discourse, например, офлайн-мероприятия или события в интернете, такие как участие в сообществе в качестве клиента или покупка товара.

  • Возможность для пользователей обменивать свои баллы на сувенирную продукцию, товары или привилегии

Сегодня, ровно в день первой годовщины плагина, мы сделали всё вышеперечисленное возможным благодаря полноценному API для обработки пользовательских событий начисления очков :tada:.

Эта новая система позволяет администраторам:

  • Начислять пользователям пользовательские события начисления очков

  • Начислять пользователям события с отрицательными очками для обработки операций обмена или штрафов

  • Обновлять и просматривать список ранее созданных пользовательских событий

API

:warning: Очки, начисленные через API, могут отображаться в общем рейтинге пользователя до 1 часа для событий, созданных с текущей датой, и до 24 часов для событий, созданных в последние 10 дней. Для событий, созданных с датой старше 10 дней, вы можете использовать кнопку Пересчитать баллы в интерфейсе администратора геймификации или запустить задачу rake для заполнения данных: rake gamification_scores:backfill_scores_from[YYYY-MM-DD].

В настоящее время доступно три различных конечных точки API.

Список событий

Возвращает до 100 событий. Вы можете фильтровать по id, user_id и/или date.

curl https://<example_url>/admin/plugins/gamification/score_events.json \
-H 'API-Key: <api_key_here>' \
-H 'API-Username: <api_username_here>'

Вы также можете получить список событий для конкретного пользователя или даты:

curl https://<example_url>/admin/plugins/gamification/score_events.json?user_id=1&date=2023-05-01 \
-H 'API-Key: <api_key_here>' \
-H 'API-Username: <api_username_here>'

Создание события

curl -X POST https://<example_url>/admin/plugins/gamification/score_events.json \
-H 'API-Key: <api_key_here>' \
-H 'API-Username: <api_username_here>' \
-H "Content-Type: application/json" \
-d '{
  "user_id": 13,
  "date": "2023-04-14",
  "points": 15,
  "description": "Участник караоке-вечера, май 2023"
}'

Альтернативный синтаксис с использованием jo:

jo -p user_id="13" date="2023-04-14" points="15" description="Участник караоке-вечера, май 2023" | curl --json @- -XPOST http://example/admin/plugins/gamification/score_events -H "Api-Key: apikeyhere" -H "Api-Username: system"

Обновление события

Конечная точка обновления требует указания id и points. Вы также можете обновить description. Обратите внимание, что user_id и date нельзя изменить после создания события.

curl -L -X PUT https://<example_url>/admin/plugins/gamification/score_events.json \
-H 'API-Key: <api_key_here>' \
-H 'API-Username: <api_username_here>' \
-H "Content-Type: application/json" \
-d '{
  "id": 6,
  "points": 25,
  "description": "Участник keynote-выступления, май 2023"
}'

Альтернативный синтаксис с использованием jo:

jo -p id="11" points="25" description="Участник караоке-вечера, май 2023" | curl --json @- -XPUT http://example/admin/plugins/gamification/score_events -H "Api-Key: apikeyhere" -H "Api-Username: system"
29 лайков

Is/will there be a way to do this through the UI?

9 лайков

That’s something I would consider if an Enterprise customer wants to sponsor it.

10 лайков

This is incredible. We’re just in the middle of starting and piloting an ambassador/champions program, and we’ve been using Airtable to monitor webhooks from our different sources (Discourse, GitHub, Ghost) and aggregate our champions program there. I’m excited to check this out and see if it could be used for us to manage/monitor our program and contributions.

It would be great if you could award points to a user group instead of a user. The use case for us as an enterprise customer would be that we essentially want to award points to the company the users work for and aggregate their points for each company. What is the feasibility of something like this?

9 лайков

Ahh I don’t know how to use this :smiling_face_with_tear:
We’re using a business plan.

I wish we could operate this via the UI.

But still, thanks for building this team! Keep up the good work.

5 лайков

That could help to give one-time points within Discourse with Automation plugin?

1 лайк

How does redeeming points work? I see there is an update event that could be used to subtract points from individual events, but that seems like an inefficient way to redeem points.

Also, when attempting to list events in my discourse instance, I get a 404.

GET https://developer.sailpoint.com/discuss/admin/plugins/gamification/score_events.json

404 Not Found
“The requested URL or resource could not be found.”

I have enabled the plugin and can configure it through the UI. Am I missing something to enable the external system API?

1 лайк

It may be my decade of experience working at banks, but the way I envision redeeming points is issuing negative value custom events.

For example, let’s say you have a user who wants to redeem points for a T-Shirt, and that T-Shirt costs 10k points. The flow on your redeeming system would be:

  1. Check if the user has enough points:

    curl https://meta.discourse.org/u/falco.json -s | jq . | grep score
        "gamification_score": 89386,
    
  2. Issue a “point withdraw” event

    jo -p user_id="13" date="2023-04-14" points="-10000" description="T-Shirt Redeem - order #123" | curl --json @- -XPOST http://example/admin/plugins/gamification/score_events -H "Api-Key: apikeyhere" -H "Api-Username: system"
    

You will want to wrap this in a semaphore of some sorts, as this is the text book example of using those, but that is the gist of the proposed workflow.

This is a very recent feature, so let me know if the proposed workflow doesn’t work correctly.

It’s working fine for me, both in the browser and via API. It’s an admin endpoint, so you need to be a logged in admin via browser, or pass API keys like explained in the OP.

3 лайка

Ok, that’s what I was missing. I didn’t realize you could issue negative points. That should work perfectly then.

:man_facepalming: I was using expired credentials. Thanks for confirming anyway.

2 лайка

@Falco

Are there any plans to add scopes to this API? It appears that the only way I can create or update scores is by having an admin API key that has global access. I would love to have a scope that restricts a key to just being able to update scores. This would give me more confidence using this API in automation tools as I wouldn’t have an admin key that can do much more than just update scores.

3 лайка

That’s a good idea, but I personally don’t have the bandwidth to work on this in the near future.

If you are keen on sponsoring this feature, please contact our support channel so we can get you a quote.

3 лайка

Facing the same issue here:

{"errors":["The requested URL or resource could not be found."],"error_type":"not_found"}

That error was caused by

So you want to check yours :wink:

1 лайк

Thanks, I’m also gonna update to latest just in case

Updating to latest worked! ty

1 лайк

I’ve been testing this a bit today. I see the events I can track, though unsure if there is a direct query to view only events by userid. Looking for a way to maybe have an audit log or present to users how they have gained/lost points.

1 лайк

There is something logged in UI when API call get sucess adding points?

Awesome! And I have another suggestion, is it possible to add a feature that enable users to redeem points for subscriptions in the ui interface? And the ability to add a limit to the number of points a user can earn per day on an event ( like create topics).

Thanks!

No, the feature is 100% API based. You can call the “List Events” endpoint to check for events as described in the OP.

3 лайка