How to handle new_chat_members when a user joined to telegram group with telegram bot? - laravel

I'm trying to send a message to user, who joined to a group, with my telegram bot. I add bot to the group and bot is admin in group. and I set the Group Privacy off. I get user with new_chat_member when user joined to group, but the message send to user infinitely. And the update which is for when a member join to group is pending.
if(isset($arrayMessage['message'])) {
if (isset($arrayMessage['message']['new_chat_member'])) {
$text= "hello!";
$url= "https://api.telegram.org/bot".$token."/sendMessage?chat_id=".$chat_id."&text=".$text;
file_get_contents($url);
}
}

I'll assume you are using long polling for this answer. When using the getUpdates method, it will keep retrieving the existing unconfirmed updates until you confirm them by using the offset parameter.
See enter link description here
If you do not confirm the updates, you will keep receiving the same update, thus the infinite messages.

Related

Telegram add and retrieve metadata from message

Hi I'm looking for a way to store user session/metadata with the least amount of latency and that will not cost me an arm and a leg.
Brief problem description.
I have a bot that helps users download files from Google Drive.
It uses a Webhook of an AWS lambda function.
Users are provided with clickable filenames, e.g.
/File.pdf
Once they click on it, it needs to be downloaded and sent to the user.
The problem is I need a way of knowing what file the user chose without having to use a database or iterating through all my files by name.
E.g. Is there a way of adding metadata to the clickable message? Such that I can add that metadata to the clickable and if a user clicks /File.pdf, I'll be able to extract the metadata.
You can send InlineKeyboardButton like in this example and set in callback_data whatever you need. When user clicks on that button - your bot will receive that data in update:
button_list = [
InlineKeyboardButton("File1.pdf", callback_data="https://drive.google.com/invoice.pdf"),
InlineKeyboardButton("File2.pdf", callback_data="https://drive.google.com/presentation.pdf"),
InlineKeyboardButton("File3.pdf", callback_data="https://drive.google.com/report.pdf")
]
reply_markup = InlineKeyboardMarkup(button_list)
bot.send_message(chat_id=chat_id, "Files list:", reply_markup=reply_markup)
# in update handler:
def some_update_handler(update, context):
url = update.callback_query.data
# ...
# further processing
This can be also useful in any other case when Telegram bot user should see some nice message, but shouldn't see some internal value sent to Telegram bot.

Identify first sign in with Authentication using AD for Microsoft Bot Framework

I would like to give a login successful message to the user when he sign in for the first time. So i need to identify weather the user have used sign card shown to sign in(user have interacted) or system automatically taken the token itself without user intervention. It will be nice we show a successful message user interaction was there. How i can identify weather there was a user interaction or not?
The answer I found is to find the Activity Type if its event type user have interacted else it’s an automatic signin. You can reverify the connection just established by checking the value of key connectionName in Activity.Value. The following code will help you.
string output = JsonConvert.SerializeObject(stepContext.Context.Activity.Value, Formatting.Indented);
if (stepContext.Context.Activity.Type is "event")
{
var conName = JsonConvert.DeserializeObject<JObject>(output)["connectionName"].ToString();
if (conName ==<Your Connection Name>)
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"You have successfully Signed In"), cancellationToken);
await stepContext.Context.SendActivityAsync(MessageFactory.Text($"How can I help you?"), cancellationToken);
}
}

Laravel Presence Channel: Store Joining and Leaving Users in database

