Application wide subscription to a channel - laravel

Quick question about Pusher.js.
I've started working on a notifications functionality today and wanted to do this with Pusher.js, since I used it for my chat.
I'm working in Laravel. What I want to achieve is an application wide subscription to a channel. When a user registrates a channel is being made for him "notifications_channel", which I store in the database. I know how to register a user to a channel, but once he leaves that page, the room vacates. That's not really what I'm looking for, since I'd like to send the user notifications no matter where he is on the platform.
I couldn't really find anything like this in the documentation, so I thought maybe one of you guys know how to do so.
Here are some snippets of what I do:
When the user registrates I fire this:
$generateChannel = User::generateNotificationsChannel($request['email']);
This corresponds to this in my model:
public static function generateNotificationsChannel($email){
$userID = User::getIdByMail($email);
return self::where('email', $email)->update(['notifications_channel' => $userID."-".str_random(35)]);
}
It's fairly basic, but for now that's all I need.
So for now, when the user logs in the Index function of my HomeController is being fired, which gathers his NotificationsChannel from the database and sends it to the view.
public function index()
{
$notificationsChannel = User::getUserNotificationsChannel(\Auth::user()->id);
return view('home', compact('notificationsChannel', $notificationsChannel));
}
Once we get there I simply subscribe the user to that channel and bind him to any events linked to the channel:
var notifications = pusher.subscribe('{{$notificationsChannel}}');
channel.bind('new-notification', notifyUser);
function notifyUser(data){
console.log(data);
}
So as you can see, for now it's pretty basic. But my debug console shows me that the channel vacates as soon as the user leaves /home.
So the question is, how do I make him subscribed to the channel, no matter where he is on the platform?
Any and all help would be deeply appreciated!
Thanks in advance.

I've found a fix to this issue, I've decided to send the notifications-channel to my Master layout, which I use to extend all views after the user has logged in. In my master layout I subscribe the user to his own notifications channel.
For people who might be interested in how I did it:
I altered the boot function of my AppServiceProvider which you can find in \app\Providers\AppServiceProvider. The code looks like this:
public function boot()
{
view()->composer('layouts.app', function($view){
$channel = User::getUserNotificationsChannel(\Auth::user()->id);
$view->with('data', array('channel' => $channel));
});
}
In my Master layout I simply subscribed the user by grabbing the channel name.

Related

Laravel 9, send notification with preferredLocale

I am creating a bilingual application in which I have implemented database and e-mail notifications.
A notification is, for example, information that a user has started a new conversation. Unfortunately, notifications sent to the database are sent in the language of the user who sends them (set language: App::setLocale(Auth()->user->locale);) and not in the language of the recipient.
I use:
use Illuminate\Contracts\Translation\HasLocalePreference;
class User extends Model implements HasLocalePreference
{
/**
* Get the user's preferred locale.
*
* #return string
*/
public function preferredLocale()
{
return $this->locale;
}
}
Oddly enough, email notifications work this way.
I translate notifications like this:
$customer->notify(new NewMessageNotification($message, trans('notifications.new_message', ['user' => $user->name])));
I tried this way, but it didn't change anything:
https://setkyar.medium.com/fixing-laravels-notification-locale-issue-9ad74c2652ca
Although now I'm wondering if it wouldn't be better to save in the key base and translate only when reading, so that all received notifications are translated when changing the language. The only question is how to do it then.
If i understand well, you want to send notification based on destination language and not based on sender one. If yes, preferredLocale may not works, but you can try to define the language on notification trigger like this:
$customer->notify(new NewMessageNotification($message, trans('notifications.new_message', ['user' => $user->name]))->locale('pt'));
I found that I save to the database in both languages ​​and when reading, I check the language set by the user to display the appropriate version.
On second thought, it seems more logical to have notifications displayed in the currently set language rather than when sent.

laravel - if the database changes, send notification

if any data has been inserted into the database, I want to alert message to another page. How can I do it?
This is the controller page:
public function insertFunction(Request $request) {
$insert = New ExampleTable;
$insert->test_id = $request->id;
$insert->save();
// after this i want to send notification to the another page(panel.blade.php) without refreshing
}
This is the panel.blade.php where I want to see the notification:
<script>
// if notification comes, do it
alert("notification came");
</script>
I'm using mysql. If you help me I will be glad, thanks.
Assuming that you want real time notification, the best practice would be to use the broadcast functionality of Laravel.
Most likely, you will end up using something like pusher.
However, you could make a custom java-script loop that continuously asks your endpoint if there has been any updates, but that would be bad practice and is not recommended.
This is an article that I found helpful. Good luck!

Default message in botman

