How can i answer "CallbackData" without use "AnswerCallbackQueryAsync" in telegram bot (C#) - c#

the main problem is i want to send answer to user without showing by
notification or alert in telegram , and i want to show message in main
panel like other messages.
This line of code just fire a notification
await api.AnswerCallbackQueryAsync(update.CallbackQuery.Id,"text");
How can i response to callback like this line code?
await api.SendTextMessageAsync(update.Message.Chat.Id,"text");

You should use that because this will stop loading GIF from telegram.
If you don't want to show alert, Leave text parameter null and it won't show alert.
then use SendTextMessageAsync method to send message to other messages.
Your code should be like this:
private void Bot_OnCallbackQuery(object sender, CallbackQueryEventArgs e)
{
if (e.Query.Data == "Hello")
{
string reply = "Hi!";
// Answer with null parameter:
await Bot.AnswerCallbackQuery(e.Query.Id, null);
// Reply with message instead:
await Bot.SendTextMessageAsync(e.Query.Message.Chat, reply);
}
}

Related

Discord.Net bot reply - contains word

I have just started tinkering with discord.net for creating a bot. I have a very basic bot right now that already replies with my given response when I type the command text. So if I type, "Hello" it will reply with, "...world!"
However, what I want, is to have the bot reply with a canned response whenever a message contains a certain word at any point. So if a user types, "Well, hello there" it will still reply with, "...world!" even though the command word is in the middle of the message. I think I may be able to swing it with the .Contains() method, but I'm a little stuck.
private async Task OnMessageReceived(SocketMessage arg)
{
if (!(arg is SocketUserMessage message)) return;
if (message.Source != MessageSource.User) return;
string[] filters = { "hello" };
string content = message.Content;
bool contains = filters.Any(x => content.Split(" ").Any(y => y.Contains(x)));
if (contains)
{
var guild = _client.GetGuild((message.Channel as SocketGuildChannel).Guild.Id);
await message.Channel.SendMessageAsync($"{arg.Content} world!");
return;
}
}
This is the MessageReceived event that you can get from the DiscordSocketClient. Put this in your CommandHandler.

botframework confirm dialog, send message as user

I have created a confirm dialog where the user can select yes/no
private async Task Confirm(IDialogContext context, IAwaitable<bool> result)
{
var res= await result;
await context.PostAsync(res? "Proceed" : "Ok then");
if (res) {
......
}
}
If the user selects Yes he will receive the message "Proceed"
At the same time (again if "res" is true), i want to send a
specific message to the bot without appearing in the conversation.
Is there a way to send a custom message back to the bot when user
press Yes?
You could try constructing a new activity using data stored in the context which you have access to in this method. I don't fully understand your scenario but it seems this may work for what you need.
var a = new Activity();
a.Conversation = context.Activity.Conversation;
a.Recipient = context.Activity.Recipient;
a.From = context.Activity.From;
a.Id = context.Activity.Id;
... //set whatever else you need set
a.Text = "Whatever you need the text to be";
//send or process the activity do what it is you are trying to accomplish
Edit: I think what you are actually looking for is Prompt.Confirm().

How to get most recent update in Telegram Bot API

I am struggling on how to get the text of a message to my C#-console tool with a telegram bot. Here is a piece of that is supposed to just print all messages in the telegram channel
private async Task getTelegramMessage()
{
var bot = new Telegram.Bot.TelegramBotClient("token")
var updates = await bot.GetUpdatesAsync();
foreach (var update in updates)
{
Console.WriteLine("Bot: " + update.Message.Text);
}
}
the problem is that i always get all old updates. The maximum length of the array updates is 100. So after I sent 100 messages in the telegram channel, I would only have access to the first 100 messages and no access to the newest. How can I get access to the most recent update? Or can I somehow delete the message after my tool has processed it?
I have seen that the bot provides the Event OnUpdate but I couldnt figure out how to use it.
Thanks a lot for help on that issue.
According documentation, you can use offset -1 to get the last update.
Just put in mind all previous updates will forgotten.
getUpdates Docs
https://api.telegram.org/bot{TOKEN}/getUpdates?offset=-1
oh, I just figured it out. for the offset you have to set the ID returned in the update.
Notes
2. In order to avoid getting duplicate updates, recalculate offset after each server response.
Instead subscribe to the BotOnUpdateReceived event to handle the updates. In main.cs:
Bot.OnUpdate += BotOnUpdateReceived;
Bot.StartReceiving(Array.Empty<UpdateType>());
Console.WriteLine($"Start listening!!");
Console.ReadLine();
Bot.StopReceiving();
And handle the event:
private static async void BotOnUpdateReceived(object sender, UpdateEventArgs e)
{
var message = e.Update.Message;
if (message == null || message.Type != MessageType.Text) return;
var text = message.Text;
Console.WriteLine(text);
await Bot.SendTextMessageAsync(message.Chat.Id, "_Received Update._", ParseMode.Markdown);
}
The Offset is internally working in it and it also internally call GetUpdatesAsync().
From Here you can also get channel post via:
var message = e.Update.ChannelPost.Text; // For Text Messages
I hope it will Help!!

MS Bot Framework stuck sending messages in an infinite loop

My bot that uses MS Bot Framework is stuck sending messages to the user in an infinite loop, both on the facebook and emulator channels.
My bot has a "root" IDialog, kind of like a menu, that calls a few other IDialogs depending on the user's selection. The child dialogs are called in this way:
...
else if (response.Text == MainOptions[2])
{
await context.Forward(new InfoCounterDialog(), ChildDialogComplete,
response, CancellationToken.None);
}
...
response is an IMessageActivity sent by user;
ChildDialogComplete is a method that builds the main menu again and ends with these lines:
.
await context.PostAsync(restartPrompt);
context.Wait(MainScreenSelectionReceived);
All dialogs work fine except this one very short dialog, which causes an infinite loop - the bot keeps sending this message again and again until I stop the web app.
namespace XXXX
{
[Serializable]
public class InfoCounterDialog : IDialog
{
public async Task StartAsync(IDialogContext context)
{
var hourNow = DateTime.Now.Hour;
var openNow = "";
if (hourNow >= 7)
{
openNow = "It is open now and will close at midnight.";
}
else
{
openNow = "It is closed now and will open at 7:00";
}
var card = HeroCardUtils.CardWithImageAndMiscButtons(
"Our information counter can help!",
"It's located in Shop 081, Level 3 in Building 2. " + openNow,
"http://www.[image URL here].jpg",
new[] { "More Details" },
new[] { ActionTypes.OpenUrl },
new[] { "[webpage URL here]" }
);
await BotUtils.SendCardToChat(context, card);
context.Done(this);
}
}
}
If you're wondering what SendCardToChat does:
public async static Task SendCardToChat(IDialogContext context, HeroCard card)
{
var activity = context.MakeMessage();
activity.Attachments = HeroCardUtils.CardToAttachments(card);
await context.PostAsync(activity);
}
To recap:
I'm launching a dialog from another dialog using context.Forward()
The dialog is supposed to show a message to the user and immediately terminate without extra input from user
Instead, it keeps sending the "Our information counter can help!" message infinitely.
My best guess is that the child dialog somehow returns the user's initial message to the conversation, which triggers the same dialog again and again. But this shouldn't happen, the child IDialog shouldn't send anything to the conversation except the HeroCard I created.
Or maybe I'm looking in a wrong direction and Bot Framework just doesn't support IDialogs that do something and immediately terminate without a context.Wait()?
I found that there isn't much documentation on context.Done(R value) but its really important in controlling the flow of the dialog.
I'm guessing that context.Done(this) calls your Dialog again? have you tried
context.Done(true);
I'm finding it frustrating that there isn't a context.Done() method (no parameter) to tell the dialog that your finished.
Further to this, i've found that in this Microsoft Example they use
// within a HotelsDialog.cs
context.Done<object>(null);
This is possible because they call the dialog from a root dialog
// within RootDialog.cs
context.Call(new HotelsDialog(), this.ResumeAfterOptionDialog);

Windows Phone 8.1 Modal Dialog. How?

Following examples here in Stack Overflow, I put together a MessageDialog to show my user error messages.
In the emulator, it works fine.
On the phone, it blows right through, flashes the MessageDialog on the screen for only a moment, and even blows through a Task.Delay I put in as a workaround.
Would somebody please explain to me what's happening, or point me in the right direction?
p.s. I also tried a ContentDialog per an article here. THAT doesn't even display the message text.
Here's a code snippet:
public static async void ShowAndGo (String MessCode, String MessText, Boolean Xit)
{
String Mess = ""; // Start out with an empty Message to tell Joe User.
String Title = ""; // And an empty title too.
if (MessCode != "") // If we're sent a Message "Code,"
Mess = App.ResLdr.GetString (MessCode) + Cx.ld + Cx.ld; // turn it into text, culturally-aware.
Mess += MessText; // Stick MessText onto the end of it.
if (Xit)
Title = App.ResLdr.GetString ("OhSnap"); // If we're goin' down, curse a little.
else
Title = App.ResLdr.GetString ("NoProb"); // If it's just informational, no problem-o.
MessageDialog messageDialog = new MessageDialog (Mess, Title);
await messageDialog.ShowAsync (); // IT FREAKING ISN'T STOPPING HERE!!!
Task.Delay (10000).Wait (); // Wait 10 seconds with error message on the screen.
// AND IT FREAKING DOESN'T STOP HERE EITHER!!!
}
The reason of your problem is simple - you are declaring async void method - avoid that, this should be used only in special cases, for example events. In the code you have, your program doesn't stop on line where you invoke the method:
ShowAndGo("Message code", "Message Text", false);
Debug.WriteLine("Something happening");
It probably shows a message, but how long it will survive it depends on your further code. The remedy for this is to change the method from void to Task and await:
public static async Task ShowAndGo (String MessCode, String MessText, Boolean Xit)
{ /* method */ }
//invoke:
await ShowAndGo("Message code", "Message Text", false);
Debug.WriteLine("Something happening"); // now it should wait till user clicks OK
Of course that requires async all the way, but probably that's how your program should look like.

Categories