Telegram bot: How do I send message with inline keyboard and hide custom keyboard simultaneously? - telegram-bot

Step 1: Send user a message with ReplyKeyboardMarkup with few buttons (for example ["Yes", "No"])
Step 2: If user click one of the buttons (for example "Yes") I want to display a message with inline keyboard and hide the buttons sent at step 1.
Is it possible to do? The message has just single reply_markup property and can be either InlinkeKeyboardMarkup or ReplyKeyboardHide. The only way to do that I see is to send 2 messages (first to hide keyboard and 2nd with inline keyboard) but that would not be best solution from user experience point of view. I'm OK to do couple of request but want to have just 1 message visible to user.
Any thoughts?

It's impossible right now. Telegram Bot API currently allows sending only one type of keyboard: inline or simple (including KeyboardHide and other).

There isn't any logical solution. but there's a trick. you can send a message to remove the previous keyboard, then remove this message, finally send the next message with it's keyboard.
// send a fake message
Message sentMsg = bot.SendTextMessageAsync(chatID, ".", replyKeyboardMarkup: new ReplyKeyboardRemove()).Result;
// remove the fake message
bot.DeleteMessageAsync(chatID, sentMsg.MessageId);
// send the main message with it's keyboard
bot.SendTextMessageAsync(chatID, "the next message", replyKeyboardMarkup: new ReplyKeyboardMarkup(keyboardData));

I guess you want the button should disappear once it's pressed:
ReplyKeyboardMarkup MyButton = new ReplyKeyboardMarkup();
MyButton.OneTimeKeyboard = true;
You can even make it more responsive by adding this:
MyButton.ResizeKeyboard = true;

But you can send two messages, the first one would send ReplyKeyboardHide/ReplyKeyboardRemove and the second would send the inline keyboard

Just set the OneTimeKeyboard Property to true,
Button.OneTimeKeyboard = true;
Once button is used it's never showing again

you better use inlinekeyboard for both yes/no and the preceding keyboard which you want to show after pressing yes or no. that way, you can edit the yes/no inlinekeyboard message and show new keyboard.
you can send the inlineKeyboard and by checking it's callBackQuery.Data parameter you can edit the sent message again and show your new message instead.
below is a sample update message json:
{"update_id":14603298,
"callback_query":
{
"id": "479899181065761766",
"from": {
"id": 111735238,
"first_name": "eric",
"username": "...."
},
"message": {
"message_id": 22,
"from": {
"id": 3576731383,
"first_name": "the_bot_name",
"username": "mybot_bot"
},
"chat": {
"id": 111745258,
"first_name": "eric",
"username": "....",
"type": "private"
},
"date": 1492113810,
"text": "sent message"
},
"chat_instance": "5419183837652256438",
"data": "yes"
}}
so, when the user clicks on yes or no, you will get an update message. based on above update message, the chatid and messageid are known so using the c# Telegram.Bot library the edit code is like:
var chatid= 111745258;
var messageid=22;
TelegramBotClient api = new TelegramBotClient("YOUR_TOKEN");
var new_keyboard = new InlineKeyboardMarkup(
new[]
{
new[]
{
new InlineKeyboardButton("step_1","step1") ,
},
new[]
{
new InlineKeyboardButton("step_2","step2"),
new InlineKeyboardButton("step_3","step3"),
},
new[]
{
new InlineKeyboardButton("step_4","step4"),
}
});
api.EditMessageReplyMarkupAsync(chatid, messageid, replyMarkup: new_keyboard);

Related

How to update the pop-up note via API

I'm trying to update the pop-up note via the API. I can easily update the top box (aka the Note) but I don't see how I go about updating the pop-up section. What's odd to me is that the Note doesn't even appear in the WSE, abut when I send the update it does work.
When I retrieve the record, it also doesn't appear to send the data that I have in the pop-up section, and I'm not even clear how I can add it to the WSE.
I've tried just adding it to the JSON update with a couple different names like this (tried popupnote, notepopup), and that still goes through, but only updates the top box:
"note": {
"value": "Travis Update Test!"
},
"notepopup": {
"value": "Travis Pop update Test!"
},
Anyone know if this is possible?
The answer from Acumatica Support is below. In short you need to add a custom field in the items sectionm for the 2 notes and it works perfectly. When loading the items, if you plan to serialize into this class, add this ?$custom=Item.NoteText,Item.NotePopupText to the end of your url:
{
"id": "2a113b2c-d87f-e411-beca-00b56d0561c2",
"custom": {
"Item": {
"NoteText": {
"type": "CustomStringField",
"value": "Regular note 2"
},
"NotePopupText": {
"type": "CustomStringField",
"value": "Popup note 2"
}
}
}
}

How to SelectFrame dynamically in Salesforce?

