-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support telegram bot #4
Open
dadamu
wants to merge
16
commits into
main
Choose a base branch
from
paul/telegram-bot
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
821d6ab
feat: make new folder for discord bot
dadamu 8a77897
feat: build telegram bot
dadamu 79db1bb
feat: implement send command
dadamu e1fc6af
feat: built cmd handler
dadamu e640a1e
docs: added TODO comment
dadamu 2eec9cc
chore: improve how get telegram context args
dadamu 26c0ae0
fix: limitation set and docs
dadamu cac4eb1
fix: remove verify cmd from telegram bot
dadamu e60bfe3
chore: run lint
dadamu f976296
chore: fix typo
dadamu 8ecc737
docs: add missing docs and remove unused docs
dadamu edf10b3
chore: fixed error because of rebase
dadamu 552281a
chore: improve docs and import
dadamu 690eabe
Merge branch 'main' into paul/telegram-bot
dadamu 67a013b
fix: remove check command
dadamu 768fe1a
chore: readd line breaks
dadamu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
# Build | ||
.idea/ | ||
build/ | ||
vendor | ||
|
||
# Configuration | ||
*.yaml | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,7 +45,6 @@ func (bot *Bot) HandleSendTokens(s disgord.Session, data *disgord.MessageCreate) | |
} | ||
|
||
log.Debug().Str(types.LogRecipient, recipient).Str(LogTxHash, res.TxHash).Msg("tokens sent successfully") | ||
bot.SetCommandLimitation(msg.Author.ID, types.CmdSend) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove it since it should be handled in |
||
bot.Reply(msg, s, fmt.Sprintf( | ||
"Your tokens have been sent successfully. You can see it by running `desmos q tx %s`."+ | ||
"If your balance does not update in the next seconds, make sure your node is synced.", res.TxHash, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package bot | ||
|
||
import ( | ||
"strconv" | ||
"time" | ||
|
||
"github.com/desmos-labs/hephaestus/limitations" | ||
"github.com/desmos-labs/hephaestus/network" | ||
"github.com/desmos-labs/hephaestus/types" | ||
"github.com/rs/zerolog/log" | ||
telebot "gopkg.in/telebot.v3" | ||
) | ||
|
||
// Bot represents the object that should be used to interact with Discord | ||
type Bot struct { | ||
cfg *types.BotConfig | ||
telegram *telebot.Bot | ||
|
||
testnet *network.Client | ||
mainnet *network.Client | ||
} | ||
|
||
// Create allows to build a new Bot instance | ||
func Create(cfg *types.BotConfig, testnet *network.Client, mainnet *network.Client) (*Bot, error) { | ||
// Set the default prefix if empty | ||
if cfg.Prefix == "" { | ||
cfg.Prefix = "/" | ||
} | ||
bot, err := telebot.NewBot(telebot.Settings{ | ||
Token: cfg.Token, | ||
Poller: &telebot.LongPoller{Timeout: 10 * time.Second}, | ||
ParseMode: telebot.ModeMarkdown, | ||
}) | ||
return &Bot{ | ||
cfg: cfg, | ||
telegram: bot, | ||
testnet: testnet, | ||
mainnet: mainnet, | ||
}, err | ||
} | ||
|
||
// Start starts the bot so that it can listen to events properly | ||
func (bot *Bot) Start() { | ||
log.Debug().Msg("starting bot") | ||
bot.Handle(types.CmdDocs, bot.HandleDocs) | ||
bot.Handle(types.CmdHelp, bot.HandleHelp) | ||
bot.Handle(types.CmdConnect, bot.HandleConnect) | ||
bot.Handle(types.CmdSend, bot.HandleSendTokens) | ||
log.Debug().Msg("listening for messages...") | ||
bot.telegram.Start() | ||
} | ||
|
||
// CheckCommandLimit returns the date on which the given user will be able to run the command again | ||
func (bot *Bot) CheckCommandLimit(userID int64, command string) *time.Time { | ||
// Try getting the expiration date for the command | ||
expirationDate, err := limitations.GetLimitationExpiration(strconv.FormatInt(userID, 10), command) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
// Check if the user is blocked | ||
if expirationDate != nil && time.Now().Before(*expirationDate) { | ||
log.Debug().Str(types.LogCommand, command).Time(types.LogExpirationEnd, *expirationDate).Msg("user is limited") | ||
return expirationDate | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// SetCommandLimitation sets the limitation for the given user for the provided command | ||
func (bot *Bot) SetCommandLimitation(userID int64, cmd string) { | ||
// Set the expiration | ||
commandLimitation := bot.cfg.FindLimitationByCommand(cmd) | ||
if commandLimitation != nil { | ||
err := limitations.SetLimitationExpiration(strconv.FormatInt(userID, 10), cmd, time.Now().Add(commandLimitation.Duration)) | ||
if err != nil { | ||
log.Error().Err(err).Str(types.LogCommand, cmd).Msg("error while setting limitation expiration") | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package bot | ||
|
||
import ( | ||
"encoding/hex" | ||
"encoding/json" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/desmos-labs/hephaestus/types" | ||
"github.com/desmos-labs/hephaestus/utils" | ||
telebot "gopkg.in/telebot.v3" | ||
) | ||
|
||
type CallData struct { | ||
// Username is the plain-text Telegram username of the user that wants to be verified | ||
Username string `json:"username"` | ||
} | ||
|
||
// NewCallData returns a new CallData instance | ||
func NewCallData(username string) *CallData { | ||
return &CallData{ | ||
Username: username, | ||
} | ||
} | ||
|
||
// HandleConnect handle a connection request. This request is done by the users when they want to connect their Desmos | ||
// profile with their Telegram account. | ||
// The command expects one single argument which must be the JSON object returned from the "desmos sign" command. | ||
// | ||
// The handling of the command will fail in the following occasions: | ||
// 1. The signed value does not correspond to the username of the user sending the message | ||
// 2. Any of the values are badly encoded | ||
func (bot *Bot) HandleConnect(ctx telebot.Context) error { | ||
parts := ctx.Args() | ||
if len(parts) != 2 { | ||
ctx.Reply(fmt.Sprintf(`**Connect** | ||
This command allows you to connect your Telegram account to your Desmos profile. | ||
To do this, you have to: | ||
|
||
1. Sign your Telegram username using the Desmos CLI or any Desmos-compatible application. | ||
2. Use the %[1]s command to send the signature result. | ||
|
||
__Signing your Telegram username__ | ||
1. Copy your Telegram username by clicking on it in the bottom part of your Telegram client. | ||
|
||
2. Open your Desmos CLI or application, and sign your username. | ||
If you use the Desmos CLI, you can do this by using the following command: | ||
`+"`desmos sign <Telegram username> --from <your-key>`"+` | ||
|
||
Eg. `+"`desmos sign \"foo_123\" --from foo`"+` | ||
|
||
__Sending the signed value__ | ||
The sign command should return a JSON object. The last thing you have to do is now send it to me using the %[1]s command. To do this, simply send me a message as the following: | ||
`+"`/%[1]s <%[2]s/%[3]s> <JSON>`"+` | ||
|
||
Eg. `+"`/%[1]s %[2]s {...}`"+` | ||
`, types.CmdConnect, types.NetworkTestnet, types.NetworkMainnet)) | ||
return nil | ||
} | ||
|
||
// Get the network client to be used | ||
var networkClient = bot.testnet | ||
if parts[0] == types.NetworkMainnet { | ||
networkClient = bot.mainnet | ||
} | ||
|
||
// Get the signature data | ||
username := ctx.Sender().Username | ||
signatureData, err := utils.GetSignatureData(parts[1]) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Upload the data to Themis | ||
err = networkClient.UploadDataToThemis(username, bot.cfg.Name, signatureData) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Return to the user the call data for the Desmos command | ||
callDataBz, err := json.Marshal(NewCallData(username)) | ||
if err != nil { | ||
return types.NewWarnErr("Error while serializing call data: %s", err) | ||
} | ||
ctx.Reply(fmt.Sprintf("Your verification data has been stored successfully. "+ | ||
"All you have to do now is execute the following command:\n"+ | ||
"```\n"+ | ||
"desmos tx profiles link-app ibc-profiles [channel] telegram \"%[1]s\" %[2]s --packet-timeout-height 0-0 --packet-timeout-timestamp %[3]d --from <key_name>"+ | ||
"```", | ||
username, | ||
hex.EncodeToString(callDataBz), | ||
time.Now().Add(time.Hour).UnixNano(), | ||
)) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package bot | ||
|
||
import ( | ||
"fmt" | ||
|
||
telebot "gopkg.in/telebot.v3" | ||
) | ||
|
||
// HandleDocs handles the the request for docs by the user | ||
func (bot *Bot) HandleDocs(ctx telebot.Context) error { | ||
// Answer to the command | ||
ctx.Reply(fmt.Sprintf( | ||
"Here are a series of useful links:\n"+ | ||
"- General documentation: %s\n"+ | ||
"- Become a validator: %s", | ||
"https://docs.desmos.network/", | ||
"https://docs.desmos.network/validators/setup.html")) | ||
return nil | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move
CmdHandler
fromtypes
folder since telegram and discord have different handler structure.