I have created a backed in asp.net web-forms successful send a notification for all registered devices but I tired to send a link for example I need to send one push notification include a link When user touch on the notification redirect to mobile browser and open the link.
private static async void SendNotificationAsync()
{
NotificationHubClient hub = NotificationHubClient
.CreateClientFromConnectionString("<Here is my endpoint >", "<hub name>");
await hub.SendGcmNativeNotificationAsync("{ \"data\" : {\"message\":\"Hello Users \"}}");
}
Based on my experience, we could use custom json format and at receiver end convert that string into url. For example,Here’s a sample of the complete JSON payload with a custom "web_link" key containing the URL:
{"data": "{\"message\":\"xxxx\",\"web_link\":\"https://www.example.com\"}"}
Then we could override the OnMessage function to create Notification, we also could get more detail info from the Azure document.
Related
I am looking to open a task module (Pop up - iframe with audio/video) in my bot that is connected to Teams channel. I am having issues following the sample code provided on the GitHub page.
I have tried to follow the sample and incorporate to my code by did not succeed.
In my bot.cs file I am creating card action of invoke type:
card.Buttons.Add(new CardAction("invoke", TaskModuleUIConstants.YouTube.ButtonTitle, null,null,null,
new Teams.Samples.TaskModule.Web.Models.BotFrameworkCardValue<string>()
{
Data = TaskModuleUIConstants.YouTube.Id
}));
In my BotController.cs that inherits from Controller
[HttpPost]
public async Task PostAsync()
{
// Delegate the processing of the HTTP POST to the adapter.
// The adapter will invoke the bot.
await _adapter.ProcessAsync(Request, Response, _bot);
}
public async Task<HttpResponseMessage> Post([FromBody] Activity activity)
{
if (activity.Type == ActivityTypes.Invoke)
{
return HandleInvokeMessages(activity);
}
return new HttpResponseMessage(HttpStatusCode.Accepted);
}
private HttpResponseMessage HandleInvokeMessages (Activity activity)
{
var activityValue = activity.Value.ToString();
if (activity.Name == "task/fetch")
{
var action = Newtonsoft.Json.JsonConvert.DeserializeObject<Teams.Samples.TaskModule.Web.Models.BotFrameworkCardValue<string>>(activityValue);
Teams.Samples.TaskModule.Web.Models.TaskInfo taskInfo = GetTaskInfo(action.Data);
Teams.Samples.TaskModule.Web.Models.TaskEnvelope taskEnvelope = new Teams.Samples.TaskModule.Web.Models.TaskEnvelope
{
Task = new Teams.Samples.TaskModule.Web.Models.Task()
{
Type = Teams.Samples.TaskModule.Web.Models.TaskType.Continue,
TaskInfo = taskInfo
}
};
return msg;
}
return new HttpResponseMessage(HttpStatusCode.Accepted);
}
There is more code as per the GitHub sample but I won't paste it here. Can someone point me into the correct direction ?
I have got to the stage that it is displaying a pop up window but the content and title comes from manifest file instead of creating actual iframe also no video is rendering. My goal is to render video within my teams using iframe container.
The important part from the sample:
This sample is deployed on Microsoft Azure and you can try it yourself by uploading Task Module CSharp.zip to one of your teams and/or as a personal app. (Sideloading must be enabled for your tenant; see step 6 here.) The app is running on the free Azure tier, so it may take a while to load if you haven't used it recently and it goes back to sleep quickly if it's not being used, but once it's loaded it's pretty snappy.
So,
Your Teams Admin MUST enable sideloading
Your bot MUST be sideloaded into Teams
The easiest way to do this would be download the sample manifest, open it in App Studio, then edit your bot information in. You then need to make sure Domains and permissions > Valid Domains are set for your bot. Also ensure you change the Tabs URLs to your own.
You also need to make sure that in your Tasks, the URLs they call ALL use https and not http. If anywhere in the chain is using http (like if you're using ngrok and http://localhost), it won't work.
I am using Twilio Programmable Chat to add a chat feature to my mobile app built in React Native. I'm using the JS client SDK for this.
When the app receives a new message, the data that comes through uses the user identity for the author field. Is there away to include the friendlyName in the payload so I can display this to the user.
I could make a separate request for all users and find the correct user within the app but it would be great if this data could just be on the same request.
Thanks for any help
Yes, only author field present in new message event, I used an alternate approach
channelMembersDict = {}
// Assuming you have set selected an Channel
this.activeChannel.getMembers().then(members => {
members.forEach(mem => {
//member contains friendlyName attribute
this.channelMembersDict[mem.state.identity] = mem;
//If you really want user then
mem.getUser().then(user => {
this.channelMembersDict[mem.state.identity] = user;
});
});
I am sending push notification via an external script and capturing the response that is return from MobileFirst. The response is always 200 and a messageId is in the response JSON object
How can I simulate a error condition?
I used the MFP API to remove the subscription, removing the device from the device tab in the MFP console. However, I can still send and receive push notification for that deviceID .
Unsubscribing from the tag subscription (which you have subscribed in the code) does not clear all subscriptions. A default Push.ALL tag subscription stays in the DB. This is why you are able to still send notifications.
You can remove the device registration either using the SDK ( as mentioned by Gaurab) or use the REST API call to do this.
Details here: Push Device Registration Delete
I assume that you are using IBM MobileFirst v8.0.
You need to implement these API in client side to unregister the device or unsubscribe from tags.
Unregister the device from push notification service instance.
MFPPush.unregisterDevice(
function(successResponse) {
alert("Unregistered successfully");
},
function() {
alert("Failed to unregister");
}
);
Unsubscribe from tags.
var tags = ['sample-tag1','sample-tag2'];
MFPPush.unsubscribe(
tags,
function(tags) {
alert("Unsubscribed successfully");
},
function() {
alert("Failed to unsubscribe");
}
);
I'm writing a Telegram bot and I'm using the official bot API. I've got a webhook server that handles requests and sends a 200 OK response for every request.
Before the server stops, the webhook is detached so Telegram does not send updates anymore. However, whenever I turn the bot on and set the webhook URL again, Telegram starts flooding the webhook server with old updates.
Is there any way I can prevent this without requesting /getUpdates repeatedly until I reach the last update?
Here's a heavily simplified version of how my code looks like:
var http = require('http'),
unirest = require('unirest'),
token = '***';
// Attach the webhook
unirest.post('https://api.telegram.org/bot' + token + '/setWebhook')
.field('url', 'https://example.com/api/update')
.end();
process.on('exit', function() {
// Detach the webhook
unirest.post('https://api.telegram.org/bot' + token + '/setWebhook')
.field('url', '')
.end();
});
// Handle requests
var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' })
res.end('Thanks!');
});
server.listen(80);
Thanks in advance.
The best way is to use update_id which is a specific number that increases on every new request (i.e. update). How to implement it?
First off, let's start with the following anonymous class (using PHP7):
$lastUpdateId = new class()
{
const FILE_PATH = "last-update-id.txt";
private $value = 1;
public function __construct()
{
$this->ensureFileExists();
$this->value = filesize(self::FILE_PATH) == 0
? 0 : (int)(file_get_contents(self::FILE_PATH));
}
public function set(int $lastUpdateId)
{
$this->ensureFileExists();
file_put_contents(self::FILE_PATH, $lastUpdateId);
$this->value = $lastUpdateId;
}
public function get(): int
{
return $this->value;
}
public function isNewRequest(int $updateId): bool
{
return $updateId > $this->value;
}
private function ensureFileExists()
{
if (!file_exists(self::FILE_PATH)) {
touch(self::FILE_PATH);
}
}
};
What the class does is clear: Handling the last update_id via a plain file.
Note: The class is tried to be as short as possible. It does not provide error-checking. Use your custom implementation (e.g. use SplFileObject instead of file_{get|put}_contents() functions) instead.
Now, there are two methods of getting updates: Long Polling xor WebHooks (check Telegram bot API for more details on each methods and all JSON properties). The above code (or similar) should be used in both cases.
Note: Currently, it is impossible to use both methods at the same time.
Long Polling Method (default)
This way, you send HTTPS requests to Telegram bot API, and you'd get updates as response in a JSON-formatted object. So, the following work can be done to get new updates (API, why using offset):
$botToken = "<token>";
$updates = json_decode(file_get_contents("https://api.telegram.org/bot{$botToken}/getUpdates?offset={$lastUpdateId->get()}"), true);
// Split updates from each other in $updates
// It is considered that one sample update is stored in $update
// See the section below
parseUpdate($update);
WebHook Method (preferred)
Requiring support for HTTPS POST method from your server, the best way of getting updates at-the-moment.
Initially, you must enable WebHooks for your bot, using the following request (more details):
https://api.telegram.org/bot<token>/setWebhook?url=<file>
Replace <token> with you bot token, and <file> with the address of your file which is going to accept new requests. Again, it must be HTTPS.
OK, the last step is creating your file at the specified URL:
// The update is sent
$update = $_POST;
// See the section below
parseUpdate($update);
From now, all requests and updates your bot will be directly sent to the file.
Implementation of parseUpdate()
Its implementation is totally up to you. However, to show how to use the class above in the implementation, this is a sample and short implementation for it:
function parseUpdate($update)
{
// Validate $update, first
// Actually, you should have a validation class for it
// Here, we suppose that: $update["update_id"] !== null
if ($lastUpdateId->isNewRequest($update["update_id"])) {
$lastUpdateId->set($update["update_id"]);
// New request, go on
} else {
// Old request (or possible file error)
// You may throw exceptions here
}
}
Enjoy!
Edit: Thanks to #Amir for suggesting editions made this answer more complete and useful.
When you server starts up you can record the timestamp and then use this to compare against incoming message date values. If the date is >= the timestamp when you started...the message is ok to be processed.
I am not sure if there is a way you can tell Telegram you are only interested in new updates, their retry mechanism is a feature so that messages aren't missed...even if your bot is offline.
In the webhook mode, Telegram servers send updates every minute until receives an OK response from the webhook program.
so I recommend these steps:
Check your webhook program that you specified its address as url parameter of the setWebhook method. Call its address in a browser. It does not produce an output to view, but clears that probably there is no error in your program.
Include a command that produces a '200 OK Status' header output in your program to assure that the program sends this header to the Telegram server.
I have the same issue, then I tried to reset the default webhook with
https://api.telegram.org/bot[mybotuniqueID]/setWebhook?url=
after that, i verified the current getUpdates query were the same old updates but I sent new requests through the telegram's bot chat
https://api.telegram.org/bot[mybotuniqueID]/getUpdates
when I set up my webhook again the webhook read the same old updates. Maybe the getUpdates method is not refreshing the JSON content.
NOTE:
in my case, it was working fine until I decided to change /set privacy bot settings from botfather
I am developing android app in titanium,by button click event I have to get registration ID from GCM. how to do that I am new to titanium.
I followed this http://iamyellow.net/post/40100981563/gcm-appcelerator-titanium-module, but I am not able to understand how to implement?
Thanks in advance.
To implement push notification, you should use Ti.CloudPush module.
You can achieve GCM Push Notification in 6 easy steps
Setting up Google Cloud Messaging
Push Configuration in ACS Console
CloudPush Module Implementation
Retrieve Device Token
Cloud User Login
Subscribe a Channel
1. Setting Up GCM
To use GCM, you need to create a Google API project to obtain a Google API key and GCM sender ID. For instructions on creating and obtaining these items, see Android Developer: Getting Started with GCM and follow the directions in "Creating a Google API Project", "Enabling the GCM Service" and "Obtaining an API Key".
We will use our Project number as GCM Sender ID.
When creating a new server key, you are asked for a list of IP addresses to accept requests from. Do not enter any information in the textbox and click Create to accept all IP addresses.
2. Push Configuration in the ACS
Go to your apps, then go to My Apps -> Manage ACS -> DEVELOPMENT -> Settings/Android Push Configuration and enter your Google API key in the Google Cloud Messaging (GCM) API Key textbox and GCM sender ID in the Google Cloud Messaging (GCM) Sender ID textbox. (which we got from Step 1)
3. CloudPush Module Implementation
Add CloudPush module into your application.
To add CloudPush module, you need to add <module platform="android">ti.cloudpush</module> in your TiApp.xml. Then require the module in your javascript file using var CloudPush = require('ti.cloudpush');.
To use push notifications, in the tiapp.xml file, you need to specify push type to GCM.
To do this go to your tiapp.xml.
Add/edit the following lines
<property name="acs-push-type-development" type="string">gcm</property>
<property name="acs-push-type-production" type="string">gcm</property>
<property name="acs-push-type" type="string">gcm</property>
4. Retrieve Device Token
Call the retrieveDeviceToken method before setting the enabled property to true to enable the device to receive push notifications. You must call retrieveDeviceToken before any other CloudPush API call or else the device will not receive push notifications.
var CloudPush = require('ti.cloudpush');
var deviceToken = null;
CloudPush.retrieveDeviceToken({
success: function deviceTokenSuccess(e) {
Ti.API.info('Device Token: ' + e.deviceToken);
deviceToken = e.deviceToken;
},
error: function deviceTokenError(e) {
alert('Failed to register for push! ' + e.error);
}
});
5. Cloud User Login
Before subscribe for Push Notification, cloud user should logg in.
Cloud.Users.login({
login: username,
password: password
}, function (e) {
if (e.success) {
alert("login success");
} else {
alert('Error: ' + ((e.error && e.message) || JSON.stringify(e)));
}
});
6. Subscribe a Channel
You need to subscribe to a channel to get the pushnotification. Push notification will be sending to the particular channel and it will be reached to all users who subscribed to the channel.
if(deviceToken != null){
Cloud.PushNotifications.subscribe({
channel: 'yourchannelName',
device_token: deviceToken,
type: 'gcm' //here i am using gcm, it is recommended one
}, function (e) {
if (e.success) {
alert('Subscribed for Push Notification!');
} else {
alert('Subscribe error:' + ((e.error && e.message) || JSON.stringify(e)));
}
});
} else {
alert('You need to retrieve the device token first');
}
Now you can send push notification. To do this go to My Apps -> Manage ACS -> DEVELOPMENT -> Push Notifications, here you can see number of clients subscribed for push notification, channels etc. You can send the push notification from there.
UPDATE : Attention!!
GCM supports devices that run Android 2.2 and later
Google Play Store application should be installed in your device.
For pre-4.0 devices, the user is required to set up their Google account.
You're using an android device for testing, not emulator(Since you can't install Google Play in your emulator).
Google play service is running on your device.
The following links will help you:
Titanium.CloudPush
Android SDK Titanium
ACS Push Notification Using GCM