remark42 icon indicating copy to clipboard operation
remark42 copied to clipboard

Feature: Telegram Notify

Open uPagge opened this issue 4 years ago • 2 comments
trafficstars

The way the notifications are now made in telegrams is quite convenient for site administrators, but not at all convenient for users.

It would be cool to do, like on vas3k.club.

There you can subscribe for notifications to a separate post, as well as receive notifications to your comments.

uPagge avatar Dec 09 '20 15:12 uPagge

I will expand the idea a little more. It would also be cool to be able to reply to comments directly from the telegram

This is how it looks in one of my projects for gitlab

изображение

изображение

uPagge avatar Feb 17 '21 05:02 uPagge

Now it's up to @akellbl4 (or someone else familiar with the frontend) to implement the frontend part of the Telegram notifications.

paskal avatar Jul 22 '21 12:07 paskal

I want to help with this feature and I want to make my first FE contribution to the project. But can somebody give me an overview of what "FE support" means for this feature?

goooseman avatar Jun 24 '23 05:06 goooseman

There is a button in the web interface which takes you through the flow of subscribing to replies to your messages through email if the feature is enabled on the backend.

For Telegram, I've created the endpoints for a similar subscription flow, but there are no buttons in the frontend to allow users to use it.

It seems like I didn't describe the steps for a subscription yet. I'll do that once I'm near the computer so that this task will be easier to pick up.

paskal avatar Jun 24 '23 06:06 paskal

@paskal I've taken a look on the email subscriptions and looks like I can do the same feature for Telegram

Screenshot 2023-06-25 at 12 39 57

I have some question though:

  1. Am I right that this Telegram notification should be visible only if user authenticated with Telegram?
  2. What params should I ask from user and where is the BE spec?

goooseman avatar Jun 25 '23 09:06 goooseman

Used endpoints are described in remark.rest:

### get information for sending confirmation token for current user. auth token for dev user for secret=12345.
### After you'll get the response, construct link with it and open it: https://t.me/<bot>?start=<token>
GET {{host}}/api/v1/telegram/subscribe?site={{site}}

### verify telegram notifications for current user via token obtained in the previous step, after talking to bot. auth token for dev user for secret=12345.
GET {{host}}/api/v1/telegram/subscribe?tkn={{token}}

### delete current user telegram. auth token for dev user for secret=12345.
DELETE {{host}}/api/v1/telegram?site={{site}}

### generate a QR code for Telegram url
GET {{host}}/api/v1/qr/telegram?url=https://t.me/BotFather

Telegram notifications should be present to all users when enabled except for anonymous users, GitHub or email users can use it as well. No questions to the user, just asking them to click the link to Telegram and then click the link in the chat. The notification subscription flow is following:

  1. Get /api/v1/telegram/subscribe?site=SITE_ID, there will be an URL in response which need to be presented to the user to click
  2. Generate a QR code to assist the user on Desktop in case their Telegram is on the phone: /api/v1/qr/telegram?url=URL_FROM_PREVIOUS_STEP
  3. User clicks on the link they received after talking to the telegram bot, it would be /api/v1/telegram/subscribe?tkn=TOKEN_GENERATED_BY_REMARK, subscription is complete
  4. Calling Delete on /api/v1/telegram?site=SITE_ID will disable the subscription

The auth flow uses the first three steps as well. Please let me know if you have any questions.

paskal avatar Jun 28 '23 06:06 paskal

@paskal I've started to work on implementation, and I need to enable this feature on FE project-wise if:

  1. FE show_telegram_subscription flag is not set to false
  2. BE is configured to enable telegram notifications by NOTIFY_USERS env var or notify.users configuration var

So I need to know on FE if BE is configured to enable those notifications. I've taken a look at GET /config here and as far as I see there is email_notifications: bool, but there is nothing about telegram notification being enabled.

Can I request to add a property here? Or is there any way to check that from FE?

goooseman avatar Jun 28 '23 11:06 goooseman

If telegram_bot_username is set, Telegram user notifications are enabled: now I don't see any reason why it's done that way and not as a boolean flag. Feel free to alter the backend code to make it a boolean flag telegram_notifications, or let me know if you want me to do it.

From https://github.com/umputun/remark42/pull/1029:

For frontend: when config option telegram_bot_username is not empty, telegram notifications are enabled. We need to ask the user to write a bot with that username (https://tg.me/$username) and then use his ID for subscription: send /getid to https://tg.me/myidbot in Telegram messenger.

This is not needed as the backend gives you a proper link to show in the frontend.

paskal avatar Jun 28 '23 13:06 paskal

@paskal Looks a little bit implicit, but it's ok for me. On FE we have a single place where this logic is implemented, so I believe it is ok to case string to bool there.

goooseman avatar Jun 28 '23 14:06 goooseman

I've changed the config option to boolean telegram_notification in #1648.

As for the subscription URL, I was wrong: for the subscribe request, you get JSON with token and bot fields and need to construct a link like https://t.me/BOT/?start=TOKEN and also call the QR endpoint with this URL.

paskal avatar Jun 28 '23 20:06 paskal

@paskal I've found a bug

Steps to reproduce

  1. Call /telegram/subscribe to get bot and token
  2. Construct a unique link, e.g. https://t.me/bar_bot/?start=foo
  3. Do not open the link in Telegram yet, but try GET /telegram/subscribe?site=remark&tkn=foo

Expected

The API to fail with 4xx response code and some error message

Actual

Request fails with 500 and empty response body.

BE logs:

2023/07/02 10:27:18.043 [WARN]  {rest/httperrors.go:81 rest.SendErrorJSON} can't set telegram for user - request is not verified yet - 500 (0) - Alexander/telegram_c**- /api/v1/telegram/subscribe?site=remark&tkn=*** - [rest/api/rest_private.go:433 api.(*private).telegramSubscribeCtrl]
2023/07/02 10:27:18.043 [INFO]  {logger/logger.go:134 logger.(*Middleware).Handler.func1.1} GET - /api/v1/telegram/subscribe?site=remark&tkn=*** - r42.goooseman.dev - 0449df86a1d3 - 500 (89) - 235.676µs

goooseman avatar Jul 02 '23 15:07 goooseman

Reproduced both on my remote deployment and on demo.remark42.com

goooseman avatar Jul 02 '23 15:07 goooseman

@paskal anyway the PR is created: #1649

goooseman avatar Jul 03 '23 17:07 goooseman

Thanks a lot! As for the confusing error code, please path by yourself in your branch:

diff --git a/backend/app/rest/api/rest_private_test.go b/backend/app/rest/api/rest_private_test.go
--- a/backend/app/rest/api/rest_private_test.go	(revision add01455fba91e6b96b6fe13c3be306773afc6bc)
+++ b/backend/app/rest/api/rest_private_test.go	(date 1688587010194)
@@ -1156,8 +1156,8 @@
 	body, err = io.ReadAll(resp.Body)
 	require.NoError(t, err)
 	require.NoError(t, resp.Body.Close())
-	require.Equal(t, http.StatusInternalServerError, resp.StatusCode, string(body))
-	require.Equal(t, `{"code":0,"details":"can't set telegram for user","error":"not verified"}`+"\n", string(body))
+	require.Equal(t, http.StatusNotFound, resp.StatusCode, string(body))
+	require.Equal(t, `{"code":0,"details":"request is not verified yet","error":"not verified"}`+"\n", string(body))
 
 	mockTlgrm.notVerified = false
 
diff --git a/backend/app/rest/api/rest_private.go b/backend/app/rest/api/rest_private.go
--- a/backend/app/rest/api/rest_private.go	(revision add01455fba91e6b96b6fe13c3be306773afc6bc)
+++ b/backend/app/rest/api/rest_private.go	(date 1688586814273)
@@ -430,7 +430,7 @@
 	var address, siteID string
 	address, siteID, err := s.telegramService.CheckToken(queryToken, user.ID)
 	if err != nil {
-		rest.SendErrorJSON(w, r, http.StatusInternalServerError, err, "can't set telegram for user", rest.ErrInternal)
+		rest.SendErrorJSON(w, r, http.StatusNotFound, err, "request is not verified yet", rest.ErrInternal)
 		return
 	}
 

paskal avatar Jul 03 '23 18:07 paskal

@paskal I've tried to fix this bug in my branch, but I couldnt find how to run go tests. go test did not return me any error after I did this change, which is weird, because I see I should also do a change on line number 1159 of backend/app/rest/api/rest_private_test.go.

So I've skipped this change. Anyway it does not affect this functionality.

goooseman avatar Jul 04 '23 14:07 goooseman

I've updated the code above with test change, please apply it in your branch.

paskal avatar Jul 05 '23 19:07 paskal