How to Set Up the Recipient Id in Public Activity

How to set up the recipient id in public activity

tracked recipient: ->(controller, model) { model && model.user }

assuming Tom is the user of tracked object. Otherwise change model.user as per your application

Rails Public_Activity gem recipient id getting error

Recipient is looking for a user and not an id. The reason why current_user works is because it is a user object. If you had used current_user.id, it would not have worked.

Use User.find(2) to get the user object.

How to set up friends as recipients in public activity?

I think you would have to do this through custom activity.
For example,

When a new movie is created , you can do the create activity a callback method,

after_create :create_activity

def create_activity
user.friends.each do |friend|
self.create_activity action: :new , parameters: {title:title,poster:poster}, recipient: friend, owner: current_user
end
end

however this solution is very inefficient. I am not sure if there is a method provided for the gem that you can create multiple activities all together, like ActiveRecord, Moview.create([{title:1},{title:2}]). Otherwise you many want to move this into a background job, something like sidekiq .

Multiple recipients of activity

When searching inside the string there's 4 possibilities

  • id is in the beginning of the field

    ex: "id, 2, 3"
  • id is in the end of the field

    ex: "1, 2, id"
  • id is in the middle of the field

    ex: "1, id, 3"
  • id is the only number in the field

    ex "id"

So here's how i think a query might look like

@activities = PublicActivity::Activity.where(
"user_recipients LIKE ':id,%' or
user_recipients LIKE '%, :id' or
user_recipients LIKE '%, :id,%' or
user_recipients = ':id'", id: current_user.id)

The reason why I can't do a simple LIKE %id% is that this would match partial numbers, meaning id = 5 will match [1, 10, 15] though there's no 5, but 15 does match, so I need to check for the commas , to make sure I'm not picking a wrong number.

How to Set [Activity.From.Id] , [member.Id] or [activity.Recipient.Id] using DirectLine?

Regarding my comment, I decided I'd just provide how to do what you want with both packages. Again, if it isn't too much trouble to switch, I highly, highly recommend using Microsoft.Bot.Connector (newer and more frequently updated) over Microsoft.Bot.Connector.DirectLine (older, not updated in 2.5 years, and deprecated until/unless we open-source it Update: This isn't actually deprecated, yet. We're currently working on open-sourcing this, but it's a low-priority task).

Recommended: Microsoft.Bot.Connector

Create the conversation with To and From, all-in-one.

var userAccount = new ChannelAccount(toId,toName);
var botAccount = new ChannelAccount(fromId, fromName);
var connector = new ConnectorClient(new Uri(serviceUrl));

IMessageActivity message = Activity.CreateMessageActivity();
if (!string.IsNullOrEmpty(conversationId) && !string.IsNullOrEmpty(channelId))
{
message.ChannelId = channelId;
}
else
{
conversationId = (await connector.Conversations.CreateDirectConversationAsync( botAccount, userAccount)).Id;
}
message.From = botAccount;
message.Recipient = userAccount;
message.Conversation = new ConversationAccount(id: conversationId);
message.Text = "Hello, this is a notification";
message.Locale = "en-Us";
await connector.Conversations.SendToConversationAsync((Activity)message);

Credit

Not Recommended: Microsoft.Bot.Connector.DirectLine

This is kind of a hacky workaround, but basically, you create the conversation and then send a ConversationUpdate activity.

//server side, retrieve token from secret
string directLineSecret = ConfigurationManager.AppSettings["DirectLineSecret"];
HttpClient httpClient = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post,$"https://directline.botframework.com/v3/directline/tokens/generate");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", directLineSecret);
var fromUser = $"dl_{Guid.NewGuid()}";
request.Content = new StringContent(
JsonConvert.SerializeObject(
new { User = new { Id = fromUser } }),
Encoding.UTF8,
"application/json");
var response = await httpClient.SendAsync(request);
DirectLineToken dlToken = null;
if (response.IsSuccessStatusCode)
{
var body = await response.Content.ReadAsStringAsync();
dlToken = JsonConvert.DeserializeObject<DirectLineToken>(body);
}
string token = dlToken.token;

//create DirectLineClient from token, client side
DirectLineClient client = new DirectLineClient(token);
var conversation = await client.Conversations.StartConversationAsync();
new System.Threading.Thread(async () => await ReadBotMessagesAsync(client, conversation.ConversationId)).Start();

//send conversationUpdate
var user = new ChannelAccount(fromUser);
await client.Conversations.PostActivityAsync(conversation.ConversationId,
new Activity
{
From = user,
Text = string.Empty,
Type = ActivityTypes.ConversationUpdate,
MembersAdded = new[] { user }
}
);
TimeSpan delayTime = TimeSpan.FromSeconds(dlToken.expires_in) - TimeSpan.FromMinutes(5);
Task.Factory.StartNew(async () =>
{
while (!_getTokenAsyncCancellation.IsCancellationRequested)
{
var t = await client.Tokens.RefreshTokenAsync().ConfigureAwait(false);

await Task.Delay(delayTime, _getTokenAsyncCancellation.Token).ConfigureAwait(false);
}
}).ConfigureAwait(false);

Credit

Using One-to-Many Associations for the Public Activity Rails gem

To save the author you better use the relation while creating the new book

author.books.create(name: "Jaws")

Then if you want to save the reader, you'll need to add it in the args hash

author.books.create(name: "Jaws", reader: some_user)

Note:
The reason why this prefills the object is that when you call new on an active record relation object, all the conditions inside the condition are used to create the new object, for example

Book.where(author: some_author).new

This will generate an instance of book and the author_id will be the id of the some_author from the where query.

So when we did an author.books this created a query

Book.where(author_id: author.id)

And by calling new, the new book will have the id of the author.

PS:
This also works on multiple args in the where

Model.where(key1: value1, key2: value2, key3: value3).new

will create a new instance where the attributes key1, key2, key3 are already filled.



Related Topics



Leave a reply



Submit