Photon Bot for Dify
Answer messages on iMessage, SMS, WhatsApp, WhatsApp Business, email, and Telegram with a Dify Chatflow or Chatbot app, through Photon's messaging API (API reference).
Photon calls a conversation a space. Each space belongs to one platform, and the project's own phone numbers, bots, and email accounts are its agent users. When the project receives a message, Photon delivers a signed webhook to this plugin's endpoint. The plugin passes the message's text to the app selected in the endpoint's settings and sends the app's answer back into the same space, from the agent user that received the message. Each space keeps one Dify conversation, so the app answers with the space's earlier messages as context.
Setup
- In your Photon project, connect the channels you will use (Messaging). The plugin does not connect channels.
- Create an Account Service Key () or a Project API key () that can send messages in the project (Set up your project).
- Install Photon Bot, and add an endpoint to it with these settings:
- Copy the endpoint URL that Dify shows, ending in , and create a webhook destination for it in the Photon project, subscribed to with API version . Use the URL exactly as Dify shows it: Photon does not follow redirects. With Photon's Create webhook destination:
- Paste the destination's signing secret (, , returned only when the destination is created) into the endpoint's , and save.
Until the signing secret is saved, the endpoint rejects every delivery, and Photon does not retry rejected deliveries.
Photon delivers only to public HTTPS URLs. On self-hosted Dify, set to the public HTTPS address of your Dify, for example , because Dify builds the endpoint URL it shows from it.
Usage
When a person sends "What are your opening hours?" to the project's Telegram bot, Photon delivers (abbreviated):
The plugin sends the text to the app as the query, in the conversation it keeps for and the app; the first message of a space starts a new conversation. It then sends the app's answer with Photon's Send a Message:
with the idempotency key , derived from the received message, so Photon sends at most one reply to each message.
- Only deliveries with text content () are answered. Other events, other content (images, voice, reactions, and others), messages sent by one of the project's agents, and messages without are acknowledged without an answer. Skipping the agents' messages keeps them from answering each other, and the reply is sent as .
- An app that answers with empty text sends nothing.
- Every delivery is checked against Photon's signature before anything else: the Standard Webhooks HMAC-SHA256 signature over the delivery's ID, timestamp, and body, with the timestamp within 5 minutes. A delivery that fails the check gets HTTP 401 and starts nothing.
Timing and retries
Photon waits 20 seconds for each delivery attempt and retries a delivery that times out or fails; the destination's later messages wait until that delivery is done. The plugin calls the app and sends the answer before it responds, so:
- An answer that takes the app longer than 20 seconds may not be sent.
- Each message is answered at most once. When Photon delivers a message again, after a timeout or an error, the plugin acknowledges it without calling the app again. A message whose app call or reply failed gets no reply; the space keeps its Dify conversation.
Connection requirements
The plugin makes HTTPS requests to Photon at to send the replies (Send a Message), and calls the selected app through Dify. Photon sends deliveries to the endpoint URL.
Limitations
- Only text is answered, and replies are plain text.
- The endpoint answers every text message its destination delivers, on every platform and line of the project.
- Agent apps cannot answer. Dify 1.17.1 rejects the plugin's blocking call to an Agent app (), and rejects apps of its newer Agent runtime (app mode ) as . To use tools, add tool or Agent nodes to a Chatflow.
- In Dify 1.17.1, if a space's conversation is deleted, a Chatbot app fails every later message in that space, because Dify cannot find the conversation; a Chatflow starts a new one.
- If the destination's signing secret is rotated in Photon, save the new secret in the endpoint before the old one expires.
Privacy
See PRIVACY.md.
Development
Source: photon-hq/dify, in . With Python 3.12, from :
The tests mock Photon and Dify's app and storage calls, and never send messages.
License
MIT