Remote Event Receiver not firing when created using App Context - sharepoint-online

When I create a remote event receiver for the list added event using an App Context the endpoint doesn't get called when a user adds a list or library using the UI, however when I create the event receiver with a user context it does get called
I can list the event receivers and the one I have created is there and looks correct
Example Code, where the event receiver doesn't fire
var am = new AuthenticationManager();
using (var cc = am.GetAzureADAppOnlyAuthenticatedContext(siteUrl, ClientId, Tenant, CertificatePath, CertificatePassword))
{
cc.Web.AddRemoteEventReceiver("ListAddedFunction", "https://redacted.ngrok.io/api/ListAddedFunction", EventReceiverType.ListAdded, EventReceiverSynchronization.Asynchronous, false);
}
If I replace the client context creation with
using (var cc = authManager.GetWebLoginClientContext(siteUrl))
then the endpoint is called as expected

You might need to call appinv.aspx for the appId (or clientId) of your app registration to get SharePoint to call the RER, have a look at this issue for details:
https://github.com/SharePoint/sp-dev-docs/issues/4381

Related

Error handling in Azure function when used with SendGrid as output binding

I have a C# Azure function with output binding to SendGrid.
This Azure Function gets triggered when a message arrives in a ServiceBus topic. I operate on message and finally returns SendGridMessage. Hereon, SendGrid is responsible for sending out the actual email.
But in this whole scenario, Azure function does not get to know if the email is delivered or failed. Is there any way or hook available which can give me the aforementioned details ?
Any links, examples are appreciated.
Thanks
I don't think there is a way using the Sendgrid binding, as all the sending logic is abstracted away. If you need that, however, it's not much more complicated to instantiate your own Sendgrid client inside your Function:
using SendGrid;
using SendGrid.Helpers.Mail;
static SendGridClient _sendGridClient = new SendGridClient(ConfigurationManager.AppSettings["SendgridApiKey"]);
var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
var result = await _sendGridClient.SendEmailAsync(msg);
log.LogDebug($"SendGrid result={result.Body}");

Send message to a group of users in SignalR Service in Azure Functions

Looking at the docs for the SignalR bindings to send a message to a specified user you include the UserId property on the message as such -
[FunctionName("SendMessage")]
public static Task SendMessage(
[HttpTrigger(AuthorizationLevel.Anonymous, "post")]object message,
[SignalR(HubName = "chat")]IAsyncCollector<SignalRMessage> signalRMessages)
{
return signalRMessages.AddAsync(
new SignalRMessage
{
// the message will only be sent to these user IDs
UserId = "userId1",
Target = "newMessage",
Arguments = new [] { message }
});
}
This example is taken straight from the documentation, but the comment implies you message multiple userids, even though the property is a string and not an array.
How would you specify multiple users? (If for example, they are in a private chat channel together) Or is this mistake in the wording of the comment and you would need to send a message per user?
With other versions of SignalR I would put them in a group, but bindings for this do not exist for functions.
Group operations were introduced in the latest release.
Now you can:
Send a message to a group using GroupName in SignalRMessage
Add/remove user in a group using IAsyncCollector<SignalRGroupAction> output
Unfortunately just like the doc says, right now with Azure function binding we can only send message to one user or to all clients.
See the code of current extension SDK Microsoft.Azure.WebJobs.Extensions.SignalRService v1.0.0-preview1-10002.
It shows the extension has only two methods SendToAll and SendToUser.
Task SendToAll(string hubName, SignalRData data);
Task SendToUser(string hubName, string userId, SignalRData data);
The comment confused you is actually for old sample, the author forgot to modify it.
Good news is that support for group operation is under progress.

Unable to accept the permission prompt on Actions on Google

I am trying to get permissions for location and name for my app.
Here is my index.js - link
It seems to be stuck in a loop :-
Here are my intents on API.AI :-
The event actions_intent_PERMISSION needs to be attached to an Intent that will be called after the user authorizes the information to be sent. The handling for it in the webhook needs to read the information given and save it or do something with it immediately.
Your code is looping because the code that is processing the request_permission action is, itself, requesting permission:
function requestPermission(app){
const permissions = [
app.SupportedPermissions.NAME,
app.SupportedPermissions.DEVICE_PRECISE_LOCATION
];
app.askForPermissions('To pick you up', permissions);
}
So you will need:
A new intent
that has actions_intent_PERMISSION set for the event
that has a new action string associated with it
and maps to a new function that handles the information that the user has consented to.

Creating a thumbnail card with buttons in Bot Framework for Node.js without the session object