I'm testing botman in Laravel and it works very well. But I can not find how to put a message by default. Can someone give me an orientation ?
$botman->hears('Hi', function ($bot) {
$bot->reply('Hello!');
});
BotMan allows you to create a fallback method, that gets called if none of your "hears" patterns matches. You may use this feature to give your bot users guidance on how to use your bot.
$botman->fallback(function($bot) {
$bot->reply('Sorry, I did not understand these commands. Here is a list of commands I understand: ...');
});

Getting the content from a MailMessage object

I am trying to create a system that will automatically log the content of any email notifications that my site sends to users, against their accounts.
I am doing this by listening for the NotificationSent event, which provides me with easy access to the Notifiable (the object that I want to store my log entry against) and the Notification (the object that defined the message that has been sent).
Using these I am able to get hold of the MailMessage object, but I can't work out how to render it. I was hoping it would have a render method but I can't find one. Presumably there is some other object that takes the MailMessage and does the rendering. Any clues?
Ideally I'd like the plain text version of the email (the markdown)
Thanks for any help
I've got a solution that is doing what I want. I cannibalised some code I wrote for something else, that got me a long way there. There are some steps that I don't completely understand so there may well be some unnecessary bloat in here:
class LogNotification
{
public function handle(NotificationSent $event)
{
//getting the MailMessage object
$mailMsg = $event->notification->toMail($event->notifiable);
//I think this is getting the additional variables from the
//MailMessage that are needed to render the view
$msgData = array_merge($mailMsg->toArray(),$mailMsg->viewData);
//I don't fully understand this. I get that the Markdown object is
//going to do the rendering, but I don't know why it needs to be
//instantiated with an empty View object
$markdown = new \Illuminate\Mail\Markdown(view(), config('mail.markdown'));
//Pass the renderText method the path to the markdown, and the message data
$msgContent = $markdown->renderText($mailMsg->markdown, $msgData);
}
}
Hopefully this is helpful to someone (and if anyone can offer a proper explanation of what is happening when the Markdown object is instantiated, I'd be grateful).

How do I hide posts with a specific hashtag in Yammer?

I want to hide posts in the feed that have a #joined hashtag. I tried to create a GreaseMonkey script with jQuery in the past, but it couldn't detect any posts that have the #joined text.
Am I using the wrong library? A starting point, or an existing library/plug-in would be helpful.
OFF-TOPIC: At the moment, Yammer does not have any feature to hide posts with a specific hashtag, although it has a feature to follow a hashtag.
I know that this is a pretty old question but I too was trying to create a Chrome based Add-on that hides these #joined posts (or any post with a specific hashtag). I came across this blog https://you.stonybrook.edu/thebaron/2014/10/06/hiding-joined-yammer-posts-in-chrome/ where the author of the post has shared his work (https://gist.github.com/thicknrich/e4cc2871462a6850fe8c). This is a simple javascript and does the job.
//Script from https://gist.github.com/thicknrich/e4cc2871462a6850fe8c
//load jQuery based on this SO Post:
//http://stackoverflow.com/questions/2246901/how-can-i-use-jquery-in-greasemonkey-scripts-in-google-chrome
// a function that loads jQuery and calls a callback function when jQuery has finished loading
function addJQuery(callback) {
var script = document.createElement("script");
script.setAttribute("src", "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js");
script.addEventListener('load', function() {
var script = document.createElement("script");
script.textContent = "window.jQ=jQuery.noConflict(true);(" + callback.toString() + ")();";
document.body.appendChild(script);
}, false);
document.body.appendChild(script);
}
// the guts of this userscript
function main() {
// Note, jQ replaces $ to avoid conflicts.
setInterval(function() {
//if a item thread contains #joined, hide it
//check every 5 second.
jQ('.yj-thread-list-item:contains("#joined")').css("display", "none");
}, 5000);
}
// load jQuery and execute the main function
addJQuery(main);
You can find all joined messages with the following endpoint, based upon the #joined topic:
GET https://www.yammer.com/api/v1/messages/about_topic/[:id].json
But you can only delete messsages that you own:
DELETE https://www.yammer.com/api/v1/messages/[:id]
Source: https://developer.yammer.com/restapi/
Note that this is a conscious decision by the product team, although joined messages can get spammy when a network becomes viral, it is a great opportunity to engage users right away once they join. It makes them feel welcome. As a community manager, I'd encourage you to welcome that user in and also encourage other yammer champions to welcome these users also. As a side effect, it also encourages people to follow the groups they are interested in and use the Top or Following feeds instead of the all (firehose) feed which has all these joined messages.
Just want to note that the statement in a reply here "But you can only delete messsages that you own" is not entirely correct it is possible to delete message that do not belong to you if you are a network admin. I just ran a little experiment after reading this post and deleting #joined messages that don't belong to me worked just fine.

Resources