MS Teams bot events - microsoft-graph-api

I have a notification-only bot, and I would like to send a welcome message to users only when the bot is added to a personal conversation.
I listen to 'conversationUpdate' events as stated here, though I keep receiving the same event multiple times one after the other for the same user, all events identical (except the event ID and timestamp).
I respond to the event with HTTP status 200 (I handle them via REST).
Does anyone have an idea why I would receive the same events multiple times and how to avoid it? Is it some kind of retry due to an unexpected response on my end?
It even says here: "For personal scoped bots, your bot will only ever receive the conversationUpdate event a single time, even if the bot is removed and re-added."

Related

Remove a cell number from the Twilio unsubscribe list

I have a very simple alert mechanism to alert drivers "in-the-field" when a new pickup has been assigned to them. I have had an instance twice where a driver has responded with a STOP and became un-subscribed. Once discovered we acquired the proper opt-in documentation from them. Is there any way to re-subscribe a user that opted out and changed their mind on receiving the messaging. i.e. they issued the STOP to the incorrect SMS. And have deleted the original message to START. Or do I need to code something for them to opt back in
My SendGrid provides a method to remove suppression from email but am not finding anything like that here in Twilio.
They need to send a START to the number they previously opted out of, this is currently a requirement. You will also get an error when trying to send messages to them, to alert you they opted out.
Error 21610 - Attempt to send to unsubscribed recipient

Broadcast to only one web socket in room using ActionCable

I am using ActionCable to provide Browser Notification which is easy to implement. The problem is coming when a user has open the multiple tabs in the browser and I need to send the data to only one tab i.e to only one WebSocket in user room. How can this be done?
Isolating a single pub/sub client isn't directly possible with the pub/sub approach, because the whole idea is that publishers have no knowledge of subscribers.
However, there are two common ways to solve this:
to use a different named channel per connection, saving the named channel in the database and forwarding all messages to that specific named channel (i.e. saving the channel user-ID-TIMESTAMP in the database and using it as the target connection).
another, somewhat more reliable approach (though more complex) is to send the message to all clients but create a race condition that allows only a single client to receive the actual message. This would look something like this:
server sends "you have a message" to all clients.
client polls "undelivered" messages from the server.
server locks the message pool or uses a database transaction in order to retrieve undelivered messages and mark the messages as delivered. The server sends the undelivered messages to the client (optionally setting an ACK timeout).
a single client connection receives the undelivered messages the rest get an empty array of messages (since they were all delivered to the other client) or receive a "delivered" flag so the data is updated but no notification is raised.
(optional) the client sends and ACK.
(optional) the server marks the message delivery as complete. If no ACK was received before "timeout", server unmarks delivery and resends the "you have a message" message.
Good luck!
Every time a new connection is made we will create a new room. So for example when the user is making a new connection we can give the room name as users:user_id:some_unique_random_string which may be equal to users:user_id:123j123b1h2b1j23bh12b3 and when the same user makes another connection by opening another tab we will also do the same and create a separate room.
Now one thing the ActionCable provides is that we can find all the room name followed by any prefix.
Lets the user has made three connections and their rooms are users:128:123n1jh123ko9876, users:128:asdas23412cs1234, users:128:asni9202h5i3jens then we can obtain these room name using ActionCable also.
user_id = 128
pubsub = ActionCable.server.pubsub
channel_with_prefix = pubsub.send(:channel_with_prefix, RoomChannel.channel_name)
channels = pubsub.send(:redis_connection).pubsub('channels', "#{channel_with_prefix}:users:#{user_id}:*")
Now the channels is an array consisting of the rooms name.
So puts channels
["chatapp_production:users:128:123n1jh123ko9876", "chatapp_production:users:128:asdas23412cs1234", "users:128:asni9202h5i3jens"]
This is how we can find all the rooms related to a single user without using any external database and API calls.

iOS: Unable to fetch Offline messages for XMPP Chat

