
# Anpassade kanaler

Anslut valfri meddelandeplattform eller kommunikationsverktyg till plattformen med hjälp av anpassade kanaler. Detta gör att du kan ta in meddelanden från plattformar som livechatt-widgets på webbplatser, e-postsystem, CRM-system eller andra tjänster till din inkorg – och svara på dem med din AI-agent.


---

## Vad är anpassade kanaler?

Anpassade kanaler utökar plattformen bortom dess inbyggda meddelandeplattformar ([WhatsApp](whatsapp-business.md), [SMS](sms.md), [Instagram](instagram-dms.md), [Messenger](facebook-messenger.md)). Med anpassade kanaler kan du:

- **Ta emot meddelanden** från valfri extern plattform till plattformens enhetliga inkorg.
- **Skicka svar** från appen tillbaka till din externa plattform automatiskt.
- **Använda en AI-agent** för att svara på meddelanden från vilken källa som helst.
- **Spåra alla konversationer** tillsammans med dina andra kanaler i en och samma inkorg.

Detta är idealiskt för företag som använder specialiserade kommunikationsverktyg, har en egenbyggd plattform eller vill ha alla kundmeddelanden på ett ställe.

::: note
**Obs:** Anpassade kanaler kräver viss teknisk konfiguration. Om du eller ditt team inte är bekväma med tekniska integrationer kan det vara bra att be er webbutvecklare eller IT-avdelning om hjälp med detta avsnitt.
:::


---

## Hur det fungerar

Anpassade kanaler fungerar genom att skicka meddelanden fram och tillbaka mellan din externa plattform och plattformen med hjälp av **webhooks** (automatiserade meddelanden som skickas mellan system över internet). Här är flödet:

```
Your Platform  ──(sends message to)──>  The App
                                           |
                                       AI Agent responds
                                       Contact saved
                                       Message stored
                                           |
The App  ──(sends reply to)──>  Your Platform
```

1. **Inkommande meddelanden:** Din externa plattform skickar meddelanden till en webbadress (URL). Se det som att din plattform "postar" ett meddelande till plattformens brevlåda.
2. **Bearbetning:** Plattformen skapar eller uppdaterar kontakten, lagrar meddelandet och låter en AI-agent generera ett svar (om den är aktiv).
3. **Utgående meddelanden:** När plattformen skickar ett svar (oavsett om det kommer från AI:n eller skrivs av dig), skickar den meddelandet till en URL på din plattform, där ditt system kan leverera det till slutanvändaren.

---

## Konfigurera inkommande meddelanden (Din plattform till appen)

För att skicka meddelanden från din externa plattform till appen måste din plattform skicka data till följande URL. Din utvecklare kommer att känna igen detta som en standard POST-förfrågan (ett vanligt sätt för ett system att skicka data till ett annat över internet).

### Vart meddelanden ska skickas

```
POST https://api.youraiconnector.com/v1/incoming_custom_channel_message?apiKey=YOUR_API_KEY
```

Ersätt `YOUR_API_KEY` med din API-nyckel (en privat kod som bevisar för plattformen att din plattform har tillåtelse att skicka meddelanden till den). Hitta eller generera den under **Inställningar → Integrationer → API-nyckel**.

### Meddelandeformat

Skicka meddelandedata i följande format (JSON):

```json
{
  "customData": {
    "messageSid": "unique-message-id-123",
    "fromId": "user-456",
    "toId": "your-business-id",
    "body": "Hello, I have a question about your service.",
    "status": "received",
    "channel": "my-live-chat",
    "campaignId": "optional-campaign-id",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john@example.com",
    "mediaUrl": null,
    "mediaContentType": null
  },
  "messageType": "text"
}
```

**Vad varje del betyder:**
- `messageSid` - Ett unikt ID för just detta meddelande (ditt system skapar detta). Används för att förhindra att samma meddelande bearbetas två gånger.
- `fromId` - Vem som skickade meddelandet (kan vara ett användar-ID, e-postadress eller telefonnummer från ditt system).
- `toId` - Din företagsidentifierare (kan vara vilken etikett du vill).
- `body` - Den faktiska meddelandetexten.
- `channel` - En etikett du väljer för att identifiera var meddelandet kom ifrån (t.ex. "website-chat", "email").

### Fullständig fältreferens