My bot has a timer job that checks for something every N minutes and sends a reminder to the user.
Since this is a timer job, that means it's outside any dialog and I don't have access to the session object.
The code works fine if I create the reminder message like this:
new builder.Message().text("This is a reminder!");
However, this code does not work because the CardAction requires a session object as a parameter:
var card = new builder.ThumbnailCard()
.title("Reminder")
.text("Hey it's a reminder.")
.images([exclamation_mark_image_url])
.buttons([builder.CardAction.imBack(null, "check", "Check Overdue")]); //should use `session` instead of null here
The error is a 500 Internal Server Error response from the botframework.com server in chat connector.
This is how I send the generate message when the session object is not available:
//`msg` is the message with a card generated in the code above
bot.beginDialog(address, dialog_name, msg, function (err) {
//nothing
});
How can I create a ThumbnailCard with a button without a session object?
What you can do is store the address of the user, and then use bot.loadSession(storedAddress, function (err, session) {}); This will generate the session object based on the passed in address. In its callback you can use the session object to send messages. I've used the method on a webhook to alert users when certain events are occurring.
Depending on how you're storing the timer/alarm, you can also store the user's last session.message.address with that data. I haven't worked on the implementation of such a bot, but the next part would be adding a job/method that checks a list of alarms continuously/periodically and then sends the message to the user when their alarm is triggered.

How pusher send data to selected clients only

I have used pusher recently in my PHP laravel project and it is working fine.
What I know about pusher is that it is a real time layer between our server and client and creates web socket connection to our client browser.
I setup pusher in my application using below tutorial:
pusher integration with laravel
What I have created using pusher for my web application:
1.I have created a notification functionality. Where when one user add some data to database say when one user starts following other user a event is triggered and that event sends data to particulr channel say 'notification-channel' and in my js code I have subscribed to this channel. For that I have written below line of codes:
//instantiate a Pusher object with our Credential's key
var pusher = new Pusher('68fd8888888888ee72c', {
encrypted: true
});
//Subscribe to the channel we specified in our Laravel Event
var channel = pusher.subscribe('notification-channel');
//Bind a function to a Event (the full Laravel class)
channel.bind('App\\Events\\HelloPusherEvent', addMessage);
By using addMessage() function I display some data. Now I have put a check on client side so that only if logged in user is intended to receive this message by writing simple if condition. As I have sent intended user's id in within data from App\Events\HelloPusherEvent so I used this Id to display msg to specific users only.
But I think this is not right approach to use pusher for notifications or any other functionality. Further in my project I want to use pusher for displaying new news feeds on user's newsfeed without page refresh, where obviously few users will see those posts according to whom is posting that news post.
But How I will user pusher in a way that I don't need to implement if conditions on client side to stop displaying data.
Here my concern is that if I will keep sending data to all the active clients and put if conditions to filter data that will ultimately degrade my application.
My concerns:
If pusher sends data to multiple clients that is obviously all the active users then will it not cause overhead.
Is there any option to use channels to channelize data to intended users only.
As I am implementing pusher first time I have few doubts regarding its actual working so is there any blog which can help me to understand its real time working.
Let me know if my question is not clear and specific enough, I will elaborate it further.
Thanks in advance to all who will try to answer.
This Question pusher-app-client-events explained that we can create different channels for different users to send msg to only intended users.
I go through this FAQ and came to know that we can create unlimited channels for one registered APP.
Creating multiple channels won't cause any overhead.
Now if I want to send notification to user 1 then I would create a channel 'notificaton-channel-1' and would subscribe user 1 to same channel within my frontend code.
The event class that I am using within my PHP laravel project looks like below:
<?php
namespace App\Events;
use App\Events\Event;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
/**
* Just implement the ShouldBroadcast interface and Laravel will automatically
* send it to Pusher once we fire it
**/
class HelloPusherEvent extends Event implements ShouldBroadcast
{
use SerializesModels;
/**
* Only (!) Public members will be serialized to JSON and sent to Pusher
**/
public $message;
public $id;
public $for_user_id;
/**
* Create a new event instance.
* #param string $message (notification description)
* #param integer $id (notification id)
* #param integer $for_user_id (receiver's id)
* #author hkaur5
* #return void
*/
public function __construct($message,$id, $for_user_id)
{
$this->message = $message;
$this->id = $id;
$this->for_user_id = $for_user_id;
}
/**
* Get the channels the event should be broadcast on.
*
* #return array
*/
public function broadcastOn()
{
//We have created names of channel on basis of user's id who
//will receive data from this class.
//See frontend pusher code to see how we have used this channel
//for intended user.
return ['notification-channel_'.$this->for_user_id];
}
}
and on Frontend I subscribed to 'notification-channel-'+logged_in_user_id
//Subscribe to the channel we specified in our Laravel Event
//Subscribe user to the channel created for this user.
//For example if user's id is 1 then bind to notification-channel_1
var channel = pusher.subscribe('notification-channel_'+$('#logged_in_userId').val());
//Bind a function to a Event (the full Laravel class)
channel.bind('App\\Events\\HelloPusherEvent', addMessage);
This way we can send data to intended users only rather blocking data received by all the users by putting conditions in our client side code.
I think you should add User ID within Blade template directly, not using a form field:
var channel = pusher.subscribe('notification-channel_{{ Auth::id() }}');

Resources