I am facing an issue with the presence status, following the documentation and XMPPframework example code. I have written a chat application.
Problem : When the user 1 & 2 are online I get the status successfully and they can chat with each other. However when the user 2 goes physically offline via (Wifi OFF / 3G Off) User 1 is not getting the offline status from XMPP and hence what ever messages are sent from that instant of time are lost when the user 2 comes online.
It seems since the user 2 is not notified or stored as offline in XMPP and hence its not storing the offline messages to push back to user 2 when it comes online.
I have tried to resolve this by explicitly writing a [goOffline] call to XMPP, however the call is shown in 'SEND log' for 'user 2' but not received in 'RECV log' in user 1 from XMPP, due to which the message are lost in between.
Also tried with other sources replies.
Set status for presence available and send XMPP
priority changed with values non-negative
XMPPArchiving work but this is not what I wanted.
Server side Mod_zero push enables but get only first message push notification sometimes.
Setting limit on ejabberd.cfg file for users and offline message limit.
request for offline message pull.
Can anyone help me with this?
This is very typical situation where client losses network but server can't detect that it is offline.
To detect status of each client, server need to send PING packets to every client and wait for response.
If client responds then fine otherwise server will mark that client as offline and every other online client will be informed automatically.
Here is PING Module implementation for ejabberd XMPP Server (hope you are using ejabberd server):
mod_ping:
send_pings: true
ping_interval: 10
timeout_action: kill
ping_ack_timeout: 10
This has to be written in ejabberd.yml configuration file.
At client side also we need to enable ping module to respond to server pings as:
private var xmppPing: XMPPPing?
xmppPing = XMPPPing()
xmppPing!.activate(xmppStream!)
This code has to be written while we setupStream() for iOS.
For detailed info, please go through mod_ping documentations.
Sounds like your problem is at server level. The server thinks that the user is online so it sends the message but nobody gets it. This does not really have a simple solution.
1.
The best solution would be delivery receipts. Where basically when the message is sent to your client, your client returns a confirmation of delivery receipt. If the server does not get that receipt it would resend the message every n time. Depending on your XMPP server you might find a already made solution, of not you would have to roll out your own.
2.
A possible hack would be to have your server always store and deliver last 10 messages and then at client side you discard repeated... This also depends on your server implementation. XMPP MUC and PubSub have resources along these lines.
For a long term scalable solution, you'll need to deal with this both at server and client level.

STOP for a single campaign

I do not completely understand how to handle STOP messages if I have only one campaign. Should I respond with "... text 1" when I receive STOP or can I simply opt out the user without asking them to send '1'?
EDIT:
I am trying to implement message handling for a SMS short code to be compliant with the carrier requirements. https://www.twilio.com/help/faq/short-codes. Basically, to be compliant with the requirements, I have to handle specific SMS messages that I receive, in particular, STOP message that should opt out the number that sent it from my "campaign". A "campaign" is intuitively a series of SMS messages that I sent to users. Here is Twilio help entry that explains STOP messages.
I do not understand whether I have to ask the user to text me back 1 as the page suggests if I have no other choices. Can I just handle this STOP as I would do STOPALL?
Here is a response that I received from Twilio support, in case someone else wants to ask this "non programming related" question:
"If you have one campaign, then you can opt them out the same way you would do a STOPALL."

MQTT messageId practical implementation

The company I am working for has evaluated MQTT and decided to use it as a core messaging platform for a large scale system. The main reason is how compact the protocol is and how easy it can actually be implemented. I have a single issue with MQTT though and I'm seeking for an answer to the following question:
QoS1 and QoS2 messages require confirmation from the client. The only thing I know about the message (identifying it) when receiving PUBACK, PUBREC, PUBREL and PUBCOMP is messageId and the clientId. Message id is an unsigned int16 so the max value is 65535. It doesn't seem to be large enough for long running clients, say a year, sending 15 QoS2 messages an hour.
I am not quite sure if there's any other way to identify the message? I would like to be as compliant with the standard as possible.
Probably the first point to make clear is that message IDs are handled on a per client and per direction basis. That is to say that the broker will create a message ID for each outgoing message with QoS>0 for each client that is connected and these message IDs will be completely independent of any other message IDs used for the same message published to other clients. Likewise, each client generates its own message IDs for messages that it sends.
The message ID doesn't have to be unique, so your client sending 15 messages per hour with QoS level 2 would simply overflow at some point. The real limitation is that there can only be a maximum of 65535 messages per direction "in flight" at once (i.e. part way through the message handshake). Once a message with a given ID has been fully processed then that message ID can be reused.
Another way of looking at it is to consider how it would work if your client only ever had one message in flight at once, whether because of the rate the messages are being transmitted or by design in the way you handle the messages. In this case, you could keep message ID set to 1 for every single message because there is never a chance that there will be a duplicate.
If you wish to support having multiple messages in flight at once it would be relatively straightforward to check there are no message ID duplicates before you assign a new one.
Because the message ID is per client, if you send a single message to >65535 clients there will be no chance of message ID collisions. If you send >65535 messages to each client at once and the message flows aren't complete then there will be problems.
Answering the comment "I have noticed that every MQTT broker tends to deliver only the last QoS1/2 message":
The broker will only send messages to clients it knows about. If you connect for the first time there is no way to get messages from the past, with one exception: retained messages. If a message is set to retained then it is a "last known good" value. When a new client subscribes it will be sent the retained message immediately which makes it useful for things that are updated infrequently. I suspect this is what you are referring to. If you want a client to have messages queued when it is not connected then you must connect with the "clean session" option disabled to make the client persistent. You must also use QoS>0 subscriptions and QoS>0 publications. When your client reconnects (with clean session still set to disabled), the queued messages will be delivered. You can normally configure the number of messages to queue in this way in the broker, where any further messages will be discarded. An important point is that queueing messages for a client that has not previously connected is not supported by design.
For delivering more messages at QOS1 or QOS2, you should use concept of persistant memory. In this when ever a subscriber is not available the message get stored in persistant memory and deliver once subscriber is connected. You can do this at QOS0 also after configuring mosquitto.conf file.

Resources