I have this working:
Echo.join(`chat.${roomId}`)
.here((users) => {
//
})
.joining((user) => {
this.users.push(user);
this.saveStatus(user, 'online');
})
.leaving((user) => {
this.users = this.users.filter(u => u.id != user.id);
this.saveStatus(user, 'offline');
});
That shows me an accurate list of the Users that are present.
But what I want, is to store also their status in the database with a timestamp.
So I thought about this function:
saveStatus(user, status) {
axios.post("/logbooks", { user_id: user.id, status: "offline"})
}
And call that function in the joining and leaving state.
But that's not accurate: it doesn't store values when just one user is online. And when there are 20 users offline, and one user goes offline > it'll store 19 times this value.
Any tips how to get a more accurate online-offline-log to the database?
If you are using Pusher Channels you can configure presence webhooks for your Channels app. You can activate webhooks in your account dashboard on a per app basis.
The presence webhook will be triggered for the following events; member_added and member_removed (user joins a presence channel or user leaves a presence channel (goes offline)):
You can listen for these events on your server and then update the user state depending on what events you are receiving.
If the user can join multiple rooms (channels) at once (e.g. room1, room2, room3) you may want to track whether the user is online or offline by having a user specific presence channel.
For example if the user was called 'Joe Bloggs' you would join a channel called joebloggs when first connecting to your Pusher app. (if the user joins this channel they are online, if the user leaves this channel they are offline)
You could resolve this issue by using Laravel Echo Server (instead of Pusher) and Redis. Here is the documentation:
https://github.com/tlaverdure/laravel-echo-server#presence-channels
Redis handles a publish/subscribe mechanism. Laravel Echo Server publishes each time someone joins/leaves a presence channel, and with an Artisan command, you can subscribe to Redis and react to the join/leave by notifying your database.

Return initial data on subscribe event in django graphene subscriptions

I'm trying to response to user on subscribe. By example, in a chatroom when an user connect to subscription, the subscription responses him with data (like a welcome message), but only to same user who just connect (no broadcast).
How can I do that? :(
Update: We resolve to use channels. DjangoChannelsGraphqlWs does not allow direct back messages.
Take a look at this DjangoChannelsGraphQL example. Link points to the part which is there to avoid "user self-notifications" (avoid user being notified about his own actions). You can use the same trick to send notification only to the user who made the action, e.g. who just subscribed.
Modified publish handler could look like the following:
def publish(self, info, chatroom=None):
new_msg_chatroom = self["chatroom"]
new_msg_text = self["text"]
new_msg_sender = self["sender"]
new_msg_is_greetings = self["is_greetings"]
# Send greetings message only to the user who caused it.
if new_msg_is_greetings:
if (
not info.context.user.is_authenticated
or new_msg_sender != info.context.user.username
):
return OnNewChatMessage.SKIP
return OnNewChatMessage(
chatroom=chatroom, text=new_msg_text, sender=new_msg_sender
)
I did not test the code above, so there could be issues, but I think it illustrates the idea quite well.

How to store conversation had with Alexa into database

I am developing an Alexa skill for school, my client wants to store the conversation what Alexa had with parents and want to display it in the student's dashboard. How to store the whole conversation had with my skill into database?
You will not get the skill user utterance or what the user has said. But, with what you get from Alexa request, you can kind-of re-create the conversation flow.
Use these information:
userId
If you don't have account linking in your skill, you will have to persist this to filter out conversations from a particular user. Please note that this userId will change when the user disable and re-enable your skill.
sessionId
If you want to filter out a user's particular session. You can also depend on SessionEndedRequest to check know when the session ended, but this is clean.
Intents
You wont get the user speech, but from intents you can identify the users intention. This will help you to guess what the user might have said.
Slots
If you combine slots with the mapped intents you will get some more information. Since slot values are always passed to you, you can persist this and will know the exact value the user has said in his/her conversation.
Timestamp
Always save the timestamp, this will help you to know when exactly the request came in.
Alexa Response
Always persist the response you send back.
sessionAttributes
If you have some cruicial information which you think will be helpful, then save it too.
With these information/filters if you sort it with timestamp, you will get an idea about a particular/all user's conversation with Alexa.
You can get and store/save what alexa says but you can not get exactly what the user say to alexa skill. But what you can get is user's intention (i.e what intent is called).
Solution to your problem is to use some database and make a table and do something like this in every intent
const HelpIntentHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'IntentRequest'
&& handlerInput.requestEnvelope.request.intent.name === 'AMAZON.HelpIntent';
},
handle(handlerInput) {
const speechText = 'You can say hello to me!';
*//write code to add speechText to a table against the intent name/sample utterence with date and time*
return handlerInput.responseBuilder
.speak(speechText)
.reprompt(speechText)
.withSimpleCard('Hello World', speechText)
.getResponse();
},
};

Resources