| Fält | Krävs? | Vad det gör |
|---|---|---|
| `customData.messageSid` eller `customData.id` | Ja | Ett unikt ID för detta meddelande (förhindrar dubbletter) |
| `customData.fromId` | Ja | Identifierar vem som skickade meddelandet (t.ex. ett användar-ID, e-post eller telefonnummer från ditt system) |
| `customData.toId` | Ja | Identifierar den mottagande sidan (ditt företag). Kan vara vilken text du vill. |
| `customData.body` | Ja | Själva meddelandetexten. Kan inte vara tom. |
| `customData.status` | Nej | Meddelandestatus. Lämna tomt för att använda standardvärdet (`"received"`). |
| `customData.channel` | Nej | En etikett för källan (t.ex. `"live-chat"`, `"email"`, `"my-crm"`). Hjälper dig att identifiera var meddelanden kom ifrån i din inkorg. |
| `customData.campaignId` | Nej | Ett kampanj-/Agent-ID. Använd detta för att dirigera meddelandet till en specifik AI-konfiguration. |
| `customData.firstName` | Nej | Kontaktens förnamn. Inkluderas när en ny kontakt skapas. |
| `customData.lastName` | Nej | Kontaktens efternamn. Inkluderas när en ny kontakt skapas. |
| `customData.email` | Nej | Kontaktens e-postadress. Inkluderas när en ny kontakt skapas. |
| `customData.mediaUrl` | Nej | En länk till en bifogad fil (bild, video, ljud eller dokument). Kan även vara en base64-kodad fil (se nedan). |
| `customData.mediaContentType` | Nej | Filtypen (t.ex. `"image/jpeg"`, `"video/mp4"`, `"audio/ogg"`, `"application/pdf"`). Krävs om du inkluderar `mediaUrl`. |
| `messageType` | Nej | Typ av meddelande. Lämna tomt för vanlig text. Sätt till `"reaction"` för emoji-reaktioner. |

### Emojireaktioner

Om din plattform stöder emojireaktioner (till exempel en tumme upp på ett meddelande), skicka dem som en reaktion istället för som ett textmeddelande: ställ in `messageType` till `"reaction"` och placera endast emojin i `customData.body`.

```json
{
  "messageType": "reaction",
  "customData": {
    "messageSid": "reaction-123",
    "fromId": "user-42",
    "toId": "my-business",
    "body": "👍"
  }
}
```

Assistenten hanterar det då på det sätt du förväntar dig:

- En reaktion på en fråga som assistenten ställde (till exempel "Fungerar torsdag?") behandlas som svaret, och assistenten svarar.
- En reaktion på ett avslutande meddelande (till exempel "Vi hörs snart!") avslutar konversationen tyst. Inget svar skickas.

Om din plattform omvandlar reaktioner till text, till exempel "Reagerade med: 👍", ser assistenten ett vanligt textmeddelande och avgör själv om den ska svara. Genom att skicka reaktionstypen undviker du det.

### Vad du får tillbaka

En lyckad förfrågan returnerar:

```json
{
  "success": true,
  "messageId": "1234567890"
}
```

Om något går fel får du ett felmeddelande som förklarar problemet:

```json
{
  "error": "Message body cannot be empty"
}
```

### Statuskoder

| Kod | Vad det betyder |
|---|---|
| `200` | Lyckades - meddelandet har tagits emot och bearbetas |
| `400` | Något är fel med din förfrågan - kontrollera om obligatoriska fält saknas eller om meddelandetexten är tom |
| `401` | Ogiltig API-nyckel - dubbelkolla nyckeln under **Inställningar → Integrationer → API-nyckel** |
| `405` | Fel förfrågningsmetod - se till att du använder POST, inte GET |
| `500` | Något gick fel på plattformens sida - försök igen om en liten stund |

> Om du ställer in `customData.status` är det enda godkända värdet `"received"` — utelämna det helt för att använda standardvärdet istället för att skicka något annat, annars får du ett `400`.

---

## Skicka bifogade mediefiler (bilder, videor, filer)

Du kan inkludera bifogade filer (bilder, videor, ljud, dokument) i dina meddelanden. Det finns två sätt att göra detta på:

### Alternativ 1: Länk till en fil

Om filen redan finns online, ange URL:en (webbadressen) där plattformen kan ladda ner den:

```json
{
  "customData": {
    "messageSid": "msg-789",
    "fromId": "user-456",
    "toId": "business-1",
    "body": "Here is a photo of the issue.",
    "channel": "support-portal",
    "mediaUrl": "https://example.com/uploads/photo.jpg",
    "mediaContentType": "image/jpeg"
  },
  "messageType": "text"
}
```

### Alternativ 2: Bädda in filen direkt (Base64)

Om filen inte är värd online kan du bädda in den direkt i meddelandet som kodad text (base64-format). Detta är vanligt i tekniska integrationer där ditt system genererar filer i farten. Plattformen kommer automatiskt att avkoda och lagra filen:

```json
{
  "customData": {
    "messageSid": "msg-790",
    "fromId": "user-456",
    "toId": "business-1",
    "body": "Screenshot attached.",
    "channel": "support-portal",
    "mediaUrl": "data:image/png;base64,iVBORw0KGgo...",
    "mediaContentType": "image/png"
  },
  "messageType": "text"
}
```

::: note
**Obs:** Att bädda in filer direkt gör meddelandedatan betydligt större. För stora filer är det bättre att lagra filen online och skicka en länk (Alternativ 1) istället.
:::


---

## Konfigurera utgående meddelanden (plattformen till din plattform)

När plattformen skickar ett svar på en anpassad kanal (oavsett om det kommer från AI:n eller skrivs av dig), skickar den automatiskt svaret till en URL på din plattform så att ditt system kan leverera det till slutanvändaren.

> **Ställ in webhook-URL:en först.** Du måste spara webhook-URL:en för den anpassade kanalen innan några svar kan levereras. Om ingen URL sparas genereras och lagras svaren fortfarande, men de skickas aldrig ut – och de kommer **inte** att visa en "Misslyckades"-status, så ingenting i din inkorg flaggar för problemet. Konfigurera alltid webhook-URL:en innan du går live.

### Berätta för appen vart svar ska skickas

1. Klicka på **Inställningar** nära botten i det vänstra sidofältet.
2. Under **Kanaler** i inställningsmenyn till vänster, klicka på **Kanaler**.
3. Leta upp kortet **Anpassad kanal** längst ner på sidan (efter Android SMS Gateway, iMessage, webbplatsens chattwidget, Twilio-konto och regelefterlevnad).
4. Ange **Webhook-URL** — URL:en på din plattform dit AI:n ska skicka utgående meddelanden (din utvecklare ställer in detta för att ta emot och bearbeta svar). Det måste vara en **offentlig HTTPS-URL** — `http://`-adresser och icke-offentliga värdar avvisas.
5. Klicka på **Spara**.



### Vad plattformen skickar till din plattform

När plattformen skickar ett svar kommer din plattform att ta emot följande data:

```json
{
  "contactId": "abc123",
  "messageId": "msg-456",
  "userId": "your-user-id",
  "body": "Thank you for your message! Here is the information you requested...",
  "toId": "user-456",
  "channel": "my-live-chat"
}
```

### Vad varje fält betyder

| Fält | Vad det innehåller |
|---|---|
| `contactId` | plattformens interna ID för denna kontakt |
| `messageId` | Det unika ID:t för detta meddelande i appen |
| `userId` | Ditt användar-ID |
| `body` | Svarstexten |
| `toId` | Kontaktens ID på din plattform (detta matchar det `fromId` du skickade i det inkommande meddelandet) |
| `channel` | Etiketten för den anpassade kanal du tilldelade |

Din plattform tar emot denna data och använder den för att leverera svaret till slutanvändaren via ditt eget system.

### Hur plattformen spårar leverans

Efter att ha skickat svaret till din plattform uppdaterar plattformen meddelandestatusen:

- **Skickat** - Din plattform tog emot meddelandet utan problem.
- **Misslyckades** - Din plattform returnerade ett fel eller kunde inte nås. Plattformen lagrar felinformationen tillsammans med meddelandet så att du kan felsöka.

---

## Skicka meddelanden från ditt system till appen

Utöver att ta emot meddelanden kan du även skicka utgående meddelanden via en anpassad kanal direkt från ditt eget system. Detta är användbart när du vill starta en konversation eller skicka ett proaktivt meddelande.

> **Plan-krav.** Att skicka och synkronisera meddelanden via API:et kräver en plan som inkluderar API-åtkomst och minst en meddelandekanal. Om du får ett `403` "permission denied / feature not enabled"-fel, inkluderar din nuvarande plan inte detta – uppgradera din plan eller kontakta supporten.

### Vart du ska skicka

```
POST https://api.youraiconnector.com/v1/send_custom_channel_message?apiKey=YOUR_API_KEY
```

### Meddelandeformat

```json
{
  "customData": {
    "fromId": "user-456",
    "customChannel": "my-live-chat",
    "body": "Hello! How can I help you today?",
    "campaignId": "optional-campaign-id",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john@example.com"
  }
}
```

### Obligatoriska fält

| Fält | Vad det gör |
|---|---|
| `customData.fromId` | Kontaktens ID på din plattform |
| `customData.customChannel` | Namnet på din anpassade kanal (t.ex. "my-live-chat") |
| `customData.body` | Meddelandetexten som ska skickas |

De valfria fälten (`campaignId`, `firstName`, `lastName`, `email`) fungerar på samma sätt som för inkommande meddelanden – de hjälper plattformen att skapa eller uppdatera kontaktposten.

### Vad du får tillbaka

```json
{
  "success": true,
  "messageId": "generated-message-id",
  "contactId": "contact-id",
  "message": "Message sent successfully"
}
```

---

## Registrera meddelanden som skickats från ett annat system

Ibland har du redan skickat ett meddelande till en kontakt från ett annat verktyg (till exempel ett arbetsflöde i en annan plattform), och du vill helt enkelt att plattformen ska känna till det så att AI:n har full kontext. Detta skiljer sig från att skicka: plattformen registrerar meddelandet men levererar det **inte** på nytt till kontakten.

### Vart du ska skicka

```
POST https://api.youraiconnector.com/v1/sync_custom_channel_message?apiKey=YOUR_API_KEY
```

Inkludera `customData.fromId` (kontaktens ID på din plattform) och `customData.body` (meddelandetexten som redan har skickats).

### Hur det fungerar

- **Meddelandet registreras, inte återsänds.** Plattformen lagrar det i konversationen endast för kontext.
- **AI:n pausas som standard för den kontakten.** Detta förhindrar att boten svarar på ett meddelande som en människa redan har hanterat. För att hålla boten aktiv, skicka med `customData.pauseAi: false`.
- **Nya kontakter kan skapas automatiskt.** Inkludera `customData.customChannel` så skapas kontakten om den inte redan finns.
- **Dubbletter ignoreras.** Om du återanvänder samma `messageSid` känner plattformen igen att meddelandet redan har registrerats och gör inga ändringar.

> **Plan-krav.** Precis som vid sändning kräver inspelning av meddelanden via API:et en plan som inkluderar API-åtkomst och minst en meddelandekanal. Ett `403` "permission denied / feature not enabled"-fel innebär att din nuvarande plan inte inkluderar detta.

---

## Verkliga exempel

### Livechatt på webbplats

Anslut en livechatt-widget på din webbplats till plattformen så att din AI-agent kan svara på besökares frågor:

1. En besökare skriver ett meddelande i din webbplats chattwidget.
2. Din chattwidget skickar meddelandet till plattformen.
3. AI-agenten genererar ett svar.
4. Svaret skickas tillbaka till din chattwidget, som visar det för besökaren.

**Varför detta är användbart:** Dina webbplatsbesökare får omedelbara, AI-drivna svar på sina frågor utan att du behöver vara online.

### E-post

Dirigera e-postkonversationer genom plattformen så att din AI-agent kan svara på e-postmeddelanden:

1. Konfigurera ett system som vidarebefordrar inkommande e-post till plattformen (använd e-postavsändarens adress som `fromId`, e-postämnet och brödtexten som `body`, och `"email"` som `channel`).
2. AI-agenten läser e-postmeddelandet och genererar ett svar.
3. Svaret skickas tillbaka till ditt e-postsystem, som skickar det som ett vanligt e-postsvar.

**Varför detta är användbart:** Vanliga frågor via e-post (prissättning, öppettider, tillgänglighet) besvaras omedelbart av din AI-agent.

> Om ditt e-postsystem stöder IMAP/SMTP eller OAuth kan den inbyggda [E-postkanalen](email.md) vara enklare än en anpassad integration.

### CRM-integrering

Anslut ditt befintliga CRM-system (Customer Relationship Management) till plattformen:

1. När en potentiell kund skickar ett meddelande via ditt CRM, vidarebefordra det till plattformen.
2. AI-agenten svarar och spårar konversationen.
3. AI-svaret skickas tillbaka till ditt CRM för leverans.
4. Hela konversationshistoriken finns tillgänglig både på plattformen och i ditt CRM.

**Varför detta är användbart:** Ditt säljteam får AI-assisterade svar till leads utan att behöva lämna sitt CRM.

### Supportärendesystem

Använd plattformen som en AI-driven första linjens support för kundtjänst:

1. Ditt ärendehanteringssystem vidarebefordrar nya supportärenden till plattformen.
2. AI-agenten skickar ett första svar (t.ex. bekräftar ärendet och ställer klargörande frågor).
3. Svaret bifogas ärendet i ditt supportsystem.
4. Ditt supportteam kan granska vad AI:n har skrivit och ta över vid behov.

**Varför detta är användbart:** Kunder får en omedelbar bekräftelse och initial hjälp, även utanför kontorstid.

---

## Felsökning

### Meddelanden tas inte emot av plattformen

- Kontrollera att din API-nyckel är korrekt och aktiv (kontrollera **Inställningar → Integrationer → API-nyckel**).
- Se till att du skickar en POST-förfrågan (inte GET). Din utvecklare vet skillnaden.
- Kontrollera att fältet `customData.body` inte är tomt eller endast innehåller blanksteg.
- Verifiera att fältet `customData.fromId` är inkluderat.
- Läs svarsmeddelandet för specifika feldetaljer.

### Svar når inte din plattform

- Se till att du har angett din plattforms URL i kortet **Anpassad kanal** på sidan Kanaler. Om ingen URL sparas genereras och lagras svar, men de skickas aldrig ut — och de kommer **inte** att markeras som "Misslyckades", så kontrollera detta först.
- Verifiera att URL:en är publikt tillgänglig (inte bakom en inloggning eller brandvägg) och returnerar ett lyckat svar.
- Endast svar (utgående meddelanden) skickas till din URL — inkommande meddelanden utlöser inte detta.
- Kontrollera feldetaljer för meddelandet i din inkorg.

### Kontakt skapas inte

- Se till att värdet `fromId` är konsekvent för samma användare i alla deras meddelanden. Plattformen använder detta värde för att identifiera kontakter — om det ändras mellan meddelanden skapar plattformen en ny kontakt varje gång.
- Inkludera `firstName`, `lastName` och `email` i det första meddelandet från en ny kontakt för att skapa en fullständig kontaktpost.

### Media-bilagor fungerar inte

- För fillänkar (URL:er), se till att filen är publikt tillgänglig (ingen inloggning krävs för att komma åt den).
- Inkludera alltid `mediaContentType` när du inkluderar `mediaUrl`.
- För inbäddade filer (base64), verifiera att formatet är `data:MIME_TYPE;base64,ENCODED_DATA`.
- Se till att filtypen du anger matchar det faktiska filinnehållet.

---

## Bästa praxis

- **Använd konsekventa `fromId`-värden.** Varje användare på din plattform bör alltid ha samma `fromId`. Detta säkerställer att plattformen grupperar alla deras meddelanden i en enda konversation istället för att skapa dubbletter av kontakter.
- **Välj ett tydligt `channel`-namn.** Välj något beskrivande som `"website-chat"`, `"email"` eller `"zendesk"` så att du enkelt kan se var meddelanden kom ifrån när du tittar i din inkorg.
- **Inkludera kontaktuppgifter** (`firstName`, `lastName`, `email`) i det första meddelandet från en ny kontakt. Detta skapar en fullständig och användbar kontaktpost direkt.
- **Bygg in logik för återförsök.** Låt din plattform försöka skicka meddelanden igen om plattformen inte svarar vid första försöket (nätverksproblem kan förekomma).
- **Använd unika `messageSid`-värden** för varje meddelande. Detta förhindrar att samma meddelande bearbetas två gånger om ditt system skickar det mer än en gång.
- **Använd `campaignId`** för att dirigera meddelanden till olika AI-agenter när du har flera användningsområden (t.ex. säljförfrågningar kontra supportfrågor).
- **Testa innan du går live.** Skicka testmeddelanden i båda riktningarna och verifiera att kontakter, konversationer och AI-svar fungerar korrekt innan du lanserar för riktiga användare.
