I read several questions about this argument here, but I can't find a solution.
The system has to send one o more notification to users, so my first idea is
Notification
---------------------
id
sender_id
message
Notification_user
--------------------
id
notification_id
recipient_id
is_read
created_on
read_on
User
---------------------
id
first_name
last_name
In Notification I can save message like "Walter White added a new article in 'Economy' section" and send it to users saved in Notification_user.
but in this way, there are two main problems:
If an user wants to receive the notification in a different language, I should saved the same message in different language.
If the message "Walter White added a new article in 'Economy' section" is saved in Notification, and then the admin changes the name of section from "Economy" to "Economy - Europe", the recipient will read the message with the old section name and not "Walter White added a new article in 'Economy - EUROPE' section"
So I thought to modify the Notification table in this way
Notification
----------------------
id
sender_id
extra_info
where in extra_info I concat a string that contains all info, for example: "sectionId:100,otherColumnId:125"
So, code side I can fetch the correct info, build the message and send it like a notification...but this approach should be expensive. Is there a better solution?
Related
I've been struggling for months now with a random error in the ms graph api. Finally I found some sence in the whole mess, but I think there's an error in the graph api.
I've developed a multitenant outlook-addin (JS), that my clients use to store their emails and/or the attachments into a storage. I use the Office.context.mailbox.item object to fetch both the ItemId of the message and the Id's of the attachments. I send those id's off to a sevrer to do the heavy liftning of retriving the email and/or attachments, using EWS. Because the client has a choice of selecting which attachments to save, I need to send the selected attachment Id's to the server, where I retrieve the email and the attachments. However when I try to match the attachment Id's with the selected from the Outlook app they're different, and I can't find the correct attachments. This happens with random messages, with random tenants.
From what I can see from the id's for the email and the attachments, it looks like the attachment id is prefixed with the email id. Sometimes they don't match. Example:
The user select an email in the Outlook desktop client (Mac or Windows) and get this id for the email:
AAMkADYxNWNjMTRiLWFjYTYtNDM1OS04MTNjLThiNzM1ZWM0ZDFmZgBGAAAAAADbXpqFYshcSYLgLaL8DcdZBwDVFKe56AEMQo4qySw0u6tyAAAfj8mWAADVFKe56AEMQo4qySw0u6tyAABBmpnFAAA=
The attachment has this id (which DOESN'T match the email id):
AAMkADYxNWNjMTRiLWFjYTYtNDM1OS04MTNjLThiNzM1ZWM0ZDFmZgBGAAAAAADbXpqFYshcSYLgLaL8DcdZBwDVFKe56AEMQo4qySw0u6tyAAAAAAEJAADVFKe56AEMQo4qySw0u6tyAABBmmK4AAABEgAQAOBOPI4JZ71CuMzlk7nqfZw=
but when I query the EWS using the email id (I'm aware of the REST/EWS id differences), I get this id for the attachment (which DO match the email id):
AAMkADYxNWNjMTRiLWFjYTYtNDM1OS04MTNjLThiNzM1ZWM0ZDFmZgBGAAAAAADbXpqFYshcSYLgLaL8DcdZBwDVFKe56AEMQo4qySw0u6tyAAAfj8mWAADVFKe56AEMQo4qySw0u6tyAABBmpnFAAABEgAQAOBOPI4JZ71CuMzlk7nqfZw=
The funny thing is, that it works from OWA - this attahcment id is correct. This specific email has been moved, and I know that when moving files, the id changes, but shouldn't the attachment id then follow along? In EWS the id seems to have changed but not in Outlook
I used my Id-Whispering skills to look at your ids.
The first one is the id of the item itself, not an attachment on the item. The actual PR_ENTRYID for this id is AAAAANtemoViyFxJguAtovwNx1kHANUUp7noAQxCjirJLDS7q3IAAB+PyZYAANUUp7noAQxCjirJLDS7q3IAAEGamcUAAA==
The second one is an attachment, but the parent item is different. The PR_ENTRYID for this id is
AAAAANtemoViyFxJguAtovwNx1kHANUUp7noAQxCjirJLDS7q3IAAAAAAQkAANUUp7noAQxCjirJLDS7q3IAAEGaYrgAAA==
Attachment id part: EADgTjyOCWe9QrjM5ZO56n2c
The third one is also an attachment, same "attachment id" part of the id, but in this case, it refers to the item in the original location. As you can see, the PR_ENTRYID matches:
AAAAANtemoViyFxJguAtovwNx1kHANUUp7noAQxCjirJLDS7q3IAAB+PyZYAANUUp7noAQxCjirJLDS7q3IAAEGamcUAAA==
Attachment id part: EADgTjyOCWe9QrjM5ZO56n2c
So what happened here? What it looks like is that in the second case, the item was in a different folder. PR_ENTRYID made up of the FID (folder id) and the MID (message id). As a result, if an item moves from one folder to another, then the id changes. You move it back, it reverts back to its old id. Weird, I know.
That's a good reason for Microsoft to come up with an immutable id :)
We've created an application whereby members of the public can search for each other and get in contact (think of it as a dating site) if they so desire, I'm currently in the process of building the Messaging functionality, but I'm curious on how I go about creating the table(s) in the database.
The current flow of the application is as follows:
User1 clicks on User2 to view his/her profile, scrolls down to the bottom of his/hers profile and types some text into a textarea and clicks send at this point I then pass in the data to the database I then send User2 an email saying "you have mail etc".
Taking that into consideration I would of assumed my Email table within SQL Server would look something like this:
Id (PK) (Increments by 1)
ToUserId (FK) // User who they're getting in contact with
FromUserId (FK) // User who sent the message
Content (nvarchar(3000)
Status (int) // read , new , deleted , sent
EmailDate (datetime)
EmailDeleted (datetime)
But the problem with this setup is both user's maybe sending / replying to each other so I would have multiple entries / statuses in one table which may become a nightmare to manage / control (unless I'm over thinking it)
I've spent a good few hours trying to come up with a solution from browsing on the web trying to gain knowledge for building messaging functionality yet it comes back very shy of results. Has anyone been able to build such functionality that wouldn't mind sharing knowledge with me.
You can break it to two tables, something like this:
TblMessage
(
Message_Id int identity(1,1) primary key,
Message_SentDate datetime not null default(getDate()),
Message_Title varchar(100),
Message_Content varchar(max),
Message_SenderId int, -- (fk to users)
Message_IsDraft bit not null default(0), -- when 1 it's saved as draft.
Message_IsDeletedFromOutbox bit not null default(0)-- when 1 don't show on sender outbox
)
TblMessageToRecipient
(
MTR_UserId int, -- (fk to users)
MTR_Message_Id int, -- (fk to message)
MTR_ReadDate datetime null, (if null then status is new)
MTR_DeleteDate datetime null, (if not null then status is deleted)
PRIMARY KEY (MTR_UserId, MTR_Message_Id)
)
This way you can give the recipient an option to "delete forever" a message and just delete the relevant record from TblMessageToRecipient.
Also, you can delete the message completely from tblMessage if it doesn't have a reference on the TblMessageToRecipient and Message_DeletedFromOutbox = 1
(this can be done by a scheduled sql agent job to prevent tblMessages from getting too big)
update:
I hope this will answer your question in the comment:
The recipient has several possible statuses:
New - when MTR_ReadDate is null.
Read -when MTR_ReadDate is not null, and MTR_DeleteDate is null.
Recycled - when MTR_DeleteDate is null.
Deleted - when the record is deleted from TblMessageToRecipient.
The sender have only 3 possible statuses:
Draft.
I've added a bit column to the TblMessage called IsDraft. note that drafts should also save recipient information, so it should be saved in both tables, just show it to the sender in the drafts box, and don't show it to the recipient. Note that when the sender discard the draft you should delete the message from both tables.
Sent.
Once the message is in both tables, and IsDraft = 0, and IsDeletedFromOutbox = 0, it means that the message was sent. in this case, show it to the sender in the sent messages box, and show it to the recipient.
Deleted from outbox.
When IsDeletedFromOutbox = 1 you simply don't show the message to the sender.
if the message record does not have any references in the TblMessageToRecipient, you can delete the record from TblMessages since it was deleted by the sender and by all of it's recipients.
Update 2:
To summerize our conversation in the comments, there are 2 mahor ways to keep a conversation structure (meaning the link between a message and a reply to it [and it's reply and so on...])
One way is to keep a Message_ParentId nullable column in TblMessages.
This column will contain null for any message that is not a reply to an older message, but for replies it will contain the message id of the message it was a reply to.
The second way is to keep a Message_ConversationId column that will always contain a value. when a message is a reply to an older message, it's Message_ConversationId should be the same as it's parent message. When it's not a reply, it's ConversationId should be generated. Since we are talking about sql server 2008, it means the easiest way to generate a new conversation id every time will be to add a new table called TblConversation. this table can keep a single column Conversation_Id that will be an int identity column, and to get a new conversation id do something like this:
DECLARE #ConversationId int
INSERT INTO TblConversation DEFAULT VALUES
SELECT #ConversationId = SCOPE_IDENTITY()
and then user the #ConversationId when inserting a new root message.
I have a table named tblMessages that has a field named Type .type value can be 1 for user messages and can be 2 for general messages.
in selection of user message i write this sql function:
SELECT * FROM tblMessage WHERE USERID=$Userid and Type=1 and ISseen=0;
then in another SQL code i updated that row and set ISseen=1 for specific user
UPDATE tblMessage SET ISseen=1 Where USERID=$userid;
but in selection of General messages i have a little problem.i want to select general message for all user and show it once!as i said before i can update tblmessage and set ISseen=1 then if ISseen be a value of 1 user message is not selected for another time.but for selection of general message i cant do it with WHERE USERID=$userid.
i dont want to insert general message for every user in table also.then
How can i select general messages ONCE for a user by my table structure?
*****////******
Edit number 1
my tblmessage has 20000 records and just has 10 general messages.in my website when user loged in to his/her acount and go to his/her messages can see Personal Messages and General Messages.when user reach that page i Updated the tblmessage table and set ISseen==1
then when that user loged out and then came back to website and to his/her userpage that personal message didnt show again!cause the field ISseen=1.But in another way the general messages is showed again and again.cause what?cause i dont have any ISseen field for general message.
my question is what can i do then with this explanation of my table.how can i do the same thing with general messages.
Create another table messageTable that will look like this .
ID -- Message
1 -- User message
2 -- General message
now you can apply join to get message on the behalf of type .
your query will be look like this.
SELECT messageTable.*,tblMessage.* FROM tblMessage,messageTable WHERE tblMessage.USERID=$Userid and tblMessage.Type=1 and tblMessage.ISseen=0 and tblMessage.Type=messageTable.ID;
hello I have a database with 3 tables.
USERS('user_id','name','surname')
MESSAGE_GROUP('user_one','user_two', 'hash')
MESSAGES('from_id','group_hash', 'messages')
My php code enables me to send messages between users. My question is how to enable a user to delete a message from its mailbox but the other user still watching the message. The messages must be full deleted only if both users delete the message. I am not interesting about the code, I am interesting only in finding the logic behind this. Any proposals that includes mysql code are welcome. thanks
I think you should follow this. :)
You can keep an extra field in message_group table something like 'deleted_from' which will be initially 0
If user one deletes it make the value of 'deleted_from'=1, if user two deletes it, make the value of 'deleted_from' = 2.
When you go to delete the message for a user, and you find the value 'deleted_from' other than 0, delete the message completely, else mark the value of 'deleted_from' as '1' or '2'.
You will need to either:
Make a new table that specifies the mailboxes the message resides in, so that you can connect it to both users mailboxes
Or duplicate the message so that each user has their own copy that can be deleted
Add flags to the message table (not recommended) indicating whether the sender or recipient has deleted it. This I would avoid as it will not scale well if you have (or intend to add) group messaging.
add to MESSAGE_GROUP a status field with values :
0 no owner and should be deleted
1 only the sender owns the message
2 only the reciever owns the message
3 both sender and recievers own it
I would change the fields from the table in between like this (example that every user only can send a message to one person at a time):
USERS('user_id','name','surname')
MESSAGE_GROUP('user_id','message_id')
MESSAGES('from_id', 'to_id', 'messages')
So every user that has a message, will have a row in the MESSAGE_GROUP. When one user deletes the post, delete that row in MESSAGE_GROUP
So I am writing a simple inbox private message system.
My table schema is as follows:
messageID
message
sender id
receiver id
date sent
read ( 0 = no , 1 = yes)
I am able to show the messages for the user by relating his userID to receiverID. However I also want to show the messages he has sent in the inbox to the user.
For example his inbox should show:
Darth Vader - 3 New messages
Luke - 0
new messages (0 because either I read
all of them OR i sent him the message
and he has not replied).
But what i can only come up with is
Darth Vader - 3 New messages.
Can I get any help with how I can accomplish this SQL call?
EDIT: To Clear the Confusion
I am neither Luke or Darth. I have received 3 New messages from darth, and I have sent a message to luke.
EDIT**
Basically I want to be able to make the inbox like how an SMS app would be, where you can see the sms you just sent in a list of sms's by your friends.
SELECT users.username, count(messageID) AS unread
FROM users, messages
WHERE messages.senderID=<USER ID>
AND messages.receiverID=users.userID
AND messages.read=0
Just to make sure I got this right, this query will show all the users I have sent a message to and count the number of those messages which have not been read.