I am trying to automate a script using Kantu in Salesforce.
Basically I am going through some dropdown IDs and select the right values and everything works IF the selectFrame value is correct in the beginning.
The problem is that Salesforce refreshes the iframe ID everytime the page is refreshed or a new case is opened (i.e. ext-comp-1018 | ext-comp-1035 | ext-comp-1048 etc.)
Because the script does not recognize the frame (since it is always changing), it won't go ahead to do the rest of the actions.
{
"Name": "SFDC_Auto",
"CreationDate": "2019-3-25",
"Commands": [
{
"Command": "selectFrame",
"Target": "id=ext-comp-1018",
"Value": ""
},
{
"Command": "select",
"Target": "id=cas5",
"Value": "label=Escalation"
},
I seen a post that mentioned this would be the solution, but I am not sure how to implement it in Kantu:
frames = #driver.find_elements(:xpath, '//iframe[starts-with(#id,ext-
comp-)]') #driver.switch_to.frame frames1
So far I could make this work: xpath=//iframe[starts-with(#id,ext-comp-)], however it doesn't do nothing. It reads ok but then halts at the next step saying that ID CAS5 is not recognized.
Can anyone help out?
Thanks,

How to get response from Google+ Share API about whether user shared link or not

I want to check whether the user shared my content in google plus or not, I tried onendinteraction callback but user may click close button instead of share button so i need to detect user originally shared content or not?
Just noticed this linked question. I answered it on another post but here it is again -
According to Google Developer page for their web platform, it seems you can tap into the current users activities list using a javascript code similar to -
var request = gapi.client.plus.activities.list({
'userId' : 'me',
'collection' : 'public'
});
request.execute(function(resp) {
var numItems = resp.items.length;
for (var i = 0; i < numItems; i++) {
console.log('ID: ' + resp.items[i].id + ' Content: ' +
resp.items[i].object.content);
}
});
The online tool to generate and test the query end point is there on the Developer Page
Generate and append a custom query string to the end of the link your user is sharing, the JSON returned from the end point can be parsed to check if that particular link has been shared on the users activity stream.
The JSON returned looks like this -
{
"items": [
{
"title": "",
"published": "2015-06-12T16:39:11.176Z",
"url": "https://plus.google.com/+UserID/posts/PostID",
"object": {
"content": "",
"attachments": [
{
"objectType": "article",
"url": "http://www.example.com"
}
]
}
}
]
}
If the link with the custom query is there in the attachments section of one of the returned items,Voila! Its been shared.

Action bar is not displaying in dijit dialog when using href attribute

I have the following code
var dlg = new dijit.Dialog({
"title": "my dialog",
"style": "width: 800px;",
"id": "myDlg",
"href":"some url"
}).placeAt(dojo.body());
var actionBar = dojo.create("div", {
"class": "dijitDialogPaneActionBar"
}, dlg.containerNode);
new dijit.form.Button({
"label": "Ok"
}).placeAt(actionBar);
new dijit.form.Button({
"label": "Cancel"
}).placeAt(actionBar);
dlg.show();
with this code dialog is displaying with the url content but action bar is not showing,when i replace the href with some static content action bar is working fine.What could be the problem?
When using "href" for the dojo Dialog, the content from the href loads as an ajax call every time the dialog is opened/showed. So, what happens here is your action bar and button are added first and then the href is loaded into the Dialog, which overwrites the existing action bar and the buttons -EVERYTIME!!
So, to achieve this, you can ensure that the action bar is added, once the href load is completed. For this, we use the Deferred object returned by the "show" method.
var dlg = new dijit.Dialog({
"title": "my dialog",
"style": "width: 800px;",
"id": "myDlg",
"href":"some url"
}).placeAt(dojo.body());
dlg.show().then(function() {
if(dlg.firstTime) {
var actionBar = dojo.create("div", {
"class": "dijitDialogPaneActionBar"
}, dlg.containerNode);
new dijit.form.Button({
"label": "Ok"
}).placeAt(actionBar);
new dijit.form.Button({
"label": "Cancel"
}).placeAt(actionBar);
dlg.firstTime=true;
}
});
But, i would suggest not to use this approach, because, every time, you create the action Bar and button widgets. So, i have added a parameter "firstTime" to dialog object to avoid it. SO, action bar and buttons are crated only one time.
Hope this helps.

sSearch and fnServerParams, DataTables.net

I'm trying to set up some search box / datepickers up outside of the main table, i've done some searching and read that i need to pass my values in fnServerParams with a custom value. So, i do this:
"fnServerParams": function (aoData) {
aoData.push({
"name": "iArchiveYears", "value": $("#ddYears :selected").text()}
, { "name": "iMsgType", "value": $('#msgTypeSearch').val() }
)
},
Which, when viewed in firebug appear fine as can be seen below:
I'm using a click function combined with fnFilter to try and filter bsaed on a specific value for a specific columns, which looks like this :
$('#msgTypeSearch').keyup(function (event) {
event.preventDefault();
oMsgDateDetail.fnFilter(this.value, 4, false, false, false, true);
});
for some reason this isnt filtering at all and i note that the value for the search box appears in sSearch4 - do i therefore need to specifiy fnServerParams at all? i'm not sure, as the date (2011) doesnt appear in the sSearch fields.
Is it possible to filter using fnFilter at all??
oMsgDateDetail.fnFilter(this.value, XX, false, false, false, true);
});
Send a request to the server and sSearch_XX = the value
oMsgDateDetail.fnFilter(this.value);
});
Send a request to the server and sSearch = the value
In server-side, you need to search and send all records.
fnFilter doesn't filter when bServer-side = true.
When bServer-side = false. It search